PackageManagerService.java revision 9403fa983207017339a814e7c32fc024e2cb4f41
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.NonNull;
106import android.annotation.Nullable;
107import android.app.ActivityManager;
108import android.app.AppOpsManager;
109import android.app.IActivityManager;
110import android.app.ResourcesManager;
111import android.app.admin.IDevicePolicyManager;
112import android.app.admin.SecurityLog;
113import android.app.backup.IBackupManager;
114import android.content.BroadcastReceiver;
115import android.content.ComponentName;
116import android.content.ContentResolver;
117import android.content.Context;
118import android.content.IIntentReceiver;
119import android.content.Intent;
120import android.content.IntentFilter;
121import android.content.IntentSender;
122import android.content.IntentSender.SendIntentException;
123import android.content.ServiceConnection;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.AppsQueryHelper;
127import android.content.pm.AuxiliaryResolveInfo;
128import android.content.pm.ChangedPackages;
129import android.content.pm.FallbackCategoryProvider;
130import android.content.pm.FeatureInfo;
131import android.content.pm.IOnPermissionsChangeListener;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageDeleteObserver;
134import android.content.pm.IPackageDeleteObserver2;
135import android.content.pm.IPackageInstallObserver2;
136import android.content.pm.IPackageInstaller;
137import android.content.pm.IPackageManager;
138import android.content.pm.IPackageMoveObserver;
139import android.content.pm.IPackageStatsObserver;
140import android.content.pm.InstantAppInfo;
141import android.content.pm.InstantAppRequest;
142import android.content.pm.InstantAppResolveInfo;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.IntentFilterVerificationInfo;
145import android.content.pm.KeySet;
146import android.content.pm.PackageCleanItem;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageInfoLite;
149import android.content.pm.PackageInstaller;
150import android.content.pm.PackageManager;
151import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
152import android.content.pm.PackageManagerInternal;
153import android.content.pm.PackageParser;
154import android.content.pm.PackageParser.ActivityIntentInfo;
155import android.content.pm.PackageParser.PackageLite;
156import android.content.pm.PackageParser.PackageParserException;
157import android.content.pm.PackageStats;
158import android.content.pm.PackageUserState;
159import android.content.pm.ParceledListSlice;
160import android.content.pm.PermissionGroupInfo;
161import android.content.pm.PermissionInfo;
162import android.content.pm.ProviderInfo;
163import android.content.pm.ResolveInfo;
164import android.content.pm.ServiceInfo;
165import android.content.pm.SharedLibraryInfo;
166import android.content.pm.Signature;
167import android.content.pm.UserInfo;
168import android.content.pm.VerifierDeviceIdentity;
169import android.content.pm.VerifierInfo;
170import android.content.pm.VersionedPackage;
171import android.content.res.Resources;
172import android.database.ContentObserver;
173import android.graphics.Bitmap;
174import android.hardware.display.DisplayManager;
175import android.net.Uri;
176import android.os.Binder;
177import android.os.Build;
178import android.os.Bundle;
179import android.os.Debug;
180import android.os.Environment;
181import android.os.Environment.UserEnvironment;
182import android.os.FileUtils;
183import android.os.Handler;
184import android.os.IBinder;
185import android.os.Looper;
186import android.os.Message;
187import android.os.Parcel;
188import android.os.ParcelFileDescriptor;
189import android.os.PatternMatcher;
190import android.os.Process;
191import android.os.RemoteCallbackList;
192import android.os.RemoteException;
193import android.os.ResultReceiver;
194import android.os.SELinux;
195import android.os.ServiceManager;
196import android.os.ShellCallback;
197import android.os.SystemClock;
198import android.os.SystemProperties;
199import android.os.Trace;
200import android.os.UserHandle;
201import android.os.UserManager;
202import android.os.UserManagerInternal;
203import android.os.storage.IStorageManager;
204import android.os.storage.StorageEventListener;
205import android.os.storage.StorageManager;
206import android.os.storage.StorageManagerInternal;
207import android.os.storage.VolumeInfo;
208import android.os.storage.VolumeRecord;
209import android.provider.Settings.Global;
210import android.provider.Settings.Secure;
211import android.security.KeyStore;
212import android.security.SystemKeyStore;
213import android.service.pm.PackageServiceDumpProto;
214import android.system.ErrnoException;
215import android.system.Os;
216import android.text.TextUtils;
217import android.text.format.DateUtils;
218import android.util.ArrayMap;
219import android.util.ArraySet;
220import android.util.Base64;
221import android.util.BootTimingsTraceLog;
222import android.util.DisplayMetrics;
223import android.util.EventLog;
224import android.util.ExceptionUtils;
225import android.util.Log;
226import android.util.LogPrinter;
227import android.util.MathUtils;
228import android.util.PackageUtils;
229import android.util.Pair;
230import android.util.PrintStreamPrinter;
231import android.util.Slog;
232import android.util.SparseArray;
233import android.util.SparseBooleanArray;
234import android.util.SparseIntArray;
235import android.util.Xml;
236import android.util.jar.StrictJarFile;
237import android.util.proto.ProtoOutputStream;
238import android.view.Display;
239
240import com.android.internal.R;
241import com.android.internal.annotations.GuardedBy;
242import com.android.internal.app.IMediaContainerService;
243import com.android.internal.app.ResolverActivity;
244import com.android.internal.content.NativeLibraryHelper;
245import com.android.internal.content.PackageHelper;
246import com.android.internal.logging.MetricsLogger;
247import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
248import com.android.internal.os.IParcelFileDescriptorFactory;
249import com.android.internal.os.RoSystemProperties;
250import com.android.internal.os.SomeArgs;
251import com.android.internal.os.Zygote;
252import com.android.internal.telephony.CarrierAppUtils;
253import com.android.internal.util.ArrayUtils;
254import com.android.internal.util.ConcurrentUtils;
255import com.android.internal.util.DumpUtils;
256import com.android.internal.util.FastPrintWriter;
257import com.android.internal.util.FastXmlSerializer;
258import com.android.internal.util.IndentingPrintWriter;
259import com.android.internal.util.Preconditions;
260import com.android.internal.util.XmlUtils;
261import com.android.server.AttributeCache;
262import com.android.server.DeviceIdleController;
263import com.android.server.EventLogTags;
264import com.android.server.FgThread;
265import com.android.server.IntentResolver;
266import com.android.server.LocalServices;
267import com.android.server.LockGuard;
268import com.android.server.ServiceThread;
269import com.android.server.SystemConfig;
270import com.android.server.SystemServerInitThreadPool;
271import com.android.server.Watchdog;
272import com.android.server.net.NetworkPolicyManagerInternal;
273import com.android.server.pm.Installer.InstallerException;
274import com.android.server.pm.PermissionsState.PermissionState;
275import com.android.server.pm.Settings.DatabaseVersion;
276import com.android.server.pm.Settings.VersionInfo;
277import com.android.server.pm.dex.DexManager;
278import com.android.server.storage.DeviceStorageMonitorInternal;
279
280import dalvik.system.CloseGuard;
281import dalvik.system.DexFile;
282import dalvik.system.VMRuntime;
283
284import libcore.io.IoUtils;
285import libcore.util.EmptyArray;
286
287import org.xmlpull.v1.XmlPullParser;
288import org.xmlpull.v1.XmlPullParserException;
289import org.xmlpull.v1.XmlSerializer;
290
291import java.io.BufferedOutputStream;
292import java.io.BufferedReader;
293import java.io.ByteArrayInputStream;
294import java.io.ByteArrayOutputStream;
295import java.io.File;
296import java.io.FileDescriptor;
297import java.io.FileInputStream;
298import java.io.FileOutputStream;
299import java.io.FileReader;
300import java.io.FilenameFilter;
301import java.io.IOException;
302import java.io.PrintWriter;
303import java.nio.charset.StandardCharsets;
304import java.security.DigestInputStream;
305import java.security.MessageDigest;
306import java.security.NoSuchAlgorithmException;
307import java.security.PublicKey;
308import java.security.SecureRandom;
309import java.security.cert.Certificate;
310import java.security.cert.CertificateEncodingException;
311import java.security.cert.CertificateException;
312import java.text.SimpleDateFormat;
313import java.util.ArrayList;
314import java.util.Arrays;
315import java.util.Collection;
316import java.util.Collections;
317import java.util.Comparator;
318import java.util.Date;
319import java.util.HashMap;
320import java.util.HashSet;
321import java.util.Iterator;
322import java.util.List;
323import java.util.Map;
324import java.util.Objects;
325import java.util.Set;
326import java.util.concurrent.CountDownLatch;
327import java.util.concurrent.Future;
328import java.util.concurrent.TimeUnit;
329import java.util.concurrent.atomic.AtomicBoolean;
330import java.util.concurrent.atomic.AtomicInteger;
331
332/**
333 * Keep track of all those APKs everywhere.
334 * <p>
335 * Internally there are two important locks:
336 * <ul>
337 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
338 * and other related state. It is a fine-grained lock that should only be held
339 * momentarily, as it's one of the most contended locks in the system.
340 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
341 * operations typically involve heavy lifting of application data on disk. Since
342 * {@code installd} is single-threaded, and it's operations can often be slow,
343 * this lock should never be acquired while already holding {@link #mPackages}.
344 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
345 * holding {@link #mInstallLock}.
346 * </ul>
347 * Many internal methods rely on the caller to hold the appropriate locks, and
348 * this contract is expressed through method name suffixes:
349 * <ul>
350 * <li>fooLI(): the caller must hold {@link #mInstallLock}
351 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
352 * being modified must be frozen
353 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
354 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
355 * </ul>
356 * <p>
357 * Because this class is very central to the platform's security; please run all
358 * CTS and unit tests whenever making modifications:
359 *
360 * <pre>
361 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
362 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
363 * </pre>
364 */
365public class PackageManagerService extends IPackageManager.Stub
366        implements PackageSender {
367    static final String TAG = "PackageManager";
368    static final boolean DEBUG_SETTINGS = false;
369    static final boolean DEBUG_PREFERRED = false;
370    static final boolean DEBUG_UPGRADE = false;
371    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
372    private static final boolean DEBUG_BACKUP = false;
373    private static final boolean DEBUG_INSTALL = false;
374    private static final boolean DEBUG_REMOVE = false;
375    private static final boolean DEBUG_BROADCASTS = false;
376    private static final boolean DEBUG_SHOW_INFO = false;
377    private static final boolean DEBUG_PACKAGE_INFO = false;
378    private static final boolean DEBUG_INTENT_MATCHING = false;
379    private static final boolean DEBUG_PACKAGE_SCANNING = false;
380    private static final boolean DEBUG_VERIFY = false;
381    private static final boolean DEBUG_FILTERS = false;
382    private static final boolean DEBUG_PERMISSIONS = false;
383    private static final boolean DEBUG_SHARED_LIBRARIES = false;
384
385    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
386    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
387    // user, but by default initialize to this.
388    public static final boolean DEBUG_DEXOPT = false;
389
390    private static final boolean DEBUG_ABI_SELECTION = false;
391    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
392    private static final boolean DEBUG_TRIAGED_MISSING = false;
393    private static final boolean DEBUG_APP_DATA = false;
394
395    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
396    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
397
398    private static final boolean HIDE_EPHEMERAL_APIS = false;
399
400    private static final boolean ENABLE_FREE_CACHE_V2 =
401            SystemProperties.getBoolean("fw.free_cache_v2", true);
402
403    private static final int RADIO_UID = Process.PHONE_UID;
404    private static final int LOG_UID = Process.LOG_UID;
405    private static final int NFC_UID = Process.NFC_UID;
406    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
407    private static final int SHELL_UID = Process.SHELL_UID;
408
409    // Cap the size of permission trees that 3rd party apps can define
410    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
411
412    // Suffix used during package installation when copying/moving
413    // package apks to install directory.
414    private static final String INSTALL_PACKAGE_SUFFIX = "-";
415
416    static final int SCAN_NO_DEX = 1<<1;
417    static final int SCAN_FORCE_DEX = 1<<2;
418    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
419    static final int SCAN_NEW_INSTALL = 1<<4;
420    static final int SCAN_UPDATE_TIME = 1<<5;
421    static final int SCAN_BOOTING = 1<<6;
422    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
423    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
424    static final int SCAN_REPLACING = 1<<9;
425    static final int SCAN_REQUIRE_KNOWN = 1<<10;
426    static final int SCAN_MOVE = 1<<11;
427    static final int SCAN_INITIAL = 1<<12;
428    static final int SCAN_CHECK_ONLY = 1<<13;
429    static final int SCAN_DONT_KILL_APP = 1<<14;
430    static final int SCAN_IGNORE_FROZEN = 1<<15;
431    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
432    static final int SCAN_AS_INSTANT_APP = 1<<17;
433    static final int SCAN_AS_FULL_APP = 1<<18;
434    /** Should not be with the scan flags */
435    static final int FLAGS_REMOVE_CHATTY = 1<<31;
436
437    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
438
439    private static final int[] EMPTY_INT_ARRAY = new int[0];
440
441    /**
442     * Timeout (in milliseconds) after which the watchdog should declare that
443     * our handler thread is wedged.  The usual default for such things is one
444     * minute but we sometimes do very lengthy I/O operations on this thread,
445     * such as installing multi-gigabyte applications, so ours needs to be longer.
446     */
447    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
448
449    /**
450     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
451     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
452     * settings entry if available, otherwise we use the hardcoded default.  If it's been
453     * more than this long since the last fstrim, we force one during the boot sequence.
454     *
455     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
456     * one gets run at the next available charging+idle time.  This final mandatory
457     * no-fstrim check kicks in only of the other scheduling criteria is never met.
458     */
459    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
460
461    /**
462     * Whether verification is enabled by default.
463     */
464    private static final boolean DEFAULT_VERIFY_ENABLE = true;
465
466    /**
467     * The default maximum time to wait for the verification agent to return in
468     * milliseconds.
469     */
470    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
471
472    /**
473     * The default response for package verification timeout.
474     *
475     * This can be either PackageManager.VERIFICATION_ALLOW or
476     * PackageManager.VERIFICATION_REJECT.
477     */
478    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
479
480    static final String PLATFORM_PACKAGE_NAME = "android";
481
482    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
483
484    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
485            DEFAULT_CONTAINER_PACKAGE,
486            "com.android.defcontainer.DefaultContainerService");
487
488    private static final String KILL_APP_REASON_GIDS_CHANGED =
489            "permission grant or revoke changed gids";
490
491    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
492            "permissions revoked";
493
494    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
495
496    private static final String PACKAGE_SCHEME = "package";
497
498    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
499
500    /** Permission grant: not grant the permission. */
501    private static final int GRANT_DENIED = 1;
502
503    /** Permission grant: grant the permission as an install permission. */
504    private static final int GRANT_INSTALL = 2;
505
506    /** Permission grant: grant the permission as a runtime one. */
507    private static final int GRANT_RUNTIME = 3;
508
509    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
510    private static final int GRANT_UPGRADE = 4;
511
512    /** Canonical intent used to identify what counts as a "web browser" app */
513    private static final Intent sBrowserIntent;
514    static {
515        sBrowserIntent = new Intent();
516        sBrowserIntent.setAction(Intent.ACTION_VIEW);
517        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
518        sBrowserIntent.setData(Uri.parse("http:"));
519    }
520
521    /**
522     * The set of all protected actions [i.e. those actions for which a high priority
523     * intent filter is disallowed].
524     */
525    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
526    static {
527        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
528        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
529        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
530        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
531    }
532
533    // Compilation reasons.
534    public static final int REASON_FIRST_BOOT = 0;
535    public static final int REASON_BOOT = 1;
536    public static final int REASON_INSTALL = 2;
537    public static final int REASON_BACKGROUND_DEXOPT = 3;
538    public static final int REASON_AB_OTA = 4;
539
540    public static final int REASON_LAST = REASON_AB_OTA;
541
542    /** All dangerous permission names in the same order as the events in MetricsEvent */
543    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
544            Manifest.permission.READ_CALENDAR,
545            Manifest.permission.WRITE_CALENDAR,
546            Manifest.permission.CAMERA,
547            Manifest.permission.READ_CONTACTS,
548            Manifest.permission.WRITE_CONTACTS,
549            Manifest.permission.GET_ACCOUNTS,
550            Manifest.permission.ACCESS_FINE_LOCATION,
551            Manifest.permission.ACCESS_COARSE_LOCATION,
552            Manifest.permission.RECORD_AUDIO,
553            Manifest.permission.READ_PHONE_STATE,
554            Manifest.permission.CALL_PHONE,
555            Manifest.permission.READ_CALL_LOG,
556            Manifest.permission.WRITE_CALL_LOG,
557            Manifest.permission.ADD_VOICEMAIL,
558            Manifest.permission.USE_SIP,
559            Manifest.permission.PROCESS_OUTGOING_CALLS,
560            Manifest.permission.READ_CELL_BROADCASTS,
561            Manifest.permission.BODY_SENSORS,
562            Manifest.permission.SEND_SMS,
563            Manifest.permission.RECEIVE_SMS,
564            Manifest.permission.READ_SMS,
565            Manifest.permission.RECEIVE_WAP_PUSH,
566            Manifest.permission.RECEIVE_MMS,
567            Manifest.permission.READ_EXTERNAL_STORAGE,
568            Manifest.permission.WRITE_EXTERNAL_STORAGE,
569            Manifest.permission.READ_PHONE_NUMBERS,
570            Manifest.permission.ANSWER_PHONE_CALLS);
571
572
573    /**
574     * Version number for the package parser cache. Increment this whenever the format or
575     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
576     */
577    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
578
579    /**
580     * Whether the package parser cache is enabled.
581     */
582    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
583
584    final ServiceThread mHandlerThread;
585
586    final PackageHandler mHandler;
587
588    private final ProcessLoggingHandler mProcessLoggingHandler;
589
590    /**
591     * Messages for {@link #mHandler} that need to wait for system ready before
592     * being dispatched.
593     */
594    private ArrayList<Message> mPostSystemReadyMessages;
595
596    final int mSdkVersion = Build.VERSION.SDK_INT;
597
598    final Context mContext;
599    final boolean mFactoryTest;
600    final boolean mOnlyCore;
601    final DisplayMetrics mMetrics;
602    final int mDefParseFlags;
603    final String[] mSeparateProcesses;
604    final boolean mIsUpgrade;
605    final boolean mIsPreNUpgrade;
606    final boolean mIsPreNMR1Upgrade;
607
608    // Have we told the Activity Manager to whitelist the default container service by uid yet?
609    @GuardedBy("mPackages")
610    boolean mDefaultContainerWhitelisted = false;
611
612    @GuardedBy("mPackages")
613    private boolean mDexOptDialogShown;
614
615    /** The location for ASEC container files on internal storage. */
616    final String mAsecInternalPath;
617
618    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
619    // LOCK HELD.  Can be called with mInstallLock held.
620    @GuardedBy("mInstallLock")
621    final Installer mInstaller;
622
623    /** Directory where installed third-party apps stored */
624    final File mAppInstallDir;
625
626    /**
627     * Directory to which applications installed internally have their
628     * 32 bit native libraries copied.
629     */
630    private File mAppLib32InstallDir;
631
632    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
633    // apps.
634    final File mDrmAppPrivateInstallDir;
635
636    // ----------------------------------------------------------------
637
638    // Lock for state used when installing and doing other long running
639    // operations.  Methods that must be called with this lock held have
640    // the suffix "LI".
641    final Object mInstallLock = new Object();
642
643    // ----------------------------------------------------------------
644
645    // Keys are String (package name), values are Package.  This also serves
646    // as the lock for the global state.  Methods that must be called with
647    // this lock held have the prefix "LP".
648    @GuardedBy("mPackages")
649    final ArrayMap<String, PackageParser.Package> mPackages =
650            new ArrayMap<String, PackageParser.Package>();
651
652    final ArrayMap<String, Set<String>> mKnownCodebase =
653            new ArrayMap<String, Set<String>>();
654
655    // Keys are isolated uids and values are the uid of the application
656    // that created the isolated proccess.
657    @GuardedBy("mPackages")
658    final SparseIntArray mIsolatedOwners = new SparseIntArray();
659
660    // List of APK paths to load for each user and package. This data is never
661    // persisted by the package manager. Instead, the overlay manager will
662    // ensure the data is up-to-date in runtime.
663    @GuardedBy("mPackages")
664    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
665        new SparseArray<ArrayMap<String, ArrayList<String>>>();
666
667    /**
668     * Tracks new system packages [received in an OTA] that we expect to
669     * find updated user-installed versions. Keys are package name, values
670     * are package location.
671     */
672    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
673    /**
674     * Tracks high priority intent filters for protected actions. During boot, certain
675     * filter actions are protected and should never be allowed to have a high priority
676     * intent filter for them. However, there is one, and only one exception -- the
677     * setup wizard. It must be able to define a high priority intent filter for these
678     * actions to ensure there are no escapes from the wizard. We need to delay processing
679     * of these during boot as we need to look at all of the system packages in order
680     * to know which component is the setup wizard.
681     */
682    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
683    /**
684     * Whether or not processing protected filters should be deferred.
685     */
686    private boolean mDeferProtectedFilters = true;
687
688    /**
689     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
690     */
691    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
692    /**
693     * Whether or not system app permissions should be promoted from install to runtime.
694     */
695    boolean mPromoteSystemApps;
696
697    @GuardedBy("mPackages")
698    final Settings mSettings;
699
700    /**
701     * Set of package names that are currently "frozen", which means active
702     * surgery is being done on the code/data for that package. The platform
703     * will refuse to launch frozen packages to avoid race conditions.
704     *
705     * @see PackageFreezer
706     */
707    @GuardedBy("mPackages")
708    final ArraySet<String> mFrozenPackages = new ArraySet<>();
709
710    final ProtectedPackages mProtectedPackages;
711
712    boolean mFirstBoot;
713
714    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
715
716    // System configuration read by SystemConfig.
717    final int[] mGlobalGids;
718    final SparseArray<ArraySet<String>> mSystemPermissions;
719    @GuardedBy("mAvailableFeatures")
720    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
721
722    // If mac_permissions.xml was found for seinfo labeling.
723    boolean mFoundPolicyFile;
724
725    private final InstantAppRegistry mInstantAppRegistry;
726
727    @GuardedBy("mPackages")
728    int mChangedPackagesSequenceNumber;
729    /**
730     * List of changed [installed, removed or updated] packages.
731     * mapping from user id -> sequence number -> package name
732     */
733    @GuardedBy("mPackages")
734    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
735    /**
736     * The sequence number of the last change to a package.
737     * mapping from user id -> package name -> sequence number
738     */
739    @GuardedBy("mPackages")
740    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
741
742    class PackageParserCallback implements PackageParser.Callback {
743        @Override public final boolean hasFeature(String feature) {
744            return PackageManagerService.this.hasSystemFeature(feature, 0);
745        }
746
747        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
748                Collection<PackageParser.Package> allPackages, String targetPackageName) {
749            List<PackageParser.Package> overlayPackages = null;
750            for (PackageParser.Package p : allPackages) {
751                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
752                    if (overlayPackages == null) {
753                        overlayPackages = new ArrayList<PackageParser.Package>();
754                    }
755                    overlayPackages.add(p);
756                }
757            }
758            if (overlayPackages != null) {
759                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
760                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
761                        return p1.mOverlayPriority - p2.mOverlayPriority;
762                    }
763                };
764                Collections.sort(overlayPackages, cmp);
765            }
766            return overlayPackages;
767        }
768
769        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
770                String targetPackageName, String targetPath) {
771            if ("android".equals(targetPackageName)) {
772                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
773                // native AssetManager.
774                return null;
775            }
776            List<PackageParser.Package> overlayPackages =
777                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
778            if (overlayPackages == null || overlayPackages.isEmpty()) {
779                return null;
780            }
781            List<String> overlayPathList = null;
782            for (PackageParser.Package overlayPackage : overlayPackages) {
783                if (targetPath == null) {
784                    if (overlayPathList == null) {
785                        overlayPathList = new ArrayList<String>();
786                    }
787                    overlayPathList.add(overlayPackage.baseCodePath);
788                    continue;
789                }
790
791                try {
792                    // Creates idmaps for system to parse correctly the Android manifest of the
793                    // target package.
794                    //
795                    // OverlayManagerService will update each of them with a correct gid from its
796                    // target package app id.
797                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
798                            UserHandle.getSharedAppGid(
799                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
800                    if (overlayPathList == null) {
801                        overlayPathList = new ArrayList<String>();
802                    }
803                    overlayPathList.add(overlayPackage.baseCodePath);
804                } catch (InstallerException e) {
805                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
806                            overlayPackage.baseCodePath);
807                }
808            }
809            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
810        }
811
812        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
813            synchronized (mPackages) {
814                return getStaticOverlayPathsLocked(
815                        mPackages.values(), targetPackageName, targetPath);
816            }
817        }
818
819        @Override public final String[] getOverlayApks(String targetPackageName) {
820            return getStaticOverlayPaths(targetPackageName, null);
821        }
822
823        @Override public final String[] getOverlayPaths(String targetPackageName,
824                String targetPath) {
825            return getStaticOverlayPaths(targetPackageName, targetPath);
826        }
827    };
828
829    class ParallelPackageParserCallback extends PackageParserCallback {
830        List<PackageParser.Package> mOverlayPackages = null;
831
832        void findStaticOverlayPackages() {
833            synchronized (mPackages) {
834                for (PackageParser.Package p : mPackages.values()) {
835                    if (p.mIsStaticOverlay) {
836                        if (mOverlayPackages == null) {
837                            mOverlayPackages = new ArrayList<PackageParser.Package>();
838                        }
839                        mOverlayPackages.add(p);
840                    }
841                }
842            }
843        }
844
845        @Override
846        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
847            // We can trust mOverlayPackages without holding mPackages because package uninstall
848            // can't happen while running parallel parsing.
849            // Moreover holding mPackages on each parsing thread causes dead-lock.
850            return mOverlayPackages == null ? null :
851                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
852        }
853    }
854
855    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
856    final ParallelPackageParserCallback mParallelPackageParserCallback =
857            new ParallelPackageParserCallback();
858
859    public static final class SharedLibraryEntry {
860        public final String path;
861        public final String apk;
862        public final SharedLibraryInfo info;
863
864        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
865                String declaringPackageName, int declaringPackageVersionCode) {
866            path = _path;
867            apk = _apk;
868            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
869                    declaringPackageName, declaringPackageVersionCode), null);
870        }
871    }
872
873    // Currently known shared libraries.
874    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
875    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
876            new ArrayMap<>();
877
878    // All available activities, for your resolving pleasure.
879    final ActivityIntentResolver mActivities =
880            new ActivityIntentResolver();
881
882    // All available receivers, for your resolving pleasure.
883    final ActivityIntentResolver mReceivers =
884            new ActivityIntentResolver();
885
886    // All available services, for your resolving pleasure.
887    final ServiceIntentResolver mServices = new ServiceIntentResolver();
888
889    // All available providers, for your resolving pleasure.
890    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
891
892    // Mapping from provider base names (first directory in content URI codePath)
893    // to the provider information.
894    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
895            new ArrayMap<String, PackageParser.Provider>();
896
897    // Mapping from instrumentation class names to info about them.
898    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
899            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
900
901    // Mapping from permission names to info about them.
902    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
903            new ArrayMap<String, PackageParser.PermissionGroup>();
904
905    // Packages whose data we have transfered into another package, thus
906    // should no longer exist.
907    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
908
909    // Broadcast actions that are only available to the system.
910    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
911
912    /** List of packages waiting for verification. */
913    final SparseArray<PackageVerificationState> mPendingVerification
914            = new SparseArray<PackageVerificationState>();
915
916    /** Set of packages associated with each app op permission. */
917    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
918
919    final PackageInstallerService mInstallerService;
920
921    private final PackageDexOptimizer mPackageDexOptimizer;
922    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
923    // is used by other apps).
924    private final DexManager mDexManager;
925
926    private AtomicInteger mNextMoveId = new AtomicInteger();
927    private final MoveCallbacks mMoveCallbacks;
928
929    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
930
931    // Cache of users who need badging.
932    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
933
934    /** Token for keys in mPendingVerification. */
935    private int mPendingVerificationToken = 0;
936
937    volatile boolean mSystemReady;
938    volatile boolean mSafeMode;
939    volatile boolean mHasSystemUidErrors;
940    private volatile boolean mEphemeralAppsDisabled;
941
942    ApplicationInfo mAndroidApplication;
943    final ActivityInfo mResolveActivity = new ActivityInfo();
944    final ResolveInfo mResolveInfo = new ResolveInfo();
945    ComponentName mResolveComponentName;
946    PackageParser.Package mPlatformPackage;
947    ComponentName mCustomResolverComponentName;
948
949    boolean mResolverReplaced = false;
950
951    private final @Nullable ComponentName mIntentFilterVerifierComponent;
952    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
953
954    private int mIntentFilterVerificationToken = 0;
955
956    /** The service connection to the ephemeral resolver */
957    final EphemeralResolverConnection mInstantAppResolverConnection;
958    /** Component used to show resolver settings for Instant Apps */
959    final ComponentName mInstantAppResolverSettingsComponent;
960
961    /** Activity used to install instant applications */
962    ActivityInfo mInstantAppInstallerActivity;
963    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
964
965    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
966            = new SparseArray<IntentFilterVerificationState>();
967
968    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
969
970    // List of packages names to keep cached, even if they are uninstalled for all users
971    private List<String> mKeepUninstalledPackages;
972
973    private UserManagerInternal mUserManagerInternal;
974
975    private DeviceIdleController.LocalService mDeviceIdleController;
976
977    private File mCacheDir;
978
979    private ArraySet<String> mPrivappPermissionsViolations;
980
981    private Future<?> mPrepareAppDataFuture;
982
983    private static class IFVerificationParams {
984        PackageParser.Package pkg;
985        boolean replacing;
986        int userId;
987        int verifierUid;
988
989        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
990                int _userId, int _verifierUid) {
991            pkg = _pkg;
992            replacing = _replacing;
993            userId = _userId;
994            replacing = _replacing;
995            verifierUid = _verifierUid;
996        }
997    }
998
999    private interface IntentFilterVerifier<T extends IntentFilter> {
1000        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1001                                               T filter, String packageName);
1002        void startVerifications(int userId);
1003        void receiveVerificationResponse(int verificationId);
1004    }
1005
1006    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1007        private Context mContext;
1008        private ComponentName mIntentFilterVerifierComponent;
1009        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1010
1011        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1012            mContext = context;
1013            mIntentFilterVerifierComponent = verifierComponent;
1014        }
1015
1016        private String getDefaultScheme() {
1017            return IntentFilter.SCHEME_HTTPS;
1018        }
1019
1020        @Override
1021        public void startVerifications(int userId) {
1022            // Launch verifications requests
1023            int count = mCurrentIntentFilterVerifications.size();
1024            for (int n=0; n<count; n++) {
1025                int verificationId = mCurrentIntentFilterVerifications.get(n);
1026                final IntentFilterVerificationState ivs =
1027                        mIntentFilterVerificationStates.get(verificationId);
1028
1029                String packageName = ivs.getPackageName();
1030
1031                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1032                final int filterCount = filters.size();
1033                ArraySet<String> domainsSet = new ArraySet<>();
1034                for (int m=0; m<filterCount; m++) {
1035                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1036                    domainsSet.addAll(filter.getHostsList());
1037                }
1038                synchronized (mPackages) {
1039                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1040                            packageName, domainsSet) != null) {
1041                        scheduleWriteSettingsLocked();
1042                    }
1043                }
1044                sendVerificationRequest(userId, verificationId, ivs);
1045            }
1046            mCurrentIntentFilterVerifications.clear();
1047        }
1048
1049        private void sendVerificationRequest(int userId, int verificationId,
1050                IntentFilterVerificationState ivs) {
1051
1052            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1053            verificationIntent.putExtra(
1054                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1055                    verificationId);
1056            verificationIntent.putExtra(
1057                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1058                    getDefaultScheme());
1059            verificationIntent.putExtra(
1060                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1061                    ivs.getHostsString());
1062            verificationIntent.putExtra(
1063                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1064                    ivs.getPackageName());
1065            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1066            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1067
1068            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1069            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1070                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1071                    userId, false, "intent filter verifier");
1072
1073            UserHandle user = new UserHandle(userId);
1074            mContext.sendBroadcastAsUser(verificationIntent, user);
1075            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1076                    "Sending IntentFilter verification broadcast");
1077        }
1078
1079        public void receiveVerificationResponse(int verificationId) {
1080            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1081
1082            final boolean verified = ivs.isVerified();
1083
1084            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1085            final int count = filters.size();
1086            if (DEBUG_DOMAIN_VERIFICATION) {
1087                Slog.i(TAG, "Received verification response " + verificationId
1088                        + " for " + count + " filters, verified=" + verified);
1089            }
1090            for (int n=0; n<count; n++) {
1091                PackageParser.ActivityIntentInfo filter = filters.get(n);
1092                filter.setVerified(verified);
1093
1094                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1095                        + " verified with result:" + verified + " and hosts:"
1096                        + ivs.getHostsString());
1097            }
1098
1099            mIntentFilterVerificationStates.remove(verificationId);
1100
1101            final String packageName = ivs.getPackageName();
1102            IntentFilterVerificationInfo ivi = null;
1103
1104            synchronized (mPackages) {
1105                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1106            }
1107            if (ivi == null) {
1108                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1109                        + verificationId + " packageName:" + packageName);
1110                return;
1111            }
1112            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1113                    "Updating IntentFilterVerificationInfo for package " + packageName
1114                            +" verificationId:" + verificationId);
1115
1116            synchronized (mPackages) {
1117                if (verified) {
1118                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1119                } else {
1120                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1121                }
1122                scheduleWriteSettingsLocked();
1123
1124                final int userId = ivs.getUserId();
1125                if (userId != UserHandle.USER_ALL) {
1126                    final int userStatus =
1127                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1128
1129                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1130                    boolean needUpdate = false;
1131
1132                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1133                    // already been set by the User thru the Disambiguation dialog
1134                    switch (userStatus) {
1135                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1136                            if (verified) {
1137                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1138                            } else {
1139                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1140                            }
1141                            needUpdate = true;
1142                            break;
1143
1144                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1145                            if (verified) {
1146                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1147                                needUpdate = true;
1148                            }
1149                            break;
1150
1151                        default:
1152                            // Nothing to do
1153                    }
1154
1155                    if (needUpdate) {
1156                        mSettings.updateIntentFilterVerificationStatusLPw(
1157                                packageName, updatedStatus, userId);
1158                        scheduleWritePackageRestrictionsLocked(userId);
1159                    }
1160                }
1161            }
1162        }
1163
1164        @Override
1165        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1166                    ActivityIntentInfo filter, String packageName) {
1167            if (!hasValidDomains(filter)) {
1168                return false;
1169            }
1170            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1171            if (ivs == null) {
1172                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1173                        packageName);
1174            }
1175            if (DEBUG_DOMAIN_VERIFICATION) {
1176                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1177            }
1178            ivs.addFilter(filter);
1179            return true;
1180        }
1181
1182        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1183                int userId, int verificationId, String packageName) {
1184            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1185                    verifierUid, userId, packageName);
1186            ivs.setPendingState();
1187            synchronized (mPackages) {
1188                mIntentFilterVerificationStates.append(verificationId, ivs);
1189                mCurrentIntentFilterVerifications.add(verificationId);
1190            }
1191            return ivs;
1192        }
1193    }
1194
1195    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1196        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1197                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1198                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1199    }
1200
1201    // Set of pending broadcasts for aggregating enable/disable of components.
1202    static class PendingPackageBroadcasts {
1203        // for each user id, a map of <package name -> components within that package>
1204        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1205
1206        public PendingPackageBroadcasts() {
1207            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1208        }
1209
1210        public ArrayList<String> get(int userId, String packageName) {
1211            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1212            return packages.get(packageName);
1213        }
1214
1215        public void put(int userId, String packageName, ArrayList<String> components) {
1216            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1217            packages.put(packageName, components);
1218        }
1219
1220        public void remove(int userId, String packageName) {
1221            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1222            if (packages != null) {
1223                packages.remove(packageName);
1224            }
1225        }
1226
1227        public void remove(int userId) {
1228            mUidMap.remove(userId);
1229        }
1230
1231        public int userIdCount() {
1232            return mUidMap.size();
1233        }
1234
1235        public int userIdAt(int n) {
1236            return mUidMap.keyAt(n);
1237        }
1238
1239        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1240            return mUidMap.get(userId);
1241        }
1242
1243        public int size() {
1244            // total number of pending broadcast entries across all userIds
1245            int num = 0;
1246            for (int i = 0; i< mUidMap.size(); i++) {
1247                num += mUidMap.valueAt(i).size();
1248            }
1249            return num;
1250        }
1251
1252        public void clear() {
1253            mUidMap.clear();
1254        }
1255
1256        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1257            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1258            if (map == null) {
1259                map = new ArrayMap<String, ArrayList<String>>();
1260                mUidMap.put(userId, map);
1261            }
1262            return map;
1263        }
1264    }
1265    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1266
1267    // Service Connection to remote media container service to copy
1268    // package uri's from external media onto secure containers
1269    // or internal storage.
1270    private IMediaContainerService mContainerService = null;
1271
1272    static final int SEND_PENDING_BROADCAST = 1;
1273    static final int MCS_BOUND = 3;
1274    static final int END_COPY = 4;
1275    static final int INIT_COPY = 5;
1276    static final int MCS_UNBIND = 6;
1277    static final int START_CLEANING_PACKAGE = 7;
1278    static final int FIND_INSTALL_LOC = 8;
1279    static final int POST_INSTALL = 9;
1280    static final int MCS_RECONNECT = 10;
1281    static final int MCS_GIVE_UP = 11;
1282    static final int UPDATED_MEDIA_STATUS = 12;
1283    static final int WRITE_SETTINGS = 13;
1284    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1285    static final int PACKAGE_VERIFIED = 15;
1286    static final int CHECK_PENDING_VERIFICATION = 16;
1287    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1288    static final int INTENT_FILTER_VERIFIED = 18;
1289    static final int WRITE_PACKAGE_LIST = 19;
1290    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1291
1292    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1293
1294    // Delay time in millisecs
1295    static final int BROADCAST_DELAY = 10 * 1000;
1296
1297    static UserManagerService sUserManager;
1298
1299    // Stores a list of users whose package restrictions file needs to be updated
1300    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1301
1302    final private DefaultContainerConnection mDefContainerConn =
1303            new DefaultContainerConnection();
1304    class DefaultContainerConnection implements ServiceConnection {
1305        public void onServiceConnected(ComponentName name, IBinder service) {
1306            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1307            final IMediaContainerService imcs = IMediaContainerService.Stub
1308                    .asInterface(Binder.allowBlocking(service));
1309            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1310        }
1311
1312        public void onServiceDisconnected(ComponentName name) {
1313            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1314        }
1315    }
1316
1317    // Recordkeeping of restore-after-install operations that are currently in flight
1318    // between the Package Manager and the Backup Manager
1319    static class PostInstallData {
1320        public InstallArgs args;
1321        public PackageInstalledInfo res;
1322
1323        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1324            args = _a;
1325            res = _r;
1326        }
1327    }
1328
1329    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1330    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1331
1332    // XML tags for backup/restore of various bits of state
1333    private static final String TAG_PREFERRED_BACKUP = "pa";
1334    private static final String TAG_DEFAULT_APPS = "da";
1335    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1336
1337    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1338    private static final String TAG_ALL_GRANTS = "rt-grants";
1339    private static final String TAG_GRANT = "grant";
1340    private static final String ATTR_PACKAGE_NAME = "pkg";
1341
1342    private static final String TAG_PERMISSION = "perm";
1343    private static final String ATTR_PERMISSION_NAME = "name";
1344    private static final String ATTR_IS_GRANTED = "g";
1345    private static final String ATTR_USER_SET = "set";
1346    private static final String ATTR_USER_FIXED = "fixed";
1347    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1348
1349    // System/policy permission grants are not backed up
1350    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1351            FLAG_PERMISSION_POLICY_FIXED
1352            | FLAG_PERMISSION_SYSTEM_FIXED
1353            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1354
1355    // And we back up these user-adjusted states
1356    private static final int USER_RUNTIME_GRANT_MASK =
1357            FLAG_PERMISSION_USER_SET
1358            | FLAG_PERMISSION_USER_FIXED
1359            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1360
1361    final @Nullable String mRequiredVerifierPackage;
1362    final @NonNull String mRequiredInstallerPackage;
1363    final @NonNull String mRequiredUninstallerPackage;
1364    final @Nullable String mSetupWizardPackage;
1365    final @Nullable String mStorageManagerPackage;
1366    final @NonNull String mServicesSystemSharedLibraryPackageName;
1367    final @NonNull String mSharedSystemSharedLibraryPackageName;
1368
1369    final boolean mPermissionReviewRequired;
1370
1371    private final PackageUsage mPackageUsage = new PackageUsage();
1372    private final CompilerStats mCompilerStats = new CompilerStats();
1373
1374    class PackageHandler extends Handler {
1375        private boolean mBound = false;
1376        final ArrayList<HandlerParams> mPendingInstalls =
1377            new ArrayList<HandlerParams>();
1378
1379        private boolean connectToService() {
1380            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1381                    " DefaultContainerService");
1382            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1383            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1384            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1385                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1386                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1387                mBound = true;
1388                return true;
1389            }
1390            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1391            return false;
1392        }
1393
1394        private void disconnectService() {
1395            mContainerService = null;
1396            mBound = false;
1397            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1398            mContext.unbindService(mDefContainerConn);
1399            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1400        }
1401
1402        PackageHandler(Looper looper) {
1403            super(looper);
1404        }
1405
1406        public void handleMessage(Message msg) {
1407            try {
1408                doHandleMessage(msg);
1409            } finally {
1410                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1411            }
1412        }
1413
1414        void doHandleMessage(Message msg) {
1415            switch (msg.what) {
1416                case INIT_COPY: {
1417                    HandlerParams params = (HandlerParams) msg.obj;
1418                    int idx = mPendingInstalls.size();
1419                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1420                    // If a bind was already initiated we dont really
1421                    // need to do anything. The pending install
1422                    // will be processed later on.
1423                    if (!mBound) {
1424                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1425                                System.identityHashCode(mHandler));
1426                        // If this is the only one pending we might
1427                        // have to bind to the service again.
1428                        if (!connectToService()) {
1429                            Slog.e(TAG, "Failed to bind to media container service");
1430                            params.serviceError();
1431                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1432                                    System.identityHashCode(mHandler));
1433                            if (params.traceMethod != null) {
1434                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1435                                        params.traceCookie);
1436                            }
1437                            return;
1438                        } else {
1439                            // Once we bind to the service, the first
1440                            // pending request will be processed.
1441                            mPendingInstalls.add(idx, params);
1442                        }
1443                    } else {
1444                        mPendingInstalls.add(idx, params);
1445                        // Already bound to the service. Just make
1446                        // sure we trigger off processing the first request.
1447                        if (idx == 0) {
1448                            mHandler.sendEmptyMessage(MCS_BOUND);
1449                        }
1450                    }
1451                    break;
1452                }
1453                case MCS_BOUND: {
1454                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1455                    if (msg.obj != null) {
1456                        mContainerService = (IMediaContainerService) msg.obj;
1457                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1458                                System.identityHashCode(mHandler));
1459                    }
1460                    if (mContainerService == null) {
1461                        if (!mBound) {
1462                            // Something seriously wrong since we are not bound and we are not
1463                            // waiting for connection. Bail out.
1464                            Slog.e(TAG, "Cannot bind to media container service");
1465                            for (HandlerParams params : mPendingInstalls) {
1466                                // Indicate service bind error
1467                                params.serviceError();
1468                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1469                                        System.identityHashCode(params));
1470                                if (params.traceMethod != null) {
1471                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1472                                            params.traceMethod, params.traceCookie);
1473                                }
1474                                return;
1475                            }
1476                            mPendingInstalls.clear();
1477                        } else {
1478                            Slog.w(TAG, "Waiting to connect to media container service");
1479                        }
1480                    } else if (mPendingInstalls.size() > 0) {
1481                        HandlerParams params = mPendingInstalls.get(0);
1482                        if (params != null) {
1483                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1484                                    System.identityHashCode(params));
1485                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1486                            if (params.startCopy()) {
1487                                // We are done...  look for more work or to
1488                                // go idle.
1489                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1490                                        "Checking for more work or unbind...");
1491                                // Delete pending install
1492                                if (mPendingInstalls.size() > 0) {
1493                                    mPendingInstalls.remove(0);
1494                                }
1495                                if (mPendingInstalls.size() == 0) {
1496                                    if (mBound) {
1497                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1498                                                "Posting delayed MCS_UNBIND");
1499                                        removeMessages(MCS_UNBIND);
1500                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1501                                        // Unbind after a little delay, to avoid
1502                                        // continual thrashing.
1503                                        sendMessageDelayed(ubmsg, 10000);
1504                                    }
1505                                } else {
1506                                    // There are more pending requests in queue.
1507                                    // Just post MCS_BOUND message to trigger processing
1508                                    // of next pending install.
1509                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1510                                            "Posting MCS_BOUND for next work");
1511                                    mHandler.sendEmptyMessage(MCS_BOUND);
1512                                }
1513                            }
1514                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1515                        }
1516                    } else {
1517                        // Should never happen ideally.
1518                        Slog.w(TAG, "Empty queue");
1519                    }
1520                    break;
1521                }
1522                case MCS_RECONNECT: {
1523                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1524                    if (mPendingInstalls.size() > 0) {
1525                        if (mBound) {
1526                            disconnectService();
1527                        }
1528                        if (!connectToService()) {
1529                            Slog.e(TAG, "Failed to bind to media container service");
1530                            for (HandlerParams params : mPendingInstalls) {
1531                                // Indicate service bind error
1532                                params.serviceError();
1533                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1534                                        System.identityHashCode(params));
1535                            }
1536                            mPendingInstalls.clear();
1537                        }
1538                    }
1539                    break;
1540                }
1541                case MCS_UNBIND: {
1542                    // If there is no actual work left, then time to unbind.
1543                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1544
1545                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1546                        if (mBound) {
1547                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1548
1549                            disconnectService();
1550                        }
1551                    } else if (mPendingInstalls.size() > 0) {
1552                        // There are more pending requests in queue.
1553                        // Just post MCS_BOUND message to trigger processing
1554                        // of next pending install.
1555                        mHandler.sendEmptyMessage(MCS_BOUND);
1556                    }
1557
1558                    break;
1559                }
1560                case MCS_GIVE_UP: {
1561                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1562                    HandlerParams params = mPendingInstalls.remove(0);
1563                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1564                            System.identityHashCode(params));
1565                    break;
1566                }
1567                case SEND_PENDING_BROADCAST: {
1568                    String packages[];
1569                    ArrayList<String> components[];
1570                    int size = 0;
1571                    int uids[];
1572                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1573                    synchronized (mPackages) {
1574                        if (mPendingBroadcasts == null) {
1575                            return;
1576                        }
1577                        size = mPendingBroadcasts.size();
1578                        if (size <= 0) {
1579                            // Nothing to be done. Just return
1580                            return;
1581                        }
1582                        packages = new String[size];
1583                        components = new ArrayList[size];
1584                        uids = new int[size];
1585                        int i = 0;  // filling out the above arrays
1586
1587                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1588                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1589                            Iterator<Map.Entry<String, ArrayList<String>>> it
1590                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1591                                            .entrySet().iterator();
1592                            while (it.hasNext() && i < size) {
1593                                Map.Entry<String, ArrayList<String>> ent = it.next();
1594                                packages[i] = ent.getKey();
1595                                components[i] = ent.getValue();
1596                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1597                                uids[i] = (ps != null)
1598                                        ? UserHandle.getUid(packageUserId, ps.appId)
1599                                        : -1;
1600                                i++;
1601                            }
1602                        }
1603                        size = i;
1604                        mPendingBroadcasts.clear();
1605                    }
1606                    // Send broadcasts
1607                    for (int i = 0; i < size; i++) {
1608                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1609                    }
1610                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1611                    break;
1612                }
1613                case START_CLEANING_PACKAGE: {
1614                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1615                    final String packageName = (String)msg.obj;
1616                    final int userId = msg.arg1;
1617                    final boolean andCode = msg.arg2 != 0;
1618                    synchronized (mPackages) {
1619                        if (userId == UserHandle.USER_ALL) {
1620                            int[] users = sUserManager.getUserIds();
1621                            for (int user : users) {
1622                                mSettings.addPackageToCleanLPw(
1623                                        new PackageCleanItem(user, packageName, andCode));
1624                            }
1625                        } else {
1626                            mSettings.addPackageToCleanLPw(
1627                                    new PackageCleanItem(userId, packageName, andCode));
1628                        }
1629                    }
1630                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1631                    startCleaningPackages();
1632                } break;
1633                case POST_INSTALL: {
1634                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1635
1636                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1637                    final boolean didRestore = (msg.arg2 != 0);
1638                    mRunningInstalls.delete(msg.arg1);
1639
1640                    if (data != null) {
1641                        InstallArgs args = data.args;
1642                        PackageInstalledInfo parentRes = data.res;
1643
1644                        final boolean grantPermissions = (args.installFlags
1645                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1646                        final boolean killApp = (args.installFlags
1647                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1648                        final String[] grantedPermissions = args.installGrantPermissions;
1649
1650                        // Handle the parent package
1651                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1652                                grantedPermissions, didRestore, args.installerPackageName,
1653                                args.observer);
1654
1655                        // Handle the child packages
1656                        final int childCount = (parentRes.addedChildPackages != null)
1657                                ? parentRes.addedChildPackages.size() : 0;
1658                        for (int i = 0; i < childCount; i++) {
1659                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1660                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1661                                    grantedPermissions, false, args.installerPackageName,
1662                                    args.observer);
1663                        }
1664
1665                        // Log tracing if needed
1666                        if (args.traceMethod != null) {
1667                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1668                                    args.traceCookie);
1669                        }
1670                    } else {
1671                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1672                    }
1673
1674                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1675                } break;
1676                case UPDATED_MEDIA_STATUS: {
1677                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1678                    boolean reportStatus = msg.arg1 == 1;
1679                    boolean doGc = msg.arg2 == 1;
1680                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1681                    if (doGc) {
1682                        // Force a gc to clear up stale containers.
1683                        Runtime.getRuntime().gc();
1684                    }
1685                    if (msg.obj != null) {
1686                        @SuppressWarnings("unchecked")
1687                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1688                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1689                        // Unload containers
1690                        unloadAllContainers(args);
1691                    }
1692                    if (reportStatus) {
1693                        try {
1694                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1695                                    "Invoking StorageManagerService call back");
1696                            PackageHelper.getStorageManager().finishMediaUpdate();
1697                        } catch (RemoteException e) {
1698                            Log.e(TAG, "StorageManagerService not running?");
1699                        }
1700                    }
1701                } break;
1702                case WRITE_SETTINGS: {
1703                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1704                    synchronized (mPackages) {
1705                        removeMessages(WRITE_SETTINGS);
1706                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1707                        mSettings.writeLPr();
1708                        mDirtyUsers.clear();
1709                    }
1710                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1711                } break;
1712                case WRITE_PACKAGE_RESTRICTIONS: {
1713                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1714                    synchronized (mPackages) {
1715                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1716                        for (int userId : mDirtyUsers) {
1717                            mSettings.writePackageRestrictionsLPr(userId);
1718                        }
1719                        mDirtyUsers.clear();
1720                    }
1721                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1722                } break;
1723                case WRITE_PACKAGE_LIST: {
1724                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1725                    synchronized (mPackages) {
1726                        removeMessages(WRITE_PACKAGE_LIST);
1727                        mSettings.writePackageListLPr(msg.arg1);
1728                    }
1729                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1730                } break;
1731                case CHECK_PENDING_VERIFICATION: {
1732                    final int verificationId = msg.arg1;
1733                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1734
1735                    if ((state != null) && !state.timeoutExtended()) {
1736                        final InstallArgs args = state.getInstallArgs();
1737                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1738
1739                        Slog.i(TAG, "Verification timed out for " + originUri);
1740                        mPendingVerification.remove(verificationId);
1741
1742                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1743
1744                        final UserHandle user = args.getUser();
1745                        if (getDefaultVerificationResponse(user)
1746                                == PackageManager.VERIFICATION_ALLOW) {
1747                            Slog.i(TAG, "Continuing with installation of " + originUri);
1748                            state.setVerifierResponse(Binder.getCallingUid(),
1749                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1750                            broadcastPackageVerified(verificationId, originUri,
1751                                    PackageManager.VERIFICATION_ALLOW, user);
1752                            try {
1753                                ret = args.copyApk(mContainerService, true);
1754                            } catch (RemoteException e) {
1755                                Slog.e(TAG, "Could not contact the ContainerService");
1756                            }
1757                        } else {
1758                            broadcastPackageVerified(verificationId, originUri,
1759                                    PackageManager.VERIFICATION_REJECT, user);
1760                        }
1761
1762                        Trace.asyncTraceEnd(
1763                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1764
1765                        processPendingInstall(args, ret);
1766                        mHandler.sendEmptyMessage(MCS_UNBIND);
1767                    }
1768                    break;
1769                }
1770                case PACKAGE_VERIFIED: {
1771                    final int verificationId = msg.arg1;
1772
1773                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1774                    if (state == null) {
1775                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1776                        break;
1777                    }
1778
1779                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1780
1781                    state.setVerifierResponse(response.callerUid, response.code);
1782
1783                    if (state.isVerificationComplete()) {
1784                        mPendingVerification.remove(verificationId);
1785
1786                        final InstallArgs args = state.getInstallArgs();
1787                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1788
1789                        int ret;
1790                        if (state.isInstallAllowed()) {
1791                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1792                            broadcastPackageVerified(verificationId, originUri,
1793                                    response.code, state.getInstallArgs().getUser());
1794                            try {
1795                                ret = args.copyApk(mContainerService, true);
1796                            } catch (RemoteException e) {
1797                                Slog.e(TAG, "Could not contact the ContainerService");
1798                            }
1799                        } else {
1800                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1801                        }
1802
1803                        Trace.asyncTraceEnd(
1804                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1805
1806                        processPendingInstall(args, ret);
1807                        mHandler.sendEmptyMessage(MCS_UNBIND);
1808                    }
1809
1810                    break;
1811                }
1812                case START_INTENT_FILTER_VERIFICATIONS: {
1813                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1814                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1815                            params.replacing, params.pkg);
1816                    break;
1817                }
1818                case INTENT_FILTER_VERIFIED: {
1819                    final int verificationId = msg.arg1;
1820
1821                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1822                            verificationId);
1823                    if (state == null) {
1824                        Slog.w(TAG, "Invalid IntentFilter verification token "
1825                                + verificationId + " received");
1826                        break;
1827                    }
1828
1829                    final int userId = state.getUserId();
1830
1831                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1832                            "Processing IntentFilter verification with token:"
1833                            + verificationId + " and userId:" + userId);
1834
1835                    final IntentFilterVerificationResponse response =
1836                            (IntentFilterVerificationResponse) msg.obj;
1837
1838                    state.setVerifierResponse(response.callerUid, response.code);
1839
1840                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1841                            "IntentFilter verification with token:" + verificationId
1842                            + " and userId:" + userId
1843                            + " is settings verifier response with response code:"
1844                            + response.code);
1845
1846                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1847                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1848                                + response.getFailedDomainsString());
1849                    }
1850
1851                    if (state.isVerificationComplete()) {
1852                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1853                    } else {
1854                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1855                                "IntentFilter verification with token:" + verificationId
1856                                + " was not said to be complete");
1857                    }
1858
1859                    break;
1860                }
1861                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1862                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1863                            mInstantAppResolverConnection,
1864                            (InstantAppRequest) msg.obj,
1865                            mInstantAppInstallerActivity,
1866                            mHandler);
1867                }
1868            }
1869        }
1870    }
1871
1872    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1873            boolean killApp, String[] grantedPermissions,
1874            boolean launchedForRestore, String installerPackage,
1875            IPackageInstallObserver2 installObserver) {
1876        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1877            // Send the removed broadcasts
1878            if (res.removedInfo != null) {
1879                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1880            }
1881
1882            // Now that we successfully installed the package, grant runtime
1883            // permissions if requested before broadcasting the install. Also
1884            // for legacy apps in permission review mode we clear the permission
1885            // review flag which is used to emulate runtime permissions for
1886            // legacy apps.
1887            if (grantPermissions) {
1888                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1889            }
1890
1891            final boolean update = res.removedInfo != null
1892                    && res.removedInfo.removedPackage != null;
1893            final String origInstallerPackageName = res.removedInfo != null
1894                    ? res.removedInfo.installerPackageName : null;
1895
1896            // If this is the first time we have child packages for a disabled privileged
1897            // app that had no children, we grant requested runtime permissions to the new
1898            // children if the parent on the system image had them already granted.
1899            if (res.pkg.parentPackage != null) {
1900                synchronized (mPackages) {
1901                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1902                }
1903            }
1904
1905            synchronized (mPackages) {
1906                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1907            }
1908
1909            final String packageName = res.pkg.applicationInfo.packageName;
1910
1911            // Determine the set of users who are adding this package for
1912            // the first time vs. those who are seeing an update.
1913            int[] firstUsers = EMPTY_INT_ARRAY;
1914            int[] updateUsers = EMPTY_INT_ARRAY;
1915            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1916            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1917            for (int newUser : res.newUsers) {
1918                if (ps.getInstantApp(newUser)) {
1919                    continue;
1920                }
1921                if (allNewUsers) {
1922                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1923                    continue;
1924                }
1925                boolean isNew = true;
1926                for (int origUser : res.origUsers) {
1927                    if (origUser == newUser) {
1928                        isNew = false;
1929                        break;
1930                    }
1931                }
1932                if (isNew) {
1933                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1934                } else {
1935                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1936                }
1937            }
1938
1939            // Send installed broadcasts if the package is not a static shared lib.
1940            if (res.pkg.staticSharedLibName == null) {
1941                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1942
1943                // Send added for users that see the package for the first time
1944                // sendPackageAddedForNewUsers also deals with system apps
1945                int appId = UserHandle.getAppId(res.uid);
1946                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1947                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1948
1949                // Send added for users that don't see the package for the first time
1950                Bundle extras = new Bundle(1);
1951                extras.putInt(Intent.EXTRA_UID, res.uid);
1952                if (update) {
1953                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1954                }
1955                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1956                        extras, 0 /*flags*/,
1957                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1958                if (origInstallerPackageName != null) {
1959                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1960                            extras, 0 /*flags*/,
1961                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1962                }
1963
1964                // Send replaced for users that don't see the package for the first time
1965                if (update) {
1966                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1967                            packageName, extras, 0 /*flags*/,
1968                            null /*targetPackage*/, null /*finishedReceiver*/,
1969                            updateUsers);
1970                    if (origInstallerPackageName != null) {
1971                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1972                                extras, 0 /*flags*/,
1973                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1974                    }
1975                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1976                            null /*package*/, null /*extras*/, 0 /*flags*/,
1977                            packageName /*targetPackage*/,
1978                            null /*finishedReceiver*/, updateUsers);
1979                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1980                    // First-install and we did a restore, so we're responsible for the
1981                    // first-launch broadcast.
1982                    if (DEBUG_BACKUP) {
1983                        Slog.i(TAG, "Post-restore of " + packageName
1984                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1985                    }
1986                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1987                }
1988
1989                // Send broadcast package appeared if forward locked/external for all users
1990                // treat asec-hosted packages like removable media on upgrade
1991                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1992                    if (DEBUG_INSTALL) {
1993                        Slog.i(TAG, "upgrading pkg " + res.pkg
1994                                + " is ASEC-hosted -> AVAILABLE");
1995                    }
1996                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1997                    ArrayList<String> pkgList = new ArrayList<>(1);
1998                    pkgList.add(packageName);
1999                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2000                }
2001            }
2002
2003            // Work that needs to happen on first install within each user
2004            if (firstUsers != null && firstUsers.length > 0) {
2005                synchronized (mPackages) {
2006                    for (int userId : firstUsers) {
2007                        // If this app is a browser and it's newly-installed for some
2008                        // users, clear any default-browser state in those users. The
2009                        // app's nature doesn't depend on the user, so we can just check
2010                        // its browser nature in any user and generalize.
2011                        if (packageIsBrowser(packageName, userId)) {
2012                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2013                        }
2014
2015                        // We may also need to apply pending (restored) runtime
2016                        // permission grants within these users.
2017                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2018                    }
2019                }
2020            }
2021
2022            // Log current value of "unknown sources" setting
2023            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2024                    getUnknownSourcesSettings());
2025
2026            // Remove the replaced package's older resources safely now
2027            // We delete after a gc for applications  on sdcard.
2028            if (res.removedInfo != null && res.removedInfo.args != null) {
2029                Runtime.getRuntime().gc();
2030                synchronized (mInstallLock) {
2031                    res.removedInfo.args.doPostDeleteLI(true);
2032                }
2033            } else {
2034                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2035                // and not block here.
2036                VMRuntime.getRuntime().requestConcurrentGC();
2037            }
2038
2039            // Notify DexManager that the package was installed for new users.
2040            // The updated users should already be indexed and the package code paths
2041            // should not change.
2042            // Don't notify the manager for ephemeral apps as they are not expected to
2043            // survive long enough to benefit of background optimizations.
2044            for (int userId : firstUsers) {
2045                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2046                // There's a race currently where some install events may interleave with an uninstall.
2047                // This can lead to package info being null (b/36642664).
2048                if (info != null) {
2049                    mDexManager.notifyPackageInstalled(info, userId);
2050                }
2051            }
2052        }
2053
2054        // If someone is watching installs - notify them
2055        if (installObserver != null) {
2056            try {
2057                Bundle extras = extrasForInstallResult(res);
2058                installObserver.onPackageInstalled(res.name, res.returnCode,
2059                        res.returnMsg, extras);
2060            } catch (RemoteException e) {
2061                Slog.i(TAG, "Observer no longer exists.");
2062            }
2063        }
2064    }
2065
2066    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2067            PackageParser.Package pkg) {
2068        if (pkg.parentPackage == null) {
2069            return;
2070        }
2071        if (pkg.requestedPermissions == null) {
2072            return;
2073        }
2074        final PackageSetting disabledSysParentPs = mSettings
2075                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2076        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2077                || !disabledSysParentPs.isPrivileged()
2078                || (disabledSysParentPs.childPackageNames != null
2079                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2080            return;
2081        }
2082        final int[] allUserIds = sUserManager.getUserIds();
2083        final int permCount = pkg.requestedPermissions.size();
2084        for (int i = 0; i < permCount; i++) {
2085            String permission = pkg.requestedPermissions.get(i);
2086            BasePermission bp = mSettings.mPermissions.get(permission);
2087            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2088                continue;
2089            }
2090            for (int userId : allUserIds) {
2091                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2092                        permission, userId)) {
2093                    grantRuntimePermission(pkg.packageName, permission, userId);
2094                }
2095            }
2096        }
2097    }
2098
2099    private StorageEventListener mStorageListener = new StorageEventListener() {
2100        @Override
2101        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2102            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2103                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2104                    final String volumeUuid = vol.getFsUuid();
2105
2106                    // Clean up any users or apps that were removed or recreated
2107                    // while this volume was missing
2108                    sUserManager.reconcileUsers(volumeUuid);
2109                    reconcileApps(volumeUuid);
2110
2111                    // Clean up any install sessions that expired or were
2112                    // cancelled while this volume was missing
2113                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2114
2115                    loadPrivatePackages(vol);
2116
2117                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2118                    unloadPrivatePackages(vol);
2119                }
2120            }
2121
2122            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2123                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2124                    updateExternalMediaStatus(true, false);
2125                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2126                    updateExternalMediaStatus(false, false);
2127                }
2128            }
2129        }
2130
2131        @Override
2132        public void onVolumeForgotten(String fsUuid) {
2133            if (TextUtils.isEmpty(fsUuid)) {
2134                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2135                return;
2136            }
2137
2138            // Remove any apps installed on the forgotten volume
2139            synchronized (mPackages) {
2140                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2141                for (PackageSetting ps : packages) {
2142                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2143                    deletePackageVersioned(new VersionedPackage(ps.name,
2144                            PackageManager.VERSION_CODE_HIGHEST),
2145                            new LegacyPackageDeleteObserver(null).getBinder(),
2146                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2147                    // Try very hard to release any references to this package
2148                    // so we don't risk the system server being killed due to
2149                    // open FDs
2150                    AttributeCache.instance().removePackage(ps.name);
2151                }
2152
2153                mSettings.onVolumeForgotten(fsUuid);
2154                mSettings.writeLPr();
2155            }
2156        }
2157    };
2158
2159    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2160            String[] grantedPermissions) {
2161        for (int userId : userIds) {
2162            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2163        }
2164    }
2165
2166    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2167            String[] grantedPermissions) {
2168        SettingBase sb = (SettingBase) pkg.mExtras;
2169        if (sb == null) {
2170            return;
2171        }
2172
2173        PermissionsState permissionsState = sb.getPermissionsState();
2174
2175        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2176                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2177
2178        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2179                >= Build.VERSION_CODES.M;
2180
2181        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2182
2183        for (String permission : pkg.requestedPermissions) {
2184            final BasePermission bp;
2185            synchronized (mPackages) {
2186                bp = mSettings.mPermissions.get(permission);
2187            }
2188            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2189                    && (!instantApp || bp.isInstant())
2190                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2191                    && (grantedPermissions == null
2192                           || ArrayUtils.contains(grantedPermissions, permission))) {
2193                final int flags = permissionsState.getPermissionFlags(permission, userId);
2194                if (supportsRuntimePermissions) {
2195                    // Installer cannot change immutable permissions.
2196                    if ((flags & immutableFlags) == 0) {
2197                        grantRuntimePermission(pkg.packageName, permission, userId);
2198                    }
2199                } else if (mPermissionReviewRequired) {
2200                    // In permission review mode we clear the review flag when we
2201                    // are asked to install the app with all permissions granted.
2202                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2203                        updatePermissionFlags(permission, pkg.packageName,
2204                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2205                    }
2206                }
2207            }
2208        }
2209    }
2210
2211    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2212        Bundle extras = null;
2213        switch (res.returnCode) {
2214            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2215                extras = new Bundle();
2216                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2217                        res.origPermission);
2218                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2219                        res.origPackage);
2220                break;
2221            }
2222            case PackageManager.INSTALL_SUCCEEDED: {
2223                extras = new Bundle();
2224                extras.putBoolean(Intent.EXTRA_REPLACING,
2225                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2226                break;
2227            }
2228        }
2229        return extras;
2230    }
2231
2232    void scheduleWriteSettingsLocked() {
2233        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2234            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2235        }
2236    }
2237
2238    void scheduleWritePackageListLocked(int userId) {
2239        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2240            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2241            msg.arg1 = userId;
2242            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2243        }
2244    }
2245
2246    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2247        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2248        scheduleWritePackageRestrictionsLocked(userId);
2249    }
2250
2251    void scheduleWritePackageRestrictionsLocked(int userId) {
2252        final int[] userIds = (userId == UserHandle.USER_ALL)
2253                ? sUserManager.getUserIds() : new int[]{userId};
2254        for (int nextUserId : userIds) {
2255            if (!sUserManager.exists(nextUserId)) return;
2256            mDirtyUsers.add(nextUserId);
2257            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2258                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2259            }
2260        }
2261    }
2262
2263    public static PackageManagerService main(Context context, Installer installer,
2264            boolean factoryTest, boolean onlyCore) {
2265        // Self-check for initial settings.
2266        PackageManagerServiceCompilerMapping.checkProperties();
2267
2268        PackageManagerService m = new PackageManagerService(context, installer,
2269                factoryTest, onlyCore);
2270        m.enableSystemUserPackages();
2271        ServiceManager.addService("package", m);
2272        return m;
2273    }
2274
2275    private void enableSystemUserPackages() {
2276        if (!UserManager.isSplitSystemUser()) {
2277            return;
2278        }
2279        // For system user, enable apps based on the following conditions:
2280        // - app is whitelisted or belong to one of these groups:
2281        //   -- system app which has no launcher icons
2282        //   -- system app which has INTERACT_ACROSS_USERS permission
2283        //   -- system IME app
2284        // - app is not in the blacklist
2285        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2286        Set<String> enableApps = new ArraySet<>();
2287        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2288                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2289                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2290        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2291        enableApps.addAll(wlApps);
2292        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2293                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2294        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2295        enableApps.removeAll(blApps);
2296        Log.i(TAG, "Applications installed for system user: " + enableApps);
2297        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2298                UserHandle.SYSTEM);
2299        final int allAppsSize = allAps.size();
2300        synchronized (mPackages) {
2301            for (int i = 0; i < allAppsSize; i++) {
2302                String pName = allAps.get(i);
2303                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2304                // Should not happen, but we shouldn't be failing if it does
2305                if (pkgSetting == null) {
2306                    continue;
2307                }
2308                boolean install = enableApps.contains(pName);
2309                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2310                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2311                            + " for system user");
2312                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2313                }
2314            }
2315            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2316        }
2317    }
2318
2319    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2320        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2321                Context.DISPLAY_SERVICE);
2322        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2323    }
2324
2325    /**
2326     * Requests that files preopted on a secondary system partition be copied to the data partition
2327     * if possible.  Note that the actual copying of the files is accomplished by init for security
2328     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2329     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2330     */
2331    private static void requestCopyPreoptedFiles() {
2332        final int WAIT_TIME_MS = 100;
2333        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2334        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2335            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2336            // We will wait for up to 100 seconds.
2337            final long timeStart = SystemClock.uptimeMillis();
2338            final long timeEnd = timeStart + 100 * 1000;
2339            long timeNow = timeStart;
2340            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2341                try {
2342                    Thread.sleep(WAIT_TIME_MS);
2343                } catch (InterruptedException e) {
2344                    // Do nothing
2345                }
2346                timeNow = SystemClock.uptimeMillis();
2347                if (timeNow > timeEnd) {
2348                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2349                    Slog.wtf(TAG, "cppreopt did not finish!");
2350                    break;
2351                }
2352            }
2353
2354            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2355        }
2356    }
2357
2358    public PackageManagerService(Context context, Installer installer,
2359            boolean factoryTest, boolean onlyCore) {
2360        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2361        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2362        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2363                SystemClock.uptimeMillis());
2364
2365        if (mSdkVersion <= 0) {
2366            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2367        }
2368
2369        mContext = context;
2370
2371        mPermissionReviewRequired = context.getResources().getBoolean(
2372                R.bool.config_permissionReviewRequired);
2373
2374        mFactoryTest = factoryTest;
2375        mOnlyCore = onlyCore;
2376        mMetrics = new DisplayMetrics();
2377        mSettings = new Settings(mPackages);
2378        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2379                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2380        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2381                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2382        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2383                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2384        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2385                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2386        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2387                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2388        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2389                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2390
2391        String separateProcesses = SystemProperties.get("debug.separate_processes");
2392        if (separateProcesses != null && separateProcesses.length() > 0) {
2393            if ("*".equals(separateProcesses)) {
2394                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2395                mSeparateProcesses = null;
2396                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2397            } else {
2398                mDefParseFlags = 0;
2399                mSeparateProcesses = separateProcesses.split(",");
2400                Slog.w(TAG, "Running with debug.separate_processes: "
2401                        + separateProcesses);
2402            }
2403        } else {
2404            mDefParseFlags = 0;
2405            mSeparateProcesses = null;
2406        }
2407
2408        mInstaller = installer;
2409        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2410                "*dexopt*");
2411        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2412        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2413
2414        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2415                FgThread.get().getLooper());
2416
2417        getDefaultDisplayMetrics(context, mMetrics);
2418
2419        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2420        SystemConfig systemConfig = SystemConfig.getInstance();
2421        mGlobalGids = systemConfig.getGlobalGids();
2422        mSystemPermissions = systemConfig.getSystemPermissions();
2423        mAvailableFeatures = systemConfig.getAvailableFeatures();
2424        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2425
2426        mProtectedPackages = new ProtectedPackages(mContext);
2427
2428        synchronized (mInstallLock) {
2429        // writer
2430        synchronized (mPackages) {
2431            mHandlerThread = new ServiceThread(TAG,
2432                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2433            mHandlerThread.start();
2434            mHandler = new PackageHandler(mHandlerThread.getLooper());
2435            mProcessLoggingHandler = new ProcessLoggingHandler();
2436            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2437
2438            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2439            mInstantAppRegistry = new InstantAppRegistry(this);
2440
2441            File dataDir = Environment.getDataDirectory();
2442            mAppInstallDir = new File(dataDir, "app");
2443            mAppLib32InstallDir = new File(dataDir, "app-lib");
2444            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2445            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2446            sUserManager = new UserManagerService(context, this,
2447                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2448
2449            // Propagate permission configuration in to package manager.
2450            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2451                    = systemConfig.getPermissions();
2452            for (int i=0; i<permConfig.size(); i++) {
2453                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2454                BasePermission bp = mSettings.mPermissions.get(perm.name);
2455                if (bp == null) {
2456                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2457                    mSettings.mPermissions.put(perm.name, bp);
2458                }
2459                if (perm.gids != null) {
2460                    bp.setGids(perm.gids, perm.perUser);
2461                }
2462            }
2463
2464            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2465            final int builtInLibCount = libConfig.size();
2466            for (int i = 0; i < builtInLibCount; i++) {
2467                String name = libConfig.keyAt(i);
2468                String path = libConfig.valueAt(i);
2469                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2470                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2471            }
2472
2473            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2474
2475            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2476            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2477            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2478
2479            // Clean up orphaned packages for which the code path doesn't exist
2480            // and they are an update to a system app - caused by bug/32321269
2481            final int packageSettingCount = mSettings.mPackages.size();
2482            for (int i = packageSettingCount - 1; i >= 0; i--) {
2483                PackageSetting ps = mSettings.mPackages.valueAt(i);
2484                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2485                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2486                    mSettings.mPackages.removeAt(i);
2487                    mSettings.enableSystemPackageLPw(ps.name);
2488                }
2489            }
2490
2491            if (mFirstBoot) {
2492                requestCopyPreoptedFiles();
2493            }
2494
2495            String customResolverActivity = Resources.getSystem().getString(
2496                    R.string.config_customResolverActivity);
2497            if (TextUtils.isEmpty(customResolverActivity)) {
2498                customResolverActivity = null;
2499            } else {
2500                mCustomResolverComponentName = ComponentName.unflattenFromString(
2501                        customResolverActivity);
2502            }
2503
2504            long startTime = SystemClock.uptimeMillis();
2505
2506            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2507                    startTime);
2508
2509            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2510            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2511
2512            if (bootClassPath == null) {
2513                Slog.w(TAG, "No BOOTCLASSPATH found!");
2514            }
2515
2516            if (systemServerClassPath == null) {
2517                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2518            }
2519
2520            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2521
2522            final VersionInfo ver = mSettings.getInternalVersion();
2523            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2524            if (mIsUpgrade) {
2525                logCriticalInfo(Log.INFO,
2526                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2527            }
2528
2529            // when upgrading from pre-M, promote system app permissions from install to runtime
2530            mPromoteSystemApps =
2531                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2532
2533            // When upgrading from pre-N, we need to handle package extraction like first boot,
2534            // as there is no profiling data available.
2535            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2536
2537            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2538
2539            // save off the names of pre-existing system packages prior to scanning; we don't
2540            // want to automatically grant runtime permissions for new system apps
2541            if (mPromoteSystemApps) {
2542                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2543                while (pkgSettingIter.hasNext()) {
2544                    PackageSetting ps = pkgSettingIter.next();
2545                    if (isSystemApp(ps)) {
2546                        mExistingSystemPackages.add(ps.name);
2547                    }
2548                }
2549            }
2550
2551            mCacheDir = preparePackageParserCache(mIsUpgrade);
2552
2553            // Set flag to monitor and not change apk file paths when
2554            // scanning install directories.
2555            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2556
2557            if (mIsUpgrade || mFirstBoot) {
2558                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2559            }
2560
2561            // Collect vendor overlay packages. (Do this before scanning any apps.)
2562            // For security and version matching reason, only consider
2563            // overlay packages if they reside in the right directory.
2564            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2565                    | PackageParser.PARSE_IS_SYSTEM
2566                    | PackageParser.PARSE_IS_SYSTEM_DIR
2567                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2568
2569            mParallelPackageParserCallback.findStaticOverlayPackages();
2570
2571            // Find base frameworks (resource packages without code).
2572            scanDirTracedLI(frameworkDir, mDefParseFlags
2573                    | PackageParser.PARSE_IS_SYSTEM
2574                    | PackageParser.PARSE_IS_SYSTEM_DIR
2575                    | PackageParser.PARSE_IS_PRIVILEGED,
2576                    scanFlags | SCAN_NO_DEX, 0);
2577
2578            // Collected privileged system packages.
2579            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2580            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2581                    | PackageParser.PARSE_IS_SYSTEM
2582                    | PackageParser.PARSE_IS_SYSTEM_DIR
2583                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2584
2585            // Collect ordinary system packages.
2586            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2587            scanDirTracedLI(systemAppDir, mDefParseFlags
2588                    | PackageParser.PARSE_IS_SYSTEM
2589                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2590
2591            // Collect all vendor packages.
2592            File vendorAppDir = new File("/vendor/app");
2593            try {
2594                vendorAppDir = vendorAppDir.getCanonicalFile();
2595            } catch (IOException e) {
2596                // failed to look up canonical path, continue with original one
2597            }
2598            scanDirTracedLI(vendorAppDir, mDefParseFlags
2599                    | PackageParser.PARSE_IS_SYSTEM
2600                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2601
2602            // Collect all OEM packages.
2603            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2604            scanDirTracedLI(oemAppDir, mDefParseFlags
2605                    | PackageParser.PARSE_IS_SYSTEM
2606                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2607
2608            // Prune any system packages that no longer exist.
2609            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2610            if (!mOnlyCore) {
2611                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2612                while (psit.hasNext()) {
2613                    PackageSetting ps = psit.next();
2614
2615                    /*
2616                     * If this is not a system app, it can't be a
2617                     * disable system app.
2618                     */
2619                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2620                        continue;
2621                    }
2622
2623                    /*
2624                     * If the package is scanned, it's not erased.
2625                     */
2626                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2627                    if (scannedPkg != null) {
2628                        /*
2629                         * If the system app is both scanned and in the
2630                         * disabled packages list, then it must have been
2631                         * added via OTA. Remove it from the currently
2632                         * scanned package so the previously user-installed
2633                         * application can be scanned.
2634                         */
2635                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2636                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2637                                    + ps.name + "; removing system app.  Last known codePath="
2638                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2639                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2640                                    + scannedPkg.mVersionCode);
2641                            removePackageLI(scannedPkg, true);
2642                            mExpectingBetter.put(ps.name, ps.codePath);
2643                        }
2644
2645                        continue;
2646                    }
2647
2648                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2649                        psit.remove();
2650                        logCriticalInfo(Log.WARN, "System package " + ps.name
2651                                + " no longer exists; it's data will be wiped");
2652                        // Actual deletion of code and data will be handled by later
2653                        // reconciliation step
2654                    } else {
2655                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2656                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2657                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2658                        }
2659                    }
2660                }
2661            }
2662
2663            //look for any incomplete package installations
2664            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2665            for (int i = 0; i < deletePkgsList.size(); i++) {
2666                // Actual deletion of code and data will be handled by later
2667                // reconciliation step
2668                final String packageName = deletePkgsList.get(i).name;
2669                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2670                synchronized (mPackages) {
2671                    mSettings.removePackageLPw(packageName);
2672                }
2673            }
2674
2675            //delete tmp files
2676            deleteTempPackageFiles();
2677
2678            // Remove any shared userIDs that have no associated packages
2679            mSettings.pruneSharedUsersLPw();
2680
2681            if (!mOnlyCore) {
2682                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2683                        SystemClock.uptimeMillis());
2684                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2685
2686                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2687                        | PackageParser.PARSE_FORWARD_LOCK,
2688                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2689
2690                /**
2691                 * Remove disable package settings for any updated system
2692                 * apps that were removed via an OTA. If they're not a
2693                 * previously-updated app, remove them completely.
2694                 * Otherwise, just revoke their system-level permissions.
2695                 */
2696                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2697                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2698                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2699
2700                    String msg;
2701                    if (deletedPkg == null) {
2702                        msg = "Updated system package " + deletedAppName
2703                                + " no longer exists; it's data will be wiped";
2704                        // Actual deletion of code and data will be handled by later
2705                        // reconciliation step
2706                    } else {
2707                        msg = "Updated system app + " + deletedAppName
2708                                + " no longer present; removing system privileges for "
2709                                + deletedAppName;
2710
2711                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2712
2713                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2714                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2715                    }
2716                    logCriticalInfo(Log.WARN, msg);
2717                }
2718
2719                /**
2720                 * Make sure all system apps that we expected to appear on
2721                 * the userdata partition actually showed up. If they never
2722                 * appeared, crawl back and revive the system version.
2723                 */
2724                for (int i = 0; i < mExpectingBetter.size(); i++) {
2725                    final String packageName = mExpectingBetter.keyAt(i);
2726                    if (!mPackages.containsKey(packageName)) {
2727                        final File scanFile = mExpectingBetter.valueAt(i);
2728
2729                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2730                                + " but never showed up; reverting to system");
2731
2732                        int reparseFlags = mDefParseFlags;
2733                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2734                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2735                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2736                                    | PackageParser.PARSE_IS_PRIVILEGED;
2737                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2738                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2739                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2740                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2741                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2742                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2743                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2744                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2745                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2746                        } else {
2747                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2748                            continue;
2749                        }
2750
2751                        mSettings.enableSystemPackageLPw(packageName);
2752
2753                        try {
2754                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2755                        } catch (PackageManagerException e) {
2756                            Slog.e(TAG, "Failed to parse original system package: "
2757                                    + e.getMessage());
2758                        }
2759                    }
2760                }
2761            }
2762            mExpectingBetter.clear();
2763
2764            // Resolve the storage manager.
2765            mStorageManagerPackage = getStorageManagerPackageName();
2766
2767            // Resolve protected action filters. Only the setup wizard is allowed to
2768            // have a high priority filter for these actions.
2769            mSetupWizardPackage = getSetupWizardPackageName();
2770            if (mProtectedFilters.size() > 0) {
2771                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2772                    Slog.i(TAG, "No setup wizard;"
2773                        + " All protected intents capped to priority 0");
2774                }
2775                for (ActivityIntentInfo filter : mProtectedFilters) {
2776                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2777                        if (DEBUG_FILTERS) {
2778                            Slog.i(TAG, "Found setup wizard;"
2779                                + " allow priority " + filter.getPriority() + ";"
2780                                + " package: " + filter.activity.info.packageName
2781                                + " activity: " + filter.activity.className
2782                                + " priority: " + filter.getPriority());
2783                        }
2784                        // skip setup wizard; allow it to keep the high priority filter
2785                        continue;
2786                    }
2787                    if (DEBUG_FILTERS) {
2788                        Slog.i(TAG, "Protected action; cap priority to 0;"
2789                                + " package: " + filter.activity.info.packageName
2790                                + " activity: " + filter.activity.className
2791                                + " origPrio: " + filter.getPriority());
2792                    }
2793                    filter.setPriority(0);
2794                }
2795            }
2796            mDeferProtectedFilters = false;
2797            mProtectedFilters.clear();
2798
2799            // Now that we know all of the shared libraries, update all clients to have
2800            // the correct library paths.
2801            updateAllSharedLibrariesLPw(null);
2802
2803            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2804                // NOTE: We ignore potential failures here during a system scan (like
2805                // the rest of the commands above) because there's precious little we
2806                // can do about it. A settings error is reported, though.
2807                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2808            }
2809
2810            // Now that we know all the packages we are keeping,
2811            // read and update their last usage times.
2812            mPackageUsage.read(mPackages);
2813            mCompilerStats.read();
2814
2815            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2816                    SystemClock.uptimeMillis());
2817            Slog.i(TAG, "Time to scan packages: "
2818                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2819                    + " seconds");
2820
2821            // If the platform SDK has changed since the last time we booted,
2822            // we need to re-grant app permission to catch any new ones that
2823            // appear.  This is really a hack, and means that apps can in some
2824            // cases get permissions that the user didn't initially explicitly
2825            // allow...  it would be nice to have some better way to handle
2826            // this situation.
2827            int updateFlags = UPDATE_PERMISSIONS_ALL;
2828            if (ver.sdkVersion != mSdkVersion) {
2829                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2830                        + mSdkVersion + "; regranting permissions for internal storage");
2831                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2832            }
2833            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2834            ver.sdkVersion = mSdkVersion;
2835
2836            // If this is the first boot or an update from pre-M, and it is a normal
2837            // boot, then we need to initialize the default preferred apps across
2838            // all defined users.
2839            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2840                for (UserInfo user : sUserManager.getUsers(true)) {
2841                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2842                    applyFactoryDefaultBrowserLPw(user.id);
2843                    primeDomainVerificationsLPw(user.id);
2844                }
2845            }
2846
2847            // Prepare storage for system user really early during boot,
2848            // since core system apps like SettingsProvider and SystemUI
2849            // can't wait for user to start
2850            final int storageFlags;
2851            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2852                storageFlags = StorageManager.FLAG_STORAGE_DE;
2853            } else {
2854                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2855            }
2856            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2857                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2858                    true /* onlyCoreApps */);
2859            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2860                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2861                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2862                traceLog.traceBegin("AppDataFixup");
2863                try {
2864                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2865                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2866                } catch (InstallerException e) {
2867                    Slog.w(TAG, "Trouble fixing GIDs", e);
2868                }
2869                traceLog.traceEnd();
2870
2871                traceLog.traceBegin("AppDataPrepare");
2872                if (deferPackages == null || deferPackages.isEmpty()) {
2873                    return;
2874                }
2875                int count = 0;
2876                for (String pkgName : deferPackages) {
2877                    PackageParser.Package pkg = null;
2878                    synchronized (mPackages) {
2879                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2880                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2881                            pkg = ps.pkg;
2882                        }
2883                    }
2884                    if (pkg != null) {
2885                        synchronized (mInstallLock) {
2886                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2887                                    true /* maybeMigrateAppData */);
2888                        }
2889                        count++;
2890                    }
2891                }
2892                traceLog.traceEnd();
2893                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2894            }, "prepareAppData");
2895
2896            // If this is first boot after an OTA, and a normal boot, then
2897            // we need to clear code cache directories.
2898            // Note that we do *not* clear the application profiles. These remain valid
2899            // across OTAs and are used to drive profile verification (post OTA) and
2900            // profile compilation (without waiting to collect a fresh set of profiles).
2901            if (mIsUpgrade && !onlyCore) {
2902                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2903                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2904                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2905                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2906                        // No apps are running this early, so no need to freeze
2907                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2908                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2909                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2910                    }
2911                }
2912                ver.fingerprint = Build.FINGERPRINT;
2913            }
2914
2915            checkDefaultBrowser();
2916
2917            // clear only after permissions and other defaults have been updated
2918            mExistingSystemPackages.clear();
2919            mPromoteSystemApps = false;
2920
2921            // All the changes are done during package scanning.
2922            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2923
2924            // can downgrade to reader
2925            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2926            mSettings.writeLPr();
2927            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2928
2929            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2930                    SystemClock.uptimeMillis());
2931
2932            if (!mOnlyCore) {
2933                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2934                mRequiredInstallerPackage = getRequiredInstallerLPr();
2935                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2936                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2937                if (mIntentFilterVerifierComponent != null) {
2938                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2939                            mIntentFilterVerifierComponent);
2940                } else {
2941                    mIntentFilterVerifier = null;
2942                }
2943                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2944                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2945                        SharedLibraryInfo.VERSION_UNDEFINED);
2946                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2947                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2948                        SharedLibraryInfo.VERSION_UNDEFINED);
2949            } else {
2950                mRequiredVerifierPackage = null;
2951                mRequiredInstallerPackage = null;
2952                mRequiredUninstallerPackage = null;
2953                mIntentFilterVerifierComponent = null;
2954                mIntentFilterVerifier = null;
2955                mServicesSystemSharedLibraryPackageName = null;
2956                mSharedSystemSharedLibraryPackageName = null;
2957            }
2958
2959            mInstallerService = new PackageInstallerService(context, this);
2960            final Pair<ComponentName, String> instantAppResolverComponent =
2961                    getInstantAppResolverLPr();
2962            if (instantAppResolverComponent != null) {
2963                if (DEBUG_EPHEMERAL) {
2964                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2965                }
2966                mInstantAppResolverConnection = new EphemeralResolverConnection(
2967                        mContext, instantAppResolverComponent.first,
2968                        instantAppResolverComponent.second);
2969                mInstantAppResolverSettingsComponent =
2970                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2971            } else {
2972                mInstantAppResolverConnection = null;
2973                mInstantAppResolverSettingsComponent = null;
2974            }
2975            updateInstantAppInstallerLocked(null);
2976
2977            // Read and update the usage of dex files.
2978            // Do this at the end of PM init so that all the packages have their
2979            // data directory reconciled.
2980            // At this point we know the code paths of the packages, so we can validate
2981            // the disk file and build the internal cache.
2982            // The usage file is expected to be small so loading and verifying it
2983            // should take a fairly small time compare to the other activities (e.g. package
2984            // scanning).
2985            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2986            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2987            for (int userId : currentUserIds) {
2988                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2989            }
2990            mDexManager.load(userPackages);
2991        } // synchronized (mPackages)
2992        } // synchronized (mInstallLock)
2993
2994        // Now after opening every single application zip, make sure they
2995        // are all flushed.  Not really needed, but keeps things nice and
2996        // tidy.
2997        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2998        Runtime.getRuntime().gc();
2999        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3000
3001        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3002        FallbackCategoryProvider.loadFallbacks();
3003        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3004
3005        // The initial scanning above does many calls into installd while
3006        // holding the mPackages lock, but we're mostly interested in yelling
3007        // once we have a booted system.
3008        mInstaller.setWarnIfHeld(mPackages);
3009
3010        // Expose private service for system components to use.
3011        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3012        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3013    }
3014
3015    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3016        // we're only interested in updating the installer appliction when 1) it's not
3017        // already set or 2) the modified package is the installer
3018        if (mInstantAppInstallerActivity != null
3019                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3020                        .equals(modifiedPackage)) {
3021            return;
3022        }
3023        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3024    }
3025
3026    private static File preparePackageParserCache(boolean isUpgrade) {
3027        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3028            return null;
3029        }
3030
3031        // Disable package parsing on eng builds to allow for faster incremental development.
3032        if ("eng".equals(Build.TYPE)) {
3033            return null;
3034        }
3035
3036        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3037            Slog.i(TAG, "Disabling package parser cache due to system property.");
3038            return null;
3039        }
3040
3041        // The base directory for the package parser cache lives under /data/system/.
3042        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3043                "package_cache");
3044        if (cacheBaseDir == null) {
3045            return null;
3046        }
3047
3048        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3049        // This also serves to "GC" unused entries when the package cache version changes (which
3050        // can only happen during upgrades).
3051        if (isUpgrade) {
3052            FileUtils.deleteContents(cacheBaseDir);
3053        }
3054
3055
3056        // Return the versioned package cache directory. This is something like
3057        // "/data/system/package_cache/1"
3058        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3059
3060        // The following is a workaround to aid development on non-numbered userdebug
3061        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3062        // the system partition is newer.
3063        //
3064        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3065        // that starts with "eng." to signify that this is an engineering build and not
3066        // destined for release.
3067        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3068            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3069
3070            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3071            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3072            // in general and should not be used for production changes. In this specific case,
3073            // we know that they will work.
3074            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3075            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3076                FileUtils.deleteContents(cacheBaseDir);
3077                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3078            }
3079        }
3080
3081        return cacheDir;
3082    }
3083
3084    @Override
3085    public boolean isFirstBoot() {
3086        // allow instant applications
3087        return mFirstBoot;
3088    }
3089
3090    @Override
3091    public boolean isOnlyCoreApps() {
3092        // allow instant applications
3093        return mOnlyCore;
3094    }
3095
3096    @Override
3097    public boolean isUpgrade() {
3098        // allow instant applications
3099        return mIsUpgrade;
3100    }
3101
3102    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3103        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3104
3105        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3106                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3107                UserHandle.USER_SYSTEM);
3108        if (matches.size() == 1) {
3109            return matches.get(0).getComponentInfo().packageName;
3110        } else if (matches.size() == 0) {
3111            Log.e(TAG, "There should probably be a verifier, but, none were found");
3112            return null;
3113        }
3114        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3115    }
3116
3117    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3118        synchronized (mPackages) {
3119            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3120            if (libraryEntry == null) {
3121                throw new IllegalStateException("Missing required shared library:" + name);
3122            }
3123            return libraryEntry.apk;
3124        }
3125    }
3126
3127    private @NonNull String getRequiredInstallerLPr() {
3128        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3129        intent.addCategory(Intent.CATEGORY_DEFAULT);
3130        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3131
3132        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3133                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3134                UserHandle.USER_SYSTEM);
3135        if (matches.size() == 1) {
3136            ResolveInfo resolveInfo = matches.get(0);
3137            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3138                throw new RuntimeException("The installer must be a privileged app");
3139            }
3140            return matches.get(0).getComponentInfo().packageName;
3141        } else {
3142            throw new RuntimeException("There must be exactly one installer; found " + matches);
3143        }
3144    }
3145
3146    private @NonNull String getRequiredUninstallerLPr() {
3147        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3148        intent.addCategory(Intent.CATEGORY_DEFAULT);
3149        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3150
3151        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3152                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3153                UserHandle.USER_SYSTEM);
3154        if (resolveInfo == null ||
3155                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3156            throw new RuntimeException("There must be exactly one uninstaller; found "
3157                    + resolveInfo);
3158        }
3159        return resolveInfo.getComponentInfo().packageName;
3160    }
3161
3162    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3163        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3164
3165        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3166                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3167                UserHandle.USER_SYSTEM);
3168        ResolveInfo best = null;
3169        final int N = matches.size();
3170        for (int i = 0; i < N; i++) {
3171            final ResolveInfo cur = matches.get(i);
3172            final String packageName = cur.getComponentInfo().packageName;
3173            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3174                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3175                continue;
3176            }
3177
3178            if (best == null || cur.priority > best.priority) {
3179                best = cur;
3180            }
3181        }
3182
3183        if (best != null) {
3184            return best.getComponentInfo().getComponentName();
3185        }
3186        Slog.w(TAG, "Intent filter verifier not found");
3187        return null;
3188    }
3189
3190    @Override
3191    public @Nullable ComponentName getInstantAppResolverComponent() {
3192        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3193            return null;
3194        }
3195        synchronized (mPackages) {
3196            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3197            if (instantAppResolver == null) {
3198                return null;
3199            }
3200            return instantAppResolver.first;
3201        }
3202    }
3203
3204    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3205        final String[] packageArray =
3206                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3207        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3208            if (DEBUG_EPHEMERAL) {
3209                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3210            }
3211            return null;
3212        }
3213
3214        final int callingUid = Binder.getCallingUid();
3215        final int resolveFlags =
3216                MATCH_DIRECT_BOOT_AWARE
3217                | MATCH_DIRECT_BOOT_UNAWARE
3218                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3219        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3220        final Intent resolverIntent = new Intent(actionName);
3221        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3222                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3223        // temporarily look for the old action
3224        if (resolvers.size() == 0) {
3225            if (DEBUG_EPHEMERAL) {
3226                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3227            }
3228            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3229            resolverIntent.setAction(actionName);
3230            resolvers = queryIntentServicesInternal(resolverIntent, null,
3231                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3232        }
3233        final int N = resolvers.size();
3234        if (N == 0) {
3235            if (DEBUG_EPHEMERAL) {
3236                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3237            }
3238            return null;
3239        }
3240
3241        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3242        for (int i = 0; i < N; i++) {
3243            final ResolveInfo info = resolvers.get(i);
3244
3245            if (info.serviceInfo == null) {
3246                continue;
3247            }
3248
3249            final String packageName = info.serviceInfo.packageName;
3250            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3251                if (DEBUG_EPHEMERAL) {
3252                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3253                            + " pkg: " + packageName + ", info:" + info);
3254                }
3255                continue;
3256            }
3257
3258            if (DEBUG_EPHEMERAL) {
3259                Slog.v(TAG, "Ephemeral resolver found;"
3260                        + " pkg: " + packageName + ", info:" + info);
3261            }
3262            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3263        }
3264        if (DEBUG_EPHEMERAL) {
3265            Slog.v(TAG, "Ephemeral resolver NOT found");
3266        }
3267        return null;
3268    }
3269
3270    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3271        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3272        intent.addCategory(Intent.CATEGORY_DEFAULT);
3273        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3274
3275        final int resolveFlags =
3276                MATCH_DIRECT_BOOT_AWARE
3277                | MATCH_DIRECT_BOOT_UNAWARE
3278                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3279        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3280                resolveFlags, UserHandle.USER_SYSTEM);
3281        // temporarily look for the old action
3282        if (matches.isEmpty()) {
3283            if (DEBUG_EPHEMERAL) {
3284                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3285            }
3286            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3287            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3288                    resolveFlags, UserHandle.USER_SYSTEM);
3289        }
3290        Iterator<ResolveInfo> iter = matches.iterator();
3291        while (iter.hasNext()) {
3292            final ResolveInfo rInfo = iter.next();
3293            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3294            if (ps != null) {
3295                final PermissionsState permissionsState = ps.getPermissionsState();
3296                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3297                    continue;
3298                }
3299            }
3300            iter.remove();
3301        }
3302        if (matches.size() == 0) {
3303            return null;
3304        } else if (matches.size() == 1) {
3305            return (ActivityInfo) matches.get(0).getComponentInfo();
3306        } else {
3307            throw new RuntimeException(
3308                    "There must be at most one ephemeral installer; found " + matches);
3309        }
3310    }
3311
3312    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3313            @NonNull ComponentName resolver) {
3314        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3315                .addCategory(Intent.CATEGORY_DEFAULT)
3316                .setPackage(resolver.getPackageName());
3317        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3318        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3319                UserHandle.USER_SYSTEM);
3320        // temporarily look for the old action
3321        if (matches.isEmpty()) {
3322            if (DEBUG_EPHEMERAL) {
3323                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3324            }
3325            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3326            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3327                    UserHandle.USER_SYSTEM);
3328        }
3329        if (matches.isEmpty()) {
3330            return null;
3331        }
3332        return matches.get(0).getComponentInfo().getComponentName();
3333    }
3334
3335    private void primeDomainVerificationsLPw(int userId) {
3336        if (DEBUG_DOMAIN_VERIFICATION) {
3337            Slog.d(TAG, "Priming domain verifications in user " + userId);
3338        }
3339
3340        SystemConfig systemConfig = SystemConfig.getInstance();
3341        ArraySet<String> packages = systemConfig.getLinkedApps();
3342
3343        for (String packageName : packages) {
3344            PackageParser.Package pkg = mPackages.get(packageName);
3345            if (pkg != null) {
3346                if (!pkg.isSystemApp()) {
3347                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3348                    continue;
3349                }
3350
3351                ArraySet<String> domains = null;
3352                for (PackageParser.Activity a : pkg.activities) {
3353                    for (ActivityIntentInfo filter : a.intents) {
3354                        if (hasValidDomains(filter)) {
3355                            if (domains == null) {
3356                                domains = new ArraySet<String>();
3357                            }
3358                            domains.addAll(filter.getHostsList());
3359                        }
3360                    }
3361                }
3362
3363                if (domains != null && domains.size() > 0) {
3364                    if (DEBUG_DOMAIN_VERIFICATION) {
3365                        Slog.v(TAG, "      + " + packageName);
3366                    }
3367                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3368                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3369                    // and then 'always' in the per-user state actually used for intent resolution.
3370                    final IntentFilterVerificationInfo ivi;
3371                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3372                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3373                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3374                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3375                } else {
3376                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3377                            + "' does not handle web links");
3378                }
3379            } else {
3380                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3381            }
3382        }
3383
3384        scheduleWritePackageRestrictionsLocked(userId);
3385        scheduleWriteSettingsLocked();
3386    }
3387
3388    private void applyFactoryDefaultBrowserLPw(int userId) {
3389        // The default browser app's package name is stored in a string resource,
3390        // with a product-specific overlay used for vendor customization.
3391        String browserPkg = mContext.getResources().getString(
3392                com.android.internal.R.string.default_browser);
3393        if (!TextUtils.isEmpty(browserPkg)) {
3394            // non-empty string => required to be a known package
3395            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3396            if (ps == null) {
3397                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3398                browserPkg = null;
3399            } else {
3400                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3401            }
3402        }
3403
3404        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3405        // default.  If there's more than one, just leave everything alone.
3406        if (browserPkg == null) {
3407            calculateDefaultBrowserLPw(userId);
3408        }
3409    }
3410
3411    private void calculateDefaultBrowserLPw(int userId) {
3412        List<String> allBrowsers = resolveAllBrowserApps(userId);
3413        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3414        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3415    }
3416
3417    private List<String> resolveAllBrowserApps(int userId) {
3418        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3419        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3420                PackageManager.MATCH_ALL, userId);
3421
3422        final int count = list.size();
3423        List<String> result = new ArrayList<String>(count);
3424        for (int i=0; i<count; i++) {
3425            ResolveInfo info = list.get(i);
3426            if (info.activityInfo == null
3427                    || !info.handleAllWebDataURI
3428                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3429                    || result.contains(info.activityInfo.packageName)) {
3430                continue;
3431            }
3432            result.add(info.activityInfo.packageName);
3433        }
3434
3435        return result;
3436    }
3437
3438    private boolean packageIsBrowser(String packageName, int userId) {
3439        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3440                PackageManager.MATCH_ALL, userId);
3441        final int N = list.size();
3442        for (int i = 0; i < N; i++) {
3443            ResolveInfo info = list.get(i);
3444            if (packageName.equals(info.activityInfo.packageName)) {
3445                return true;
3446            }
3447        }
3448        return false;
3449    }
3450
3451    private void checkDefaultBrowser() {
3452        final int myUserId = UserHandle.myUserId();
3453        final String packageName = getDefaultBrowserPackageName(myUserId);
3454        if (packageName != null) {
3455            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3456            if (info == null) {
3457                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3458                synchronized (mPackages) {
3459                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3460                }
3461            }
3462        }
3463    }
3464
3465    @Override
3466    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3467            throws RemoteException {
3468        try {
3469            return super.onTransact(code, data, reply, flags);
3470        } catch (RuntimeException e) {
3471            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3472                Slog.wtf(TAG, "Package Manager Crash", e);
3473            }
3474            throw e;
3475        }
3476    }
3477
3478    static int[] appendInts(int[] cur, int[] add) {
3479        if (add == null) return cur;
3480        if (cur == null) return add;
3481        final int N = add.length;
3482        for (int i=0; i<N; i++) {
3483            cur = appendInt(cur, add[i]);
3484        }
3485        return cur;
3486    }
3487
3488    /**
3489     * Returns whether or not a full application can see an instant application.
3490     * <p>
3491     * Currently, there are three cases in which this can occur:
3492     * <ol>
3493     * <li>The calling application is a "special" process. The special
3494     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3495     *     and {@code 0}</li>
3496     * <li>The calling application has the permission
3497     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3498     * <li>[TODO] The calling application is the default launcher on the
3499     *     system partition.</li>
3500     * </ol>
3501     */
3502    private boolean canAccessInstantApps(int callingUid) {
3503        final boolean isSpecialProcess =
3504                callingUid == Process.SYSTEM_UID
3505                        || callingUid == Process.SHELL_UID
3506                        || callingUid == 0;
3507        final boolean allowMatchInstant =
3508                isSpecialProcess
3509                        || mContext.checkCallingOrSelfPermission(
3510                        android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
3511        return allowMatchInstant;
3512    }
3513    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3514        if (!sUserManager.exists(userId)) return null;
3515        if (ps == null) {
3516            return null;
3517        }
3518        PackageParser.Package p = ps.pkg;
3519        if (p == null) {
3520            return null;
3521        }
3522        final int callingUid =  Binder.getCallingUid();
3523        // Filter out ephemeral app metadata:
3524        //   * The system/shell/root can see metadata for any app
3525        //   * An installed app can see metadata for 1) other installed apps
3526        //     and 2) ephemeral apps that have explicitly interacted with it
3527        //   * Ephemeral apps can only see their own data and exposed installed apps
3528        //   * Holding a signature permission allows seeing instant apps
3529        if (!canAccessInstantApps(callingUid)) {
3530            final String instantAppPackageName = getInstantAppPackageName(callingUid);
3531            if (instantAppPackageName != null) {
3532                // ephemeral apps can only get information on themselves or
3533                // installed apps that are exposed.
3534                if (!instantAppPackageName.equals(p.packageName)
3535                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3536                    return null;
3537                }
3538            } else {
3539                if (ps.getInstantApp(userId)) {
3540                    // only get access to the ephemeral app if we've been granted access
3541                    final int callingAppId = UserHandle.getAppId(callingUid);
3542                    if (!mInstantAppRegistry.isInstantAccessGranted(
3543                            userId, callingAppId, ps.appId)) {
3544                        return null;
3545                    }
3546                }
3547            }
3548        }
3549
3550        final PermissionsState permissionsState = ps.getPermissionsState();
3551
3552        // Compute GIDs only if requested
3553        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3554                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3555        // Compute granted permissions only if package has requested permissions
3556        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3557                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3558        final PackageUserState state = ps.readUserState(userId);
3559
3560        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3561                && ps.isSystem()) {
3562            flags |= MATCH_ANY_USER;
3563        }
3564
3565        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3566                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3567
3568        if (packageInfo == null) {
3569            return null;
3570        }
3571
3572        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3573
3574        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3575                resolveExternalPackageNameLPr(p);
3576
3577        return packageInfo;
3578    }
3579
3580    @Override
3581    public void checkPackageStartable(String packageName, int userId) {
3582        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3583            throw new SecurityException("Instant applications don't have access to this method");
3584        }
3585        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3586        synchronized (mPackages) {
3587            final PackageSetting ps = mSettings.mPackages.get(packageName);
3588            if (ps == null) {
3589                throw new SecurityException("Package " + packageName + " was not found!");
3590            }
3591
3592            if (!ps.getInstalled(userId)) {
3593                throw new SecurityException(
3594                        "Package " + packageName + " was not installed for user " + userId + "!");
3595            }
3596
3597            if (mSafeMode && !ps.isSystem()) {
3598                throw new SecurityException("Package " + packageName + " not a system app!");
3599            }
3600
3601            if (mFrozenPackages.contains(packageName)) {
3602                throw new SecurityException("Package " + packageName + " is currently frozen!");
3603            }
3604
3605            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3606                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3607                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3608            }
3609        }
3610    }
3611
3612    @Override
3613    public boolean isPackageAvailable(String packageName, int userId) {
3614        if (!sUserManager.exists(userId)) return false;
3615        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3616                false /* requireFullPermission */, false /* checkShell */, "is package available");
3617        synchronized (mPackages) {
3618            PackageParser.Package p = mPackages.get(packageName);
3619            if (p != null) {
3620                final PackageSetting ps = (PackageSetting) p.mExtras;
3621                if (ps != null) {
3622                    final PackageUserState state = ps.readUserState(userId);
3623                    if (state != null) {
3624                        return PackageParser.isAvailable(state);
3625                    }
3626                }
3627            }
3628        }
3629        return false;
3630    }
3631
3632    @Override
3633    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3634        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3635                flags, userId);
3636    }
3637
3638    @Override
3639    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3640            int flags, int userId) {
3641        return getPackageInfoInternal(versionedPackage.getPackageName(),
3642                versionedPackage.getVersionCode(), flags, userId);
3643    }
3644
3645    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3646            int flags, int userId) {
3647        if (!sUserManager.exists(userId)) return null;
3648        final int callingUid = Binder.getCallingUid();
3649        flags = updateFlagsForPackage(flags, userId, packageName);
3650        enforceCrossUserPermission(callingUid, userId,
3651                false /* requireFullPermission */, false /* checkShell */, "get package info");
3652
3653        // reader
3654        synchronized (mPackages) {
3655            // Normalize package name to handle renamed packages and static libs
3656            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3657
3658            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3659            if (matchFactoryOnly) {
3660                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3661                if (ps != null) {
3662                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3663                        return null;
3664                    }
3665                    if (filterAppAccessLPr(ps, callingUid, userId)) {
3666                        return null;
3667                    }
3668                    return generatePackageInfo(ps, flags, userId);
3669                }
3670            }
3671
3672            PackageParser.Package p = mPackages.get(packageName);
3673            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3674                return null;
3675            }
3676            if (DEBUG_PACKAGE_INFO)
3677                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3678            if (p != null) {
3679                final PackageSetting ps = (PackageSetting) p.mExtras;
3680                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3681                    return null;
3682                }
3683                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
3684                    return null;
3685                }
3686                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3687            }
3688            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3689                final PackageSetting ps = mSettings.mPackages.get(packageName);
3690                if (ps == null) return null;
3691                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3692                    return null;
3693                }
3694                if (filterAppAccessLPr(ps, callingUid, userId)) {
3695                    return null;
3696                }
3697                return generatePackageInfo(ps, flags, userId);
3698            }
3699        }
3700        return null;
3701    }
3702
3703    /**
3704     * Returns whether or not access to the application should be filtered.
3705     * <p>
3706     * Access may be limited based upon whether the calling or target applications
3707     * are instant applications.
3708     *
3709     * @see #canAccessInstantApps(int)
3710     */
3711    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid,
3712            @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) {
3713        // if we're in an isolated process, get the real calling UID
3714        if (Process.isIsolated(callingUid)) {
3715            callingUid = mIsolatedOwners.get(callingUid);
3716        }
3717        // if the target and caller are the same application, don't filter
3718        if (isCallerSameApp(ps.name, callingUid)) {
3719            return false;
3720        }
3721        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3722        final boolean callerIsInstantApp = instantAppPkgName != null;
3723        if (callerIsInstantApp) {
3724            // request for a specific component; if it hasn't been explicitly exposed, filter
3725            if (component != null) {
3726                return !componentVisibleToInstantApp;
3727            }
3728            // request for application; if no components have been explicitly exposed, filter
3729            return !ps.pkg.visibleToInstantApps;
3730        }
3731        if (ps.getInstantApp(userId)) {
3732            // caller can see all components of all instant applications, don't filter
3733            if (canAccessInstantApps(callingUid)) {
3734                return false;
3735            }
3736            // request for a specific instant application component, filter
3737            if (component != null) {
3738                return true;
3739            }
3740            // request for an instant application; if the caller hasn't been granted access, filter
3741            return !mInstantAppRegistry.isInstantAccessGranted(
3742                    userId, UserHandle.getAppId(callingUid), ps.appId);
3743        }
3744        return false;
3745    }
3746
3747    /**
3748     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
3749     */
3750    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid, int userId) {
3751        return filterAppAccessLPr(ps, callingUid, null, false, userId);
3752    }
3753
3754    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
3755            int flags) {
3756        // Callers can access only the libs they depend on, otherwise they need to explicitly
3757        // ask for the shared libraries given the caller is allowed to access all static libs.
3758        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3759            // System/shell/root get to see all static libs
3760            final int appId = UserHandle.getAppId(uid);
3761            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3762                    || appId == Process.ROOT_UID) {
3763                return false;
3764            }
3765        }
3766
3767        // No package means no static lib as it is always on internal storage
3768        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3769            return false;
3770        }
3771
3772        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3773                ps.pkg.staticSharedLibVersion);
3774        if (libEntry == null) {
3775            return false;
3776        }
3777
3778        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3779        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3780        if (uidPackageNames == null) {
3781            return true;
3782        }
3783
3784        for (String uidPackageName : uidPackageNames) {
3785            if (ps.name.equals(uidPackageName)) {
3786                return false;
3787            }
3788            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3789            if (uidPs != null) {
3790                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3791                        libEntry.info.getName());
3792                if (index < 0) {
3793                    continue;
3794                }
3795                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3796                    return false;
3797                }
3798            }
3799        }
3800        return true;
3801    }
3802
3803    @Override
3804    public String[] currentToCanonicalPackageNames(String[] names) {
3805        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3806            return names;
3807        }
3808        String[] out = new String[names.length];
3809        // reader
3810        synchronized (mPackages) {
3811            for (int i=names.length-1; i>=0; i--) {
3812                PackageSetting ps = mSettings.mPackages.get(names[i]);
3813                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3814            }
3815        }
3816        return out;
3817    }
3818
3819    @Override
3820    public String[] canonicalToCurrentPackageNames(String[] names) {
3821        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3822            return names;
3823        }
3824        String[] out = new String[names.length];
3825        // reader
3826        synchronized (mPackages) {
3827            for (int i=names.length-1; i>=0; i--) {
3828                String cur = mSettings.getRenamedPackageLPr(names[i]);
3829                out[i] = cur != null ? cur : names[i];
3830            }
3831        }
3832        return out;
3833    }
3834
3835    @Override
3836    public int getPackageUid(String packageName, int flags, int userId) {
3837        if (!sUserManager.exists(userId)) return -1;
3838        flags = updateFlagsForPackage(flags, userId, packageName);
3839        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3840                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3841
3842        // reader
3843        synchronized (mPackages) {
3844            final PackageParser.Package p = mPackages.get(packageName);
3845            if (p != null && p.isMatch(flags)) {
3846                return UserHandle.getUid(userId, p.applicationInfo.uid);
3847            }
3848            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3849                final PackageSetting ps = mSettings.mPackages.get(packageName);
3850                if (ps != null && ps.isMatch(flags)) {
3851                    return UserHandle.getUid(userId, ps.appId);
3852                }
3853            }
3854        }
3855
3856        return -1;
3857    }
3858
3859    @Override
3860    public int[] getPackageGids(String packageName, int flags, int userId) {
3861        if (!sUserManager.exists(userId)) return null;
3862        flags = updateFlagsForPackage(flags, userId, packageName);
3863        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3864                false /* requireFullPermission */, false /* checkShell */,
3865                "getPackageGids");
3866
3867        // reader
3868        synchronized (mPackages) {
3869            final PackageParser.Package p = mPackages.get(packageName);
3870            if (p != null && p.isMatch(flags)) {
3871                PackageSetting ps = (PackageSetting) p.mExtras;
3872                // TODO: Shouldn't this be checking for package installed state for userId and
3873                // return null?
3874                return ps.getPermissionsState().computeGids(userId);
3875            }
3876            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3877                final PackageSetting ps = mSettings.mPackages.get(packageName);
3878                if (ps != null && ps.isMatch(flags)) {
3879                    return ps.getPermissionsState().computeGids(userId);
3880                }
3881            }
3882        }
3883
3884        return null;
3885    }
3886
3887    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3888        if (bp.perm != null) {
3889            return PackageParser.generatePermissionInfo(bp.perm, flags);
3890        }
3891        PermissionInfo pi = new PermissionInfo();
3892        pi.name = bp.name;
3893        pi.packageName = bp.sourcePackage;
3894        pi.nonLocalizedLabel = bp.name;
3895        pi.protectionLevel = bp.protectionLevel;
3896        return pi;
3897    }
3898
3899    @Override
3900    public PermissionInfo getPermissionInfo(String name, int flags) {
3901        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3902            return null;
3903        }
3904        // reader
3905        synchronized (mPackages) {
3906            final BasePermission p = mSettings.mPermissions.get(name);
3907            if (p != null) {
3908                return generatePermissionInfo(p, flags);
3909            }
3910            return null;
3911        }
3912    }
3913
3914    @Override
3915    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3916            int flags) {
3917        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3918            return null;
3919        }
3920        // reader
3921        synchronized (mPackages) {
3922            if (group != null && !mPermissionGroups.containsKey(group)) {
3923                // This is thrown as NameNotFoundException
3924                return null;
3925            }
3926
3927            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3928            for (BasePermission p : mSettings.mPermissions.values()) {
3929                if (group == null) {
3930                    if (p.perm == null || p.perm.info.group == null) {
3931                        out.add(generatePermissionInfo(p, flags));
3932                    }
3933                } else {
3934                    if (p.perm != null && group.equals(p.perm.info.group)) {
3935                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3936                    }
3937                }
3938            }
3939            return new ParceledListSlice<>(out);
3940        }
3941    }
3942
3943    @Override
3944    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3945        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3946            return null;
3947        }
3948        // reader
3949        synchronized (mPackages) {
3950            return PackageParser.generatePermissionGroupInfo(
3951                    mPermissionGroups.get(name), flags);
3952        }
3953    }
3954
3955    @Override
3956    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3957        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3958            return ParceledListSlice.emptyList();
3959        }
3960        // reader
3961        synchronized (mPackages) {
3962            final int N = mPermissionGroups.size();
3963            ArrayList<PermissionGroupInfo> out
3964                    = new ArrayList<PermissionGroupInfo>(N);
3965            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3966                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3967            }
3968            return new ParceledListSlice<>(out);
3969        }
3970    }
3971
3972    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3973            int uid, int userId) {
3974        if (!sUserManager.exists(userId)) return null;
3975        PackageSetting ps = mSettings.mPackages.get(packageName);
3976        if (ps != null) {
3977            if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
3978                return null;
3979            }
3980            if (filterAppAccessLPr(ps, uid, userId)) {
3981                return null;
3982            }
3983            if (ps.pkg == null) {
3984                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3985                if (pInfo != null) {
3986                    return pInfo.applicationInfo;
3987                }
3988                return null;
3989            }
3990            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3991                    ps.readUserState(userId), userId);
3992            if (ai != null) {
3993                rebaseEnabledOverlays(ai, userId);
3994                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3995            }
3996            return ai;
3997        }
3998        return null;
3999    }
4000
4001    @Override
4002    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4003        if (!sUserManager.exists(userId)) return null;
4004        flags = updateFlagsForApplication(flags, userId, packageName);
4005        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4006                false /* requireFullPermission */, false /* checkShell */, "get application info");
4007
4008        // writer
4009        synchronized (mPackages) {
4010            // Normalize package name to handle renamed packages and static libs
4011            packageName = resolveInternalPackageNameLPr(packageName,
4012                    PackageManager.VERSION_CODE_HIGHEST);
4013
4014            PackageParser.Package p = mPackages.get(packageName);
4015            if (DEBUG_PACKAGE_INFO) Log.v(
4016                    TAG, "getApplicationInfo " + packageName
4017                    + ": " + p);
4018            if (p != null) {
4019                PackageSetting ps = mSettings.mPackages.get(packageName);
4020                if (ps == null) return null;
4021                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
4022                    return null;
4023                }
4024                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
4025                    return null;
4026                }
4027                // Note: isEnabledLP() does not apply here - always return info
4028                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4029                        p, flags, ps.readUserState(userId), userId);
4030                if (ai != null) {
4031                    rebaseEnabledOverlays(ai, userId);
4032                    ai.packageName = resolveExternalPackageNameLPr(p);
4033                }
4034                return ai;
4035            }
4036            if ("android".equals(packageName)||"system".equals(packageName)) {
4037                return mAndroidApplication;
4038            }
4039            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4040                // Already generates the external package name
4041                return generateApplicationInfoFromSettingsLPw(packageName,
4042                        Binder.getCallingUid(), flags, userId);
4043            }
4044        }
4045        return null;
4046    }
4047
4048    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
4049        List<String> paths = new ArrayList<>();
4050        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
4051            mEnabledOverlayPaths.get(userId);
4052        if (userSpecificOverlays != null) {
4053            if (!"android".equals(ai.packageName)) {
4054                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
4055                if (frameworkOverlays != null) {
4056                    paths.addAll(frameworkOverlays);
4057                }
4058            }
4059
4060            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
4061            if (appOverlays != null) {
4062                paths.addAll(appOverlays);
4063            }
4064        }
4065        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
4066    }
4067
4068    private String normalizePackageNameLPr(String packageName) {
4069        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4070        return normalizedPackageName != null ? normalizedPackageName : packageName;
4071    }
4072
4073    @Override
4074    public void deletePreloadsFileCache() {
4075        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4076            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4077        }
4078        File dir = Environment.getDataPreloadsFileCacheDirectory();
4079        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4080        FileUtils.deleteContents(dir);
4081    }
4082
4083    @Override
4084    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4085            final IPackageDataObserver observer) {
4086        mContext.enforceCallingOrSelfPermission(
4087                android.Manifest.permission.CLEAR_APP_CACHE, null);
4088        mHandler.post(() -> {
4089            boolean success = false;
4090            try {
4091                freeStorage(volumeUuid, freeStorageSize, 0);
4092                success = true;
4093            } catch (IOException e) {
4094                Slog.w(TAG, e);
4095            }
4096            if (observer != null) {
4097                try {
4098                    observer.onRemoveCompleted(null, success);
4099                } catch (RemoteException e) {
4100                    Slog.w(TAG, e);
4101                }
4102            }
4103        });
4104    }
4105
4106    @Override
4107    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4108            final IntentSender pi) {
4109        mContext.enforceCallingOrSelfPermission(
4110                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4111        mHandler.post(() -> {
4112            boolean success = false;
4113            try {
4114                freeStorage(volumeUuid, freeStorageSize, 0);
4115                success = true;
4116            } catch (IOException e) {
4117                Slog.w(TAG, e);
4118            }
4119            if (pi != null) {
4120                try {
4121                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4122                } catch (SendIntentException e) {
4123                    Slog.w(TAG, e);
4124                }
4125            }
4126        });
4127    }
4128
4129    /**
4130     * Blocking call to clear various types of cached data across the system
4131     * until the requested bytes are available.
4132     */
4133    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4134        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4135        final File file = storage.findPathForUuid(volumeUuid);
4136        if (file.getUsableSpace() >= bytes) return;
4137
4138        if (ENABLE_FREE_CACHE_V2) {
4139            final boolean aggressive = (storageFlags
4140                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4141            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4142                    volumeUuid);
4143
4144            // 1. Pre-flight to determine if we have any chance to succeed
4145            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4146            if (internalVolume && (aggressive || SystemProperties
4147                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4148                deletePreloadsFileCache();
4149                if (file.getUsableSpace() >= bytes) return;
4150            }
4151
4152            // 3. Consider parsed APK data (aggressive only)
4153            if (internalVolume && aggressive) {
4154                FileUtils.deleteContents(mCacheDir);
4155                if (file.getUsableSpace() >= bytes) return;
4156            }
4157
4158            // 4. Consider cached app data (above quotas)
4159            try {
4160                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
4161            } catch (InstallerException ignored) {
4162            }
4163            if (file.getUsableSpace() >= bytes) return;
4164
4165            // 5. Consider shared libraries with refcount=0 and age>2h
4166            // 6. Consider dexopt output (aggressive only)
4167            // 7. Consider ephemeral apps not used in last week
4168
4169            // 8. Consider cached app data (below quotas)
4170            try {
4171                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
4172                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4173            } catch (InstallerException ignored) {
4174            }
4175            if (file.getUsableSpace() >= bytes) return;
4176
4177            // 9. Consider DropBox entries
4178            // 10. Consider ephemeral cookies
4179
4180        } else {
4181            try {
4182                mInstaller.freeCache(volumeUuid, bytes, 0);
4183            } catch (InstallerException ignored) {
4184            }
4185            if (file.getUsableSpace() >= bytes) return;
4186        }
4187
4188        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4189    }
4190
4191    /**
4192     * Update given flags based on encryption status of current user.
4193     */
4194    private int updateFlags(int flags, int userId) {
4195        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4196                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4197            // Caller expressed an explicit opinion about what encryption
4198            // aware/unaware components they want to see, so fall through and
4199            // give them what they want
4200        } else {
4201            // Caller expressed no opinion, so match based on user state
4202            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4203                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4204            } else {
4205                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4206            }
4207        }
4208        return flags;
4209    }
4210
4211    private UserManagerInternal getUserManagerInternal() {
4212        if (mUserManagerInternal == null) {
4213            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4214        }
4215        return mUserManagerInternal;
4216    }
4217
4218    private DeviceIdleController.LocalService getDeviceIdleController() {
4219        if (mDeviceIdleController == null) {
4220            mDeviceIdleController =
4221                    LocalServices.getService(DeviceIdleController.LocalService.class);
4222        }
4223        return mDeviceIdleController;
4224    }
4225
4226    /**
4227     * Update given flags when being used to request {@link PackageInfo}.
4228     */
4229    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4230        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4231        boolean triaged = true;
4232        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4233                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4234            // Caller is asking for component details, so they'd better be
4235            // asking for specific encryption matching behavior, or be triaged
4236            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4237                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4238                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4239                triaged = false;
4240            }
4241        }
4242        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4243                | PackageManager.MATCH_SYSTEM_ONLY
4244                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4245            triaged = false;
4246        }
4247        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4248            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4249                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4250                    + Debug.getCallers(5));
4251        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4252                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4253            // If the caller wants all packages and has a restricted profile associated with it,
4254            // then match all users. This is to make sure that launchers that need to access work
4255            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4256            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4257            flags |= PackageManager.MATCH_ANY_USER;
4258        }
4259        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4260            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4261                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4262        }
4263        return updateFlags(flags, userId);
4264    }
4265
4266    /**
4267     * Update given flags when being used to request {@link ApplicationInfo}.
4268     */
4269    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4270        return updateFlagsForPackage(flags, userId, cookie);
4271    }
4272
4273    /**
4274     * Update given flags when being used to request {@link ComponentInfo}.
4275     */
4276    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4277        if (cookie instanceof Intent) {
4278            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4279                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4280            }
4281        }
4282
4283        boolean triaged = true;
4284        // Caller is asking for component details, so they'd better be
4285        // asking for specific encryption matching behavior, or be triaged
4286        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4287                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4288                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4289            triaged = false;
4290        }
4291        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4292            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4293                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4294        }
4295
4296        return updateFlags(flags, userId);
4297    }
4298
4299    /**
4300     * Update given intent when being used to request {@link ResolveInfo}.
4301     */
4302    private Intent updateIntentForResolve(Intent intent) {
4303        if (intent.getSelector() != null) {
4304            intent = intent.getSelector();
4305        }
4306        if (DEBUG_PREFERRED) {
4307            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4308        }
4309        return intent;
4310    }
4311
4312    /**
4313     * Update given flags when being used to request {@link ResolveInfo}.
4314     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4315     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4316     * flag set. However, this flag is only honoured in three circumstances:
4317     * <ul>
4318     * <li>when called from a system process</li>
4319     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4320     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4321     * action and a {@code android.intent.category.BROWSABLE} category</li>
4322     * </ul>
4323     */
4324    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4325        return updateFlagsForResolve(flags, userId, intent, callingUid,
4326                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4327    }
4328    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4329            boolean wantInstantApps) {
4330        return updateFlagsForResolve(flags, userId, intent, callingUid,
4331                wantInstantApps, false /*onlyExposedExplicitly*/);
4332    }
4333    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4334            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4335        // Safe mode means we shouldn't match any third-party components
4336        if (mSafeMode) {
4337            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4338        }
4339        if (getInstantAppPackageName(callingUid) != null) {
4340            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4341            if (onlyExposedExplicitly) {
4342                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4343            }
4344            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4345            flags |= PackageManager.MATCH_INSTANT;
4346        } else {
4347            final boolean allowMatchInstant =
4348                    (wantInstantApps
4349                            && Intent.ACTION_VIEW.equals(intent.getAction())
4350                            && hasWebURI(intent))
4351                    || canAccessInstantApps(callingUid);
4352            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4353                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4354            if (!allowMatchInstant) {
4355                flags &= ~PackageManager.MATCH_INSTANT;
4356            }
4357        }
4358        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4359    }
4360
4361    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4362            int userId) {
4363        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4364        if (ret != null) {
4365            rebaseEnabledOverlays(ret.applicationInfo, userId);
4366        }
4367        return ret;
4368    }
4369
4370    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4371            PackageUserState state, int userId) {
4372        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4373        if (ai != null) {
4374            rebaseEnabledOverlays(ai.applicationInfo, userId);
4375        }
4376        return ai;
4377    }
4378
4379    @Override
4380    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4381        if (!sUserManager.exists(userId)) return null;
4382        final int callingUid = Binder.getCallingUid();
4383        flags = updateFlagsForComponent(flags, userId, component);
4384        enforceCrossUserPermission(callingUid, userId,
4385                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4386        synchronized (mPackages) {
4387            PackageParser.Activity a = mActivities.mActivities.get(component);
4388
4389            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4390            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4391                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4392                if (ps == null) return null;
4393                final boolean visibleToInstantApp =
4394                        (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4395                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4396                    return null;
4397                }
4398                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4399            }
4400            if (mResolveComponentName.equals(component)) {
4401                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4402                        userId);
4403            }
4404        }
4405        return null;
4406    }
4407
4408    @Override
4409    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4410            String resolvedType) {
4411        synchronized (mPackages) {
4412            if (component.equals(mResolveComponentName)) {
4413                // The resolver supports EVERYTHING!
4414                return true;
4415            }
4416            PackageParser.Activity a = mActivities.mActivities.get(component);
4417            if (a == null) {
4418                return false;
4419            }
4420            for (int i=0; i<a.intents.size(); i++) {
4421                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4422                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4423                    return true;
4424                }
4425            }
4426            return false;
4427        }
4428    }
4429
4430    @Override
4431    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4432        if (!sUserManager.exists(userId)) return null;
4433        flags = updateFlagsForComponent(flags, userId, component);
4434        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4435                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4436        synchronized (mPackages) {
4437            PackageParser.Activity a = mReceivers.mActivities.get(component);
4438            if (DEBUG_PACKAGE_INFO) Log.v(
4439                TAG, "getReceiverInfo " + component + ": " + a);
4440            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4441                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4442                if (ps == null) return null;
4443                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4444            }
4445        }
4446        return null;
4447    }
4448
4449    @Override
4450    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4451            int flags, int userId) {
4452        if (!sUserManager.exists(userId)) return null;
4453        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4454        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4455            return null;
4456        }
4457
4458        flags = updateFlagsForPackage(flags, userId, null);
4459
4460        final boolean canSeeStaticLibraries =
4461                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4462                        == PERMISSION_GRANTED
4463                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4464                        == PERMISSION_GRANTED
4465                || canRequestPackageInstallsInternal(packageName,
4466                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4467                        false  /* throwIfPermNotDeclared*/)
4468                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4469                        == PERMISSION_GRANTED;
4470
4471        synchronized (mPackages) {
4472            List<SharedLibraryInfo> result = null;
4473
4474            final int libCount = mSharedLibraries.size();
4475            for (int i = 0; i < libCount; i++) {
4476                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4477                if (versionedLib == null) {
4478                    continue;
4479                }
4480
4481                final int versionCount = versionedLib.size();
4482                for (int j = 0; j < versionCount; j++) {
4483                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4484                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4485                        break;
4486                    }
4487                    final long identity = Binder.clearCallingIdentity();
4488                    try {
4489                        PackageInfo packageInfo = getPackageInfoVersioned(
4490                                libInfo.getDeclaringPackage(), flags
4491                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4492                        if (packageInfo == null) {
4493                            continue;
4494                        }
4495                    } finally {
4496                        Binder.restoreCallingIdentity(identity);
4497                    }
4498
4499                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4500                            libInfo.getVersion(), libInfo.getType(),
4501                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4502                            flags, userId));
4503
4504                    if (result == null) {
4505                        result = new ArrayList<>();
4506                    }
4507                    result.add(resLibInfo);
4508                }
4509            }
4510
4511            return result != null ? new ParceledListSlice<>(result) : null;
4512        }
4513    }
4514
4515    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4516            SharedLibraryInfo libInfo, int flags, int userId) {
4517        List<VersionedPackage> versionedPackages = null;
4518        final int packageCount = mSettings.mPackages.size();
4519        for (int i = 0; i < packageCount; i++) {
4520            PackageSetting ps = mSettings.mPackages.valueAt(i);
4521
4522            if (ps == null) {
4523                continue;
4524            }
4525
4526            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4527                continue;
4528            }
4529
4530            final String libName = libInfo.getName();
4531            if (libInfo.isStatic()) {
4532                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4533                if (libIdx < 0) {
4534                    continue;
4535                }
4536                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4537                    continue;
4538                }
4539                if (versionedPackages == null) {
4540                    versionedPackages = new ArrayList<>();
4541                }
4542                // If the dependent is a static shared lib, use the public package name
4543                String dependentPackageName = ps.name;
4544                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4545                    dependentPackageName = ps.pkg.manifestPackageName;
4546                }
4547                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4548            } else if (ps.pkg != null) {
4549                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4550                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4551                    if (versionedPackages == null) {
4552                        versionedPackages = new ArrayList<>();
4553                    }
4554                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4555                }
4556            }
4557        }
4558
4559        return versionedPackages;
4560    }
4561
4562    @Override
4563    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4564        if (!sUserManager.exists(userId)) return null;
4565        final int callingUid = Binder.getCallingUid();
4566        flags = updateFlagsForComponent(flags, userId, component);
4567        enforceCrossUserPermission(callingUid, userId,
4568                false /* requireFullPermission */, false /* checkShell */, "get service info");
4569        synchronized (mPackages) {
4570            PackageParser.Service s = mServices.mServices.get(component);
4571            if (DEBUG_PACKAGE_INFO) Log.v(
4572                TAG, "getServiceInfo " + component + ": " + s);
4573            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4574                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4575                if (ps == null) return null;
4576                final boolean visibleToInstantApp =
4577                        (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4578                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4579                    return null;
4580                }
4581                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4582                        ps.readUserState(userId), userId);
4583                if (si != null) {
4584                    rebaseEnabledOverlays(si.applicationInfo, userId);
4585                }
4586                return si;
4587            }
4588        }
4589        return null;
4590    }
4591
4592    @Override
4593    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4594        if (!sUserManager.exists(userId)) return null;
4595        final int callingUid = Binder.getCallingUid();
4596        flags = updateFlagsForComponent(flags, userId, component);
4597        enforceCrossUserPermission(callingUid, userId,
4598                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4599        synchronized (mPackages) {
4600            PackageParser.Provider p = mProviders.mProviders.get(component);
4601            if (DEBUG_PACKAGE_INFO) Log.v(
4602                TAG, "getProviderInfo " + component + ": " + p);
4603            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4604                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4605                if (ps == null) return null;
4606                final boolean visibleToInstantApp =
4607                        (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4608                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4609                    return null;
4610                }
4611                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4612                        ps.readUserState(userId), userId);
4613                if (pi != null) {
4614                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4615                }
4616                return pi;
4617            }
4618        }
4619        return null;
4620    }
4621
4622    @Override
4623    public String[] getSystemSharedLibraryNames() {
4624        synchronized (mPackages) {
4625            Set<String> libs = null;
4626            final int libCount = mSharedLibraries.size();
4627            for (int i = 0; i < libCount; i++) {
4628                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4629                if (versionedLib == null) {
4630                    continue;
4631                }
4632                final int versionCount = versionedLib.size();
4633                for (int j = 0; j < versionCount; j++) {
4634                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4635                    if (!libEntry.info.isStatic()) {
4636                        if (libs == null) {
4637                            libs = new ArraySet<>();
4638                        }
4639                        libs.add(libEntry.info.getName());
4640                        break;
4641                    }
4642                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4643                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4644                            UserHandle.getUserId(Binder.getCallingUid()),
4645                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4646                        if (libs == null) {
4647                            libs = new ArraySet<>();
4648                        }
4649                        libs.add(libEntry.info.getName());
4650                        break;
4651                    }
4652                }
4653            }
4654
4655            if (libs != null) {
4656                String[] libsArray = new String[libs.size()];
4657                libs.toArray(libsArray);
4658                return libsArray;
4659            }
4660
4661            return null;
4662        }
4663    }
4664
4665    @Override
4666    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4667        // allow instant applications
4668        synchronized (mPackages) {
4669            return mServicesSystemSharedLibraryPackageName;
4670        }
4671    }
4672
4673    @Override
4674    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4675        // allow instant applications
4676        synchronized (mPackages) {
4677            return mSharedSystemSharedLibraryPackageName;
4678        }
4679    }
4680
4681    private void updateSequenceNumberLP(String packageName, int[] userList) {
4682        for (int i = userList.length - 1; i >= 0; --i) {
4683            final int userId = userList[i];
4684            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4685            if (changedPackages == null) {
4686                changedPackages = new SparseArray<>();
4687                mChangedPackages.put(userId, changedPackages);
4688            }
4689            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4690            if (sequenceNumbers == null) {
4691                sequenceNumbers = new HashMap<>();
4692                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4693            }
4694            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4695            if (sequenceNumber != null) {
4696                changedPackages.remove(sequenceNumber);
4697            }
4698            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4699            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4700        }
4701        mChangedPackagesSequenceNumber++;
4702    }
4703
4704    @Override
4705    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4706        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4707            return null;
4708        }
4709        synchronized (mPackages) {
4710            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4711                return null;
4712            }
4713            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4714            if (changedPackages == null) {
4715                return null;
4716            }
4717            final List<String> packageNames =
4718                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4719            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4720                final String packageName = changedPackages.get(i);
4721                if (packageName != null) {
4722                    packageNames.add(packageName);
4723                }
4724            }
4725            return packageNames.isEmpty()
4726                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4727        }
4728    }
4729
4730    @Override
4731    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4732        // allow instant applications
4733        ArrayList<FeatureInfo> res;
4734        synchronized (mAvailableFeatures) {
4735            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4736            res.addAll(mAvailableFeatures.values());
4737        }
4738        final FeatureInfo fi = new FeatureInfo();
4739        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4740                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4741        res.add(fi);
4742
4743        return new ParceledListSlice<>(res);
4744    }
4745
4746    @Override
4747    public boolean hasSystemFeature(String name, int version) {
4748        // allow instant applications
4749        synchronized (mAvailableFeatures) {
4750            final FeatureInfo feat = mAvailableFeatures.get(name);
4751            if (feat == null) {
4752                return false;
4753            } else {
4754                return feat.version >= version;
4755            }
4756        }
4757    }
4758
4759    @Override
4760    public int checkPermission(String permName, String pkgName, int userId) {
4761        if (!sUserManager.exists(userId)) {
4762            return PackageManager.PERMISSION_DENIED;
4763        }
4764
4765        synchronized (mPackages) {
4766            final PackageParser.Package p = mPackages.get(pkgName);
4767            if (p != null && p.mExtras != null) {
4768                final PackageSetting ps = (PackageSetting) p.mExtras;
4769                final PermissionsState permissionsState = ps.getPermissionsState();
4770                if (permissionsState.hasPermission(permName, userId)) {
4771                    return PackageManager.PERMISSION_GRANTED;
4772                }
4773                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4774                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4775                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4776                    return PackageManager.PERMISSION_GRANTED;
4777                }
4778            }
4779        }
4780
4781        return PackageManager.PERMISSION_DENIED;
4782    }
4783
4784    @Override
4785    public int checkUidPermission(String permName, int uid) {
4786        final int userId = UserHandle.getUserId(uid);
4787
4788        if (!sUserManager.exists(userId)) {
4789            return PackageManager.PERMISSION_DENIED;
4790        }
4791
4792        synchronized (mPackages) {
4793            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4794            if (obj != null) {
4795                final SettingBase ps = (SettingBase) obj;
4796                final PermissionsState permissionsState = ps.getPermissionsState();
4797                if (permissionsState.hasPermission(permName, userId)) {
4798                    return PackageManager.PERMISSION_GRANTED;
4799                }
4800                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4801                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4802                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4803                    return PackageManager.PERMISSION_GRANTED;
4804                }
4805            } else {
4806                ArraySet<String> perms = mSystemPermissions.get(uid);
4807                if (perms != null) {
4808                    if (perms.contains(permName)) {
4809                        return PackageManager.PERMISSION_GRANTED;
4810                    }
4811                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4812                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4813                        return PackageManager.PERMISSION_GRANTED;
4814                    }
4815                }
4816            }
4817        }
4818
4819        return PackageManager.PERMISSION_DENIED;
4820    }
4821
4822    @Override
4823    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4824        if (UserHandle.getCallingUserId() != userId) {
4825            mContext.enforceCallingPermission(
4826                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4827                    "isPermissionRevokedByPolicy for user " + userId);
4828        }
4829
4830        if (checkPermission(permission, packageName, userId)
4831                == PackageManager.PERMISSION_GRANTED) {
4832            return false;
4833        }
4834
4835        final long identity = Binder.clearCallingIdentity();
4836        try {
4837            final int flags = getPermissionFlags(permission, packageName, userId);
4838            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4839        } finally {
4840            Binder.restoreCallingIdentity(identity);
4841        }
4842    }
4843
4844    @Override
4845    public String getPermissionControllerPackageName() {
4846        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4847            throw new SecurityException("Instant applications don't have access to this method");
4848        }
4849        synchronized (mPackages) {
4850            return mRequiredInstallerPackage;
4851        }
4852    }
4853
4854    /**
4855     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4856     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4857     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4858     * @param message the message to log on security exception
4859     */
4860    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4861            boolean checkShell, String message) {
4862        if (userId < 0) {
4863            throw new IllegalArgumentException("Invalid userId " + userId);
4864        }
4865        if (checkShell) {
4866            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4867        }
4868        if (userId == UserHandle.getUserId(callingUid)) return;
4869        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4870            if (requireFullPermission) {
4871                mContext.enforceCallingOrSelfPermission(
4872                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4873            } else {
4874                try {
4875                    mContext.enforceCallingOrSelfPermission(
4876                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4877                } catch (SecurityException se) {
4878                    mContext.enforceCallingOrSelfPermission(
4879                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4880                }
4881            }
4882        }
4883    }
4884
4885    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4886        if (callingUid == Process.SHELL_UID) {
4887            if (userHandle >= 0
4888                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4889                throw new SecurityException("Shell does not have permission to access user "
4890                        + userHandle);
4891            } else if (userHandle < 0) {
4892                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4893                        + Debug.getCallers(3));
4894            }
4895        }
4896    }
4897
4898    private BasePermission findPermissionTreeLP(String permName) {
4899        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4900            if (permName.startsWith(bp.name) &&
4901                    permName.length() > bp.name.length() &&
4902                    permName.charAt(bp.name.length()) == '.') {
4903                return bp;
4904            }
4905        }
4906        return null;
4907    }
4908
4909    private BasePermission checkPermissionTreeLP(String permName) {
4910        if (permName != null) {
4911            BasePermission bp = findPermissionTreeLP(permName);
4912            if (bp != null) {
4913                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4914                    return bp;
4915                }
4916                throw new SecurityException("Calling uid "
4917                        + Binder.getCallingUid()
4918                        + " is not allowed to add to permission tree "
4919                        + bp.name + " owned by uid " + bp.uid);
4920            }
4921        }
4922        throw new SecurityException("No permission tree found for " + permName);
4923    }
4924
4925    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4926        if (s1 == null) {
4927            return s2 == null;
4928        }
4929        if (s2 == null) {
4930            return false;
4931        }
4932        if (s1.getClass() != s2.getClass()) {
4933            return false;
4934        }
4935        return s1.equals(s2);
4936    }
4937
4938    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4939        if (pi1.icon != pi2.icon) return false;
4940        if (pi1.logo != pi2.logo) return false;
4941        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4942        if (!compareStrings(pi1.name, pi2.name)) return false;
4943        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4944        // We'll take care of setting this one.
4945        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4946        // These are not currently stored in settings.
4947        //if (!compareStrings(pi1.group, pi2.group)) return false;
4948        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4949        //if (pi1.labelRes != pi2.labelRes) return false;
4950        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4951        return true;
4952    }
4953
4954    int permissionInfoFootprint(PermissionInfo info) {
4955        int size = info.name.length();
4956        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4957        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4958        return size;
4959    }
4960
4961    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4962        int size = 0;
4963        for (BasePermission perm : mSettings.mPermissions.values()) {
4964            if (perm.uid == tree.uid) {
4965                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4966            }
4967        }
4968        return size;
4969    }
4970
4971    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4972        // We calculate the max size of permissions defined by this uid and throw
4973        // if that plus the size of 'info' would exceed our stated maximum.
4974        if (tree.uid != Process.SYSTEM_UID) {
4975            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4976            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4977                throw new SecurityException("Permission tree size cap exceeded");
4978            }
4979        }
4980    }
4981
4982    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4983        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4984            throw new SecurityException("Instant apps can't add permissions");
4985        }
4986        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4987            throw new SecurityException("Label must be specified in permission");
4988        }
4989        BasePermission tree = checkPermissionTreeLP(info.name);
4990        BasePermission bp = mSettings.mPermissions.get(info.name);
4991        boolean added = bp == null;
4992        boolean changed = true;
4993        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4994        if (added) {
4995            enforcePermissionCapLocked(info, tree);
4996            bp = new BasePermission(info.name, tree.sourcePackage,
4997                    BasePermission.TYPE_DYNAMIC);
4998        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4999            throw new SecurityException(
5000                    "Not allowed to modify non-dynamic permission "
5001                    + info.name);
5002        } else {
5003            if (bp.protectionLevel == fixedLevel
5004                    && bp.perm.owner.equals(tree.perm.owner)
5005                    && bp.uid == tree.uid
5006                    && comparePermissionInfos(bp.perm.info, info)) {
5007                changed = false;
5008            }
5009        }
5010        bp.protectionLevel = fixedLevel;
5011        info = new PermissionInfo(info);
5012        info.protectionLevel = fixedLevel;
5013        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5014        bp.perm.info.packageName = tree.perm.info.packageName;
5015        bp.uid = tree.uid;
5016        if (added) {
5017            mSettings.mPermissions.put(info.name, bp);
5018        }
5019        if (changed) {
5020            if (!async) {
5021                mSettings.writeLPr();
5022            } else {
5023                scheduleWriteSettingsLocked();
5024            }
5025        }
5026        return added;
5027    }
5028
5029    @Override
5030    public boolean addPermission(PermissionInfo info) {
5031        synchronized (mPackages) {
5032            return addPermissionLocked(info, false);
5033        }
5034    }
5035
5036    @Override
5037    public boolean addPermissionAsync(PermissionInfo info) {
5038        synchronized (mPackages) {
5039            return addPermissionLocked(info, true);
5040        }
5041    }
5042
5043    @Override
5044    public void removePermission(String name) {
5045        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5046            throw new SecurityException("Instant applications don't have access to this method");
5047        }
5048        synchronized (mPackages) {
5049            checkPermissionTreeLP(name);
5050            BasePermission bp = mSettings.mPermissions.get(name);
5051            if (bp != null) {
5052                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5053                    throw new SecurityException(
5054                            "Not allowed to modify non-dynamic permission "
5055                            + name);
5056                }
5057                mSettings.mPermissions.remove(name);
5058                mSettings.writeLPr();
5059            }
5060        }
5061    }
5062
5063    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5064            PackageParser.Package pkg, BasePermission bp) {
5065        int index = pkg.requestedPermissions.indexOf(bp.name);
5066        if (index == -1) {
5067            throw new SecurityException("Package " + pkg.packageName
5068                    + " has not requested permission " + bp.name);
5069        }
5070        if (!bp.isRuntime() && !bp.isDevelopment()) {
5071            throw new SecurityException("Permission " + bp.name
5072                    + " is not a changeable permission type");
5073        }
5074    }
5075
5076    @Override
5077    public void grantRuntimePermission(String packageName, String name, final int userId) {
5078        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5079    }
5080
5081    private void grantRuntimePermission(String packageName, String name, final int userId,
5082            boolean overridePolicy) {
5083        if (!sUserManager.exists(userId)) {
5084            Log.e(TAG, "No such user:" + userId);
5085            return;
5086        }
5087
5088        mContext.enforceCallingOrSelfPermission(
5089                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5090                "grantRuntimePermission");
5091
5092        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5093                true /* requireFullPermission */, true /* checkShell */,
5094                "grantRuntimePermission");
5095
5096        final int uid;
5097        final SettingBase sb;
5098
5099        synchronized (mPackages) {
5100            final PackageParser.Package pkg = mPackages.get(packageName);
5101            if (pkg == null) {
5102                throw new IllegalArgumentException("Unknown package: " + packageName);
5103            }
5104
5105            final BasePermission bp = mSettings.mPermissions.get(name);
5106            if (bp == null) {
5107                throw new IllegalArgumentException("Unknown permission: " + name);
5108            }
5109
5110            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5111
5112            // If a permission review is required for legacy apps we represent
5113            // their permissions as always granted runtime ones since we need
5114            // to keep the review required permission flag per user while an
5115            // install permission's state is shared across all users.
5116            if (mPermissionReviewRequired
5117                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5118                    && bp.isRuntime()) {
5119                return;
5120            }
5121
5122            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5123            sb = (SettingBase) pkg.mExtras;
5124            if (sb == null) {
5125                throw new IllegalArgumentException("Unknown package: " + packageName);
5126            }
5127
5128            final PermissionsState permissionsState = sb.getPermissionsState();
5129
5130            final int flags = permissionsState.getPermissionFlags(name, userId);
5131            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5132                throw new SecurityException("Cannot grant system fixed permission "
5133                        + name + " for package " + packageName);
5134            }
5135            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5136                throw new SecurityException("Cannot grant policy fixed permission "
5137                        + name + " for package " + packageName);
5138            }
5139
5140            if (bp.isDevelopment()) {
5141                // Development permissions must be handled specially, since they are not
5142                // normal runtime permissions.  For now they apply to all users.
5143                if (permissionsState.grantInstallPermission(bp) !=
5144                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5145                    scheduleWriteSettingsLocked();
5146                }
5147                return;
5148            }
5149
5150            final PackageSetting ps = mSettings.mPackages.get(packageName);
5151            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5152                throw new SecurityException("Cannot grant non-ephemeral permission"
5153                        + name + " for package " + packageName);
5154            }
5155
5156            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5157                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5158                return;
5159            }
5160
5161            final int result = permissionsState.grantRuntimePermission(bp, userId);
5162            switch (result) {
5163                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5164                    return;
5165                }
5166
5167                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5168                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5169                    mHandler.post(new Runnable() {
5170                        @Override
5171                        public void run() {
5172                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5173                        }
5174                    });
5175                }
5176                break;
5177            }
5178
5179            if (bp.isRuntime()) {
5180                logPermissionGranted(mContext, name, packageName);
5181            }
5182
5183            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5184
5185            // Not critical if that is lost - app has to request again.
5186            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5187        }
5188
5189        // Only need to do this if user is initialized. Otherwise it's a new user
5190        // and there are no processes running as the user yet and there's no need
5191        // to make an expensive call to remount processes for the changed permissions.
5192        if (READ_EXTERNAL_STORAGE.equals(name)
5193                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5194            final long token = Binder.clearCallingIdentity();
5195            try {
5196                if (sUserManager.isInitialized(userId)) {
5197                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5198                            StorageManagerInternal.class);
5199                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5200                }
5201            } finally {
5202                Binder.restoreCallingIdentity(token);
5203            }
5204        }
5205    }
5206
5207    @Override
5208    public void revokeRuntimePermission(String packageName, String name, int userId) {
5209        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5210    }
5211
5212    private void revokeRuntimePermission(String packageName, String name, int userId,
5213            boolean overridePolicy) {
5214        if (!sUserManager.exists(userId)) {
5215            Log.e(TAG, "No such user:" + userId);
5216            return;
5217        }
5218
5219        mContext.enforceCallingOrSelfPermission(
5220                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5221                "revokeRuntimePermission");
5222
5223        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5224                true /* requireFullPermission */, true /* checkShell */,
5225                "revokeRuntimePermission");
5226
5227        final int appId;
5228
5229        synchronized (mPackages) {
5230            final PackageParser.Package pkg = mPackages.get(packageName);
5231            if (pkg == null) {
5232                throw new IllegalArgumentException("Unknown package: " + packageName);
5233            }
5234
5235            final BasePermission bp = mSettings.mPermissions.get(name);
5236            if (bp == null) {
5237                throw new IllegalArgumentException("Unknown permission: " + name);
5238            }
5239
5240            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5241
5242            // If a permission review is required for legacy apps we represent
5243            // their permissions as always granted runtime ones since we need
5244            // to keep the review required permission flag per user while an
5245            // install permission's state is shared across all users.
5246            if (mPermissionReviewRequired
5247                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5248                    && bp.isRuntime()) {
5249                return;
5250            }
5251
5252            SettingBase sb = (SettingBase) pkg.mExtras;
5253            if (sb == null) {
5254                throw new IllegalArgumentException("Unknown package: " + packageName);
5255            }
5256
5257            final PermissionsState permissionsState = sb.getPermissionsState();
5258
5259            final int flags = permissionsState.getPermissionFlags(name, userId);
5260            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5261                throw new SecurityException("Cannot revoke system fixed permission "
5262                        + name + " for package " + packageName);
5263            }
5264            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5265                throw new SecurityException("Cannot revoke policy fixed permission "
5266                        + name + " for package " + packageName);
5267            }
5268
5269            if (bp.isDevelopment()) {
5270                // Development permissions must be handled specially, since they are not
5271                // normal runtime permissions.  For now they apply to all users.
5272                if (permissionsState.revokeInstallPermission(bp) !=
5273                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5274                    scheduleWriteSettingsLocked();
5275                }
5276                return;
5277            }
5278
5279            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5280                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5281                return;
5282            }
5283
5284            if (bp.isRuntime()) {
5285                logPermissionRevoked(mContext, name, packageName);
5286            }
5287
5288            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5289
5290            // Critical, after this call app should never have the permission.
5291            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5292
5293            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5294        }
5295
5296        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5297    }
5298
5299    /**
5300     * Get the first event id for the permission.
5301     *
5302     * <p>There are four events for each permission: <ul>
5303     *     <li>Request permission: first id + 0</li>
5304     *     <li>Grant permission: first id + 1</li>
5305     *     <li>Request for permission denied: first id + 2</li>
5306     *     <li>Revoke permission: first id + 3</li>
5307     * </ul></p>
5308     *
5309     * @param name name of the permission
5310     *
5311     * @return The first event id for the permission
5312     */
5313    private static int getBaseEventId(@NonNull String name) {
5314        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5315
5316        if (eventIdIndex == -1) {
5317            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5318                    || "user".equals(Build.TYPE)) {
5319                Log.i(TAG, "Unknown permission " + name);
5320
5321                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5322            } else {
5323                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5324                //
5325                // Also update
5326                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5327                // - metrics_constants.proto
5328                throw new IllegalStateException("Unknown permission " + name);
5329            }
5330        }
5331
5332        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5333    }
5334
5335    /**
5336     * Log that a permission was revoked.
5337     *
5338     * @param context Context of the caller
5339     * @param name name of the permission
5340     * @param packageName package permission if for
5341     */
5342    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5343            @NonNull String packageName) {
5344        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5345    }
5346
5347    /**
5348     * Log that a permission request was granted.
5349     *
5350     * @param context Context of the caller
5351     * @param name name of the permission
5352     * @param packageName package permission if for
5353     */
5354    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5355            @NonNull String packageName) {
5356        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5357    }
5358
5359    @Override
5360    public void resetRuntimePermissions() {
5361        mContext.enforceCallingOrSelfPermission(
5362                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5363                "revokeRuntimePermission");
5364
5365        int callingUid = Binder.getCallingUid();
5366        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5367            mContext.enforceCallingOrSelfPermission(
5368                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5369                    "resetRuntimePermissions");
5370        }
5371
5372        synchronized (mPackages) {
5373            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5374            for (int userId : UserManagerService.getInstance().getUserIds()) {
5375                final int packageCount = mPackages.size();
5376                for (int i = 0; i < packageCount; i++) {
5377                    PackageParser.Package pkg = mPackages.valueAt(i);
5378                    if (!(pkg.mExtras instanceof PackageSetting)) {
5379                        continue;
5380                    }
5381                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5382                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5383                }
5384            }
5385        }
5386    }
5387
5388    @Override
5389    public int getPermissionFlags(String name, String packageName, int userId) {
5390        if (!sUserManager.exists(userId)) {
5391            return 0;
5392        }
5393
5394        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5395
5396        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5397                true /* requireFullPermission */, false /* checkShell */,
5398                "getPermissionFlags");
5399
5400        synchronized (mPackages) {
5401            final PackageParser.Package pkg = mPackages.get(packageName);
5402            if (pkg == null) {
5403                return 0;
5404            }
5405
5406            final BasePermission bp = mSettings.mPermissions.get(name);
5407            if (bp == null) {
5408                return 0;
5409            }
5410
5411            SettingBase sb = (SettingBase) pkg.mExtras;
5412            if (sb == null) {
5413                return 0;
5414            }
5415
5416            PermissionsState permissionsState = sb.getPermissionsState();
5417            return permissionsState.getPermissionFlags(name, userId);
5418        }
5419    }
5420
5421    @Override
5422    public void updatePermissionFlags(String name, String packageName, int flagMask,
5423            int flagValues, int userId) {
5424        if (!sUserManager.exists(userId)) {
5425            return;
5426        }
5427
5428        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5429
5430        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5431                true /* requireFullPermission */, true /* checkShell */,
5432                "updatePermissionFlags");
5433
5434        // Only the system can change these flags and nothing else.
5435        if (getCallingUid() != Process.SYSTEM_UID) {
5436            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5437            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5438            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5439            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5440            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5441        }
5442
5443        synchronized (mPackages) {
5444            final PackageParser.Package pkg = mPackages.get(packageName);
5445            if (pkg == null) {
5446                throw new IllegalArgumentException("Unknown package: " + packageName);
5447            }
5448
5449            final BasePermission bp = mSettings.mPermissions.get(name);
5450            if (bp == null) {
5451                throw new IllegalArgumentException("Unknown permission: " + name);
5452            }
5453
5454            SettingBase sb = (SettingBase) pkg.mExtras;
5455            if (sb == null) {
5456                throw new IllegalArgumentException("Unknown package: " + packageName);
5457            }
5458
5459            PermissionsState permissionsState = sb.getPermissionsState();
5460
5461            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5462
5463            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5464                // Install and runtime permissions are stored in different places,
5465                // so figure out what permission changed and persist the change.
5466                if (permissionsState.getInstallPermissionState(name) != null) {
5467                    scheduleWriteSettingsLocked();
5468                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5469                        || hadState) {
5470                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5471                }
5472            }
5473        }
5474    }
5475
5476    /**
5477     * Update the permission flags for all packages and runtime permissions of a user in order
5478     * to allow device or profile owner to remove POLICY_FIXED.
5479     */
5480    @Override
5481    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5482        if (!sUserManager.exists(userId)) {
5483            return;
5484        }
5485
5486        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5487
5488        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5489                true /* requireFullPermission */, true /* checkShell */,
5490                "updatePermissionFlagsForAllApps");
5491
5492        // Only the system can change system fixed flags.
5493        if (getCallingUid() != Process.SYSTEM_UID) {
5494            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5495            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5496        }
5497
5498        synchronized (mPackages) {
5499            boolean changed = false;
5500            final int packageCount = mPackages.size();
5501            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5502                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5503                SettingBase sb = (SettingBase) pkg.mExtras;
5504                if (sb == null) {
5505                    continue;
5506                }
5507                PermissionsState permissionsState = sb.getPermissionsState();
5508                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5509                        userId, flagMask, flagValues);
5510            }
5511            if (changed) {
5512                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5513            }
5514        }
5515    }
5516
5517    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5518        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5519                != PackageManager.PERMISSION_GRANTED
5520            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            throw new SecurityException(message + " requires "
5523                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5524                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5525        }
5526    }
5527
5528    @Override
5529    public boolean shouldShowRequestPermissionRationale(String permissionName,
5530            String packageName, int userId) {
5531        if (UserHandle.getCallingUserId() != userId) {
5532            mContext.enforceCallingPermission(
5533                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5534                    "canShowRequestPermissionRationale for user " + userId);
5535        }
5536
5537        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5538        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5539            return false;
5540        }
5541
5542        if (checkPermission(permissionName, packageName, userId)
5543                == PackageManager.PERMISSION_GRANTED) {
5544            return false;
5545        }
5546
5547        final int flags;
5548
5549        final long identity = Binder.clearCallingIdentity();
5550        try {
5551            flags = getPermissionFlags(permissionName,
5552                    packageName, userId);
5553        } finally {
5554            Binder.restoreCallingIdentity(identity);
5555        }
5556
5557        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5558                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5559                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5560
5561        if ((flags & fixedFlags) != 0) {
5562            return false;
5563        }
5564
5565        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5566    }
5567
5568    @Override
5569    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5570        mContext.enforceCallingOrSelfPermission(
5571                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5572                "addOnPermissionsChangeListener");
5573
5574        synchronized (mPackages) {
5575            mOnPermissionChangeListeners.addListenerLocked(listener);
5576        }
5577    }
5578
5579    @Override
5580    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5581        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5582            throw new SecurityException("Instant applications don't have access to this method");
5583        }
5584        synchronized (mPackages) {
5585            mOnPermissionChangeListeners.removeListenerLocked(listener);
5586        }
5587    }
5588
5589    @Override
5590    public boolean isProtectedBroadcast(String actionName) {
5591        // allow instant applications
5592        synchronized (mPackages) {
5593            if (mProtectedBroadcasts.contains(actionName)) {
5594                return true;
5595            } else if (actionName != null) {
5596                // TODO: remove these terrible hacks
5597                if (actionName.startsWith("android.net.netmon.lingerExpired")
5598                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5599                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5600                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5601                    return true;
5602                }
5603            }
5604        }
5605        return false;
5606    }
5607
5608    @Override
5609    public int checkSignatures(String pkg1, String pkg2) {
5610        synchronized (mPackages) {
5611            final PackageParser.Package p1 = mPackages.get(pkg1);
5612            final PackageParser.Package p2 = mPackages.get(pkg2);
5613            if (p1 == null || p1.mExtras == null
5614                    || p2 == null || p2.mExtras == null) {
5615                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5616            }
5617            return compareSignatures(p1.mSignatures, p2.mSignatures);
5618        }
5619    }
5620
5621    @Override
5622    public int checkUidSignatures(int uid1, int uid2) {
5623        // Map to base uids.
5624        uid1 = UserHandle.getAppId(uid1);
5625        uid2 = UserHandle.getAppId(uid2);
5626        // reader
5627        synchronized (mPackages) {
5628            Signature[] s1;
5629            Signature[] s2;
5630            Object obj = mSettings.getUserIdLPr(uid1);
5631            if (obj != null) {
5632                if (obj instanceof SharedUserSetting) {
5633                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5634                } else if (obj instanceof PackageSetting) {
5635                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5636                } else {
5637                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5638                }
5639            } else {
5640                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5641            }
5642            obj = mSettings.getUserIdLPr(uid2);
5643            if (obj != null) {
5644                if (obj instanceof SharedUserSetting) {
5645                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5646                } else if (obj instanceof PackageSetting) {
5647                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5648                } else {
5649                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5650                }
5651            } else {
5652                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5653            }
5654            return compareSignatures(s1, s2);
5655        }
5656    }
5657
5658    /**
5659     * This method should typically only be used when granting or revoking
5660     * permissions, since the app may immediately restart after this call.
5661     * <p>
5662     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5663     * guard your work against the app being relaunched.
5664     */
5665    private void killUid(int appId, int userId, String reason) {
5666        final long identity = Binder.clearCallingIdentity();
5667        try {
5668            IActivityManager am = ActivityManager.getService();
5669            if (am != null) {
5670                try {
5671                    am.killUid(appId, userId, reason);
5672                } catch (RemoteException e) {
5673                    /* ignore - same process */
5674                }
5675            }
5676        } finally {
5677            Binder.restoreCallingIdentity(identity);
5678        }
5679    }
5680
5681    /**
5682     * Compares two sets of signatures. Returns:
5683     * <br />
5684     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5685     * <br />
5686     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5687     * <br />
5688     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5689     * <br />
5690     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5691     * <br />
5692     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5693     */
5694    static int compareSignatures(Signature[] s1, Signature[] s2) {
5695        if (s1 == null) {
5696            return s2 == null
5697                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5698                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5699        }
5700
5701        if (s2 == null) {
5702            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5703        }
5704
5705        if (s1.length != s2.length) {
5706            return PackageManager.SIGNATURE_NO_MATCH;
5707        }
5708
5709        // Since both signature sets are of size 1, we can compare without HashSets.
5710        if (s1.length == 1) {
5711            return s1[0].equals(s2[0]) ?
5712                    PackageManager.SIGNATURE_MATCH :
5713                    PackageManager.SIGNATURE_NO_MATCH;
5714        }
5715
5716        ArraySet<Signature> set1 = new ArraySet<Signature>();
5717        for (Signature sig : s1) {
5718            set1.add(sig);
5719        }
5720        ArraySet<Signature> set2 = new ArraySet<Signature>();
5721        for (Signature sig : s2) {
5722            set2.add(sig);
5723        }
5724        // Make sure s2 contains all signatures in s1.
5725        if (set1.equals(set2)) {
5726            return PackageManager.SIGNATURE_MATCH;
5727        }
5728        return PackageManager.SIGNATURE_NO_MATCH;
5729    }
5730
5731    /**
5732     * If the database version for this type of package (internal storage or
5733     * external storage) is less than the version where package signatures
5734     * were updated, return true.
5735     */
5736    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5737        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5738        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5739    }
5740
5741    /**
5742     * Used for backward compatibility to make sure any packages with
5743     * certificate chains get upgraded to the new style. {@code existingSigs}
5744     * will be in the old format (since they were stored on disk from before the
5745     * system upgrade) and {@code scannedSigs} will be in the newer format.
5746     */
5747    private int compareSignaturesCompat(PackageSignatures existingSigs,
5748            PackageParser.Package scannedPkg) {
5749        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5750            return PackageManager.SIGNATURE_NO_MATCH;
5751        }
5752
5753        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5754        for (Signature sig : existingSigs.mSignatures) {
5755            existingSet.add(sig);
5756        }
5757        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5758        for (Signature sig : scannedPkg.mSignatures) {
5759            try {
5760                Signature[] chainSignatures = sig.getChainSignatures();
5761                for (Signature chainSig : chainSignatures) {
5762                    scannedCompatSet.add(chainSig);
5763                }
5764            } catch (CertificateEncodingException e) {
5765                scannedCompatSet.add(sig);
5766            }
5767        }
5768        /*
5769         * Make sure the expanded scanned set contains all signatures in the
5770         * existing one.
5771         */
5772        if (scannedCompatSet.equals(existingSet)) {
5773            // Migrate the old signatures to the new scheme.
5774            existingSigs.assignSignatures(scannedPkg.mSignatures);
5775            // The new KeySets will be re-added later in the scanning process.
5776            synchronized (mPackages) {
5777                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5778            }
5779            return PackageManager.SIGNATURE_MATCH;
5780        }
5781        return PackageManager.SIGNATURE_NO_MATCH;
5782    }
5783
5784    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5785        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5786        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5787    }
5788
5789    private int compareSignaturesRecover(PackageSignatures existingSigs,
5790            PackageParser.Package scannedPkg) {
5791        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5792            return PackageManager.SIGNATURE_NO_MATCH;
5793        }
5794
5795        String msg = null;
5796        try {
5797            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5798                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5799                        + scannedPkg.packageName);
5800                return PackageManager.SIGNATURE_MATCH;
5801            }
5802        } catch (CertificateException e) {
5803            msg = e.getMessage();
5804        }
5805
5806        logCriticalInfo(Log.INFO,
5807                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5808        return PackageManager.SIGNATURE_NO_MATCH;
5809    }
5810
5811    @Override
5812    public List<String> getAllPackages() {
5813        synchronized (mPackages) {
5814            return new ArrayList<String>(mPackages.keySet());
5815        }
5816    }
5817
5818    @Override
5819    public String[] getPackagesForUid(int uid) {
5820        final int userId = UserHandle.getUserId(uid);
5821        uid = UserHandle.getAppId(uid);
5822        // reader
5823        synchronized (mPackages) {
5824            Object obj = mSettings.getUserIdLPr(uid);
5825            if (obj instanceof SharedUserSetting) {
5826                final SharedUserSetting sus = (SharedUserSetting) obj;
5827                final int N = sus.packages.size();
5828                String[] res = new String[N];
5829                final Iterator<PackageSetting> it = sus.packages.iterator();
5830                int i = 0;
5831                while (it.hasNext()) {
5832                    PackageSetting ps = it.next();
5833                    if (ps.getInstalled(userId)) {
5834                        res[i++] = ps.name;
5835                    } else {
5836                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5837                    }
5838                }
5839                return res;
5840            } else if (obj instanceof PackageSetting) {
5841                final PackageSetting ps = (PackageSetting) obj;
5842                if (ps.getInstalled(userId)) {
5843                    return new String[]{ps.name};
5844                }
5845            }
5846        }
5847        return null;
5848    }
5849
5850    @Override
5851    public String getNameForUid(int uid) {
5852        // reader
5853        synchronized (mPackages) {
5854            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5855            if (obj instanceof SharedUserSetting) {
5856                final SharedUserSetting sus = (SharedUserSetting) obj;
5857                return sus.name + ":" + sus.userId;
5858            } else if (obj instanceof PackageSetting) {
5859                final PackageSetting ps = (PackageSetting) obj;
5860                return ps.name;
5861            }
5862        }
5863        return null;
5864    }
5865
5866    @Override
5867    public int getUidForSharedUser(String sharedUserName) {
5868        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5869            return -1;
5870        }
5871        if(sharedUserName == null) {
5872            return -1;
5873        }
5874        // reader
5875        synchronized (mPackages) {
5876            SharedUserSetting suid;
5877            try {
5878                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5879                if (suid != null) {
5880                    return suid.userId;
5881                }
5882            } catch (PackageManagerException ignore) {
5883                // can't happen, but, still need to catch it
5884            }
5885            return -1;
5886        }
5887    }
5888
5889    @Override
5890    public int getFlagsForUid(int uid) {
5891        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5892            return 0;
5893        }
5894        synchronized (mPackages) {
5895            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5896            if (obj instanceof SharedUserSetting) {
5897                final SharedUserSetting sus = (SharedUserSetting) obj;
5898                return sus.pkgFlags;
5899            } else if (obj instanceof PackageSetting) {
5900                final PackageSetting ps = (PackageSetting) obj;
5901                return ps.pkgFlags;
5902            }
5903        }
5904        return 0;
5905    }
5906
5907    @Override
5908    public int getPrivateFlagsForUid(int uid) {
5909        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5910            return 0;
5911        }
5912        synchronized (mPackages) {
5913            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5914            if (obj instanceof SharedUserSetting) {
5915                final SharedUserSetting sus = (SharedUserSetting) obj;
5916                return sus.pkgPrivateFlags;
5917            } else if (obj instanceof PackageSetting) {
5918                final PackageSetting ps = (PackageSetting) obj;
5919                return ps.pkgPrivateFlags;
5920            }
5921        }
5922        return 0;
5923    }
5924
5925    @Override
5926    public boolean isUidPrivileged(int uid) {
5927        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5928            return false;
5929        }
5930        uid = UserHandle.getAppId(uid);
5931        // reader
5932        synchronized (mPackages) {
5933            Object obj = mSettings.getUserIdLPr(uid);
5934            if (obj instanceof SharedUserSetting) {
5935                final SharedUserSetting sus = (SharedUserSetting) obj;
5936                final Iterator<PackageSetting> it = sus.packages.iterator();
5937                while (it.hasNext()) {
5938                    if (it.next().isPrivileged()) {
5939                        return true;
5940                    }
5941                }
5942            } else if (obj instanceof PackageSetting) {
5943                final PackageSetting ps = (PackageSetting) obj;
5944                return ps.isPrivileged();
5945            }
5946        }
5947        return false;
5948    }
5949
5950    @Override
5951    public String[] getAppOpPermissionPackages(String permissionName) {
5952        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5953            return null;
5954        }
5955        synchronized (mPackages) {
5956            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5957            if (pkgs == null) {
5958                return null;
5959            }
5960            return pkgs.toArray(new String[pkgs.size()]);
5961        }
5962    }
5963
5964    @Override
5965    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5966            int flags, int userId) {
5967        return resolveIntentInternal(
5968                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5969    }
5970
5971    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5972            int flags, int userId, boolean resolveForStart) {
5973        try {
5974            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5975
5976            if (!sUserManager.exists(userId)) return null;
5977            final int callingUid = Binder.getCallingUid();
5978            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5979            enforceCrossUserPermission(callingUid, userId,
5980                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5981
5982            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5983            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5984                    flags, userId, resolveForStart);
5985            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5986
5987            final ResolveInfo bestChoice =
5988                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5989            return bestChoice;
5990        } finally {
5991            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5992        }
5993    }
5994
5995    @Override
5996    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5997        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5998            throw new SecurityException(
5999                    "findPersistentPreferredActivity can only be run by the system");
6000        }
6001        if (!sUserManager.exists(userId)) {
6002            return null;
6003        }
6004        final int callingUid = Binder.getCallingUid();
6005        intent = updateIntentForResolve(intent);
6006        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6007        final int flags = updateFlagsForResolve(
6008                0, userId, intent, callingUid, false /*includeInstantApps*/);
6009        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6010                userId);
6011        synchronized (mPackages) {
6012            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6013                    userId);
6014        }
6015    }
6016
6017    @Override
6018    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6019            IntentFilter filter, int match, ComponentName activity) {
6020        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6021            return;
6022        }
6023        final int userId = UserHandle.getCallingUserId();
6024        if (DEBUG_PREFERRED) {
6025            Log.v(TAG, "setLastChosenActivity intent=" + intent
6026                + " resolvedType=" + resolvedType
6027                + " flags=" + flags
6028                + " filter=" + filter
6029                + " match=" + match
6030                + " activity=" + activity);
6031            filter.dump(new PrintStreamPrinter(System.out), "    ");
6032        }
6033        intent.setComponent(null);
6034        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6035                userId);
6036        // Find any earlier preferred or last chosen entries and nuke them
6037        findPreferredActivity(intent, resolvedType,
6038                flags, query, 0, false, true, false, userId);
6039        // Add the new activity as the last chosen for this filter
6040        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6041                "Setting last chosen");
6042    }
6043
6044    @Override
6045    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6046        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6047            return null;
6048        }
6049        final int userId = UserHandle.getCallingUserId();
6050        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6051        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6052                userId);
6053        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6054                false, false, false, userId);
6055    }
6056
6057    /**
6058     * Returns whether or not instant apps have been disabled remotely.
6059     */
6060    private boolean isEphemeralDisabled() {
6061        return mEphemeralAppsDisabled;
6062    }
6063
6064    private boolean isInstantAppAllowed(
6065            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6066            boolean skipPackageCheck) {
6067        if (mInstantAppResolverConnection == null) {
6068            return false;
6069        }
6070        if (mInstantAppInstallerActivity == null) {
6071            return false;
6072        }
6073        if (intent.getComponent() != null) {
6074            return false;
6075        }
6076        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6077            return false;
6078        }
6079        if (!skipPackageCheck && intent.getPackage() != null) {
6080            return false;
6081        }
6082        final boolean isWebUri = hasWebURI(intent);
6083        if (!isWebUri || intent.getData().getHost() == null) {
6084            return false;
6085        }
6086        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6087        // Or if there's already an ephemeral app installed that handles the action
6088        synchronized (mPackages) {
6089            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6090            for (int n = 0; n < count; n++) {
6091                final ResolveInfo info = resolvedActivities.get(n);
6092                final String packageName = info.activityInfo.packageName;
6093                final PackageSetting ps = mSettings.mPackages.get(packageName);
6094                if (ps != null) {
6095                    // only check domain verification status if the app is not a browser
6096                    if (!info.handleAllWebDataURI) {
6097                        // Try to get the status from User settings first
6098                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6099                        final int status = (int) (packedStatus >> 32);
6100                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6101                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6102                            if (DEBUG_EPHEMERAL) {
6103                                Slog.v(TAG, "DENY instant app;"
6104                                    + " pkg: " + packageName + ", status: " + status);
6105                            }
6106                            return false;
6107                        }
6108                    }
6109                    if (ps.getInstantApp(userId)) {
6110                        if (DEBUG_EPHEMERAL) {
6111                            Slog.v(TAG, "DENY instant app installed;"
6112                                    + " pkg: " + packageName);
6113                        }
6114                        return false;
6115                    }
6116                }
6117            }
6118        }
6119        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6120        return true;
6121    }
6122
6123    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6124            Intent origIntent, String resolvedType, String callingPackage,
6125            Bundle verificationBundle, int userId) {
6126        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6127                new InstantAppRequest(responseObj, origIntent, resolvedType,
6128                        callingPackage, userId, verificationBundle));
6129        mHandler.sendMessage(msg);
6130    }
6131
6132    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6133            int flags, List<ResolveInfo> query, int userId) {
6134        if (query != null) {
6135            final int N = query.size();
6136            if (N == 1) {
6137                return query.get(0);
6138            } else if (N > 1) {
6139                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6140                // If there is more than one activity with the same priority,
6141                // then let the user decide between them.
6142                ResolveInfo r0 = query.get(0);
6143                ResolveInfo r1 = query.get(1);
6144                if (DEBUG_INTENT_MATCHING || debug) {
6145                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6146                            + r1.activityInfo.name + "=" + r1.priority);
6147                }
6148                // If the first activity has a higher priority, or a different
6149                // default, then it is always desirable to pick it.
6150                if (r0.priority != r1.priority
6151                        || r0.preferredOrder != r1.preferredOrder
6152                        || r0.isDefault != r1.isDefault) {
6153                    return query.get(0);
6154                }
6155                // If we have saved a preference for a preferred activity for
6156                // this Intent, use that.
6157                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6158                        flags, query, r0.priority, true, false, debug, userId);
6159                if (ri != null) {
6160                    return ri;
6161                }
6162                // If we have an ephemeral app, use it
6163                for (int i = 0; i < N; i++) {
6164                    ri = query.get(i);
6165                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6166                        final String packageName = ri.activityInfo.packageName;
6167                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6168                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6169                        final int status = (int)(packedStatus >> 32);
6170                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6171                            return ri;
6172                        }
6173                    }
6174                }
6175                ri = new ResolveInfo(mResolveInfo);
6176                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6177                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6178                // If all of the options come from the same package, show the application's
6179                // label and icon instead of the generic resolver's.
6180                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6181                // and then throw away the ResolveInfo itself, meaning that the caller loses
6182                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6183                // a fallback for this case; we only set the target package's resources on
6184                // the ResolveInfo, not the ActivityInfo.
6185                final String intentPackage = intent.getPackage();
6186                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6187                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6188                    ri.resolvePackageName = intentPackage;
6189                    if (userNeedsBadging(userId)) {
6190                        ri.noResourceId = true;
6191                    } else {
6192                        ri.icon = appi.icon;
6193                    }
6194                    ri.iconResourceId = appi.icon;
6195                    ri.labelRes = appi.labelRes;
6196                }
6197                ri.activityInfo.applicationInfo = new ApplicationInfo(
6198                        ri.activityInfo.applicationInfo);
6199                if (userId != 0) {
6200                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6201                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6202                }
6203                // Make sure that the resolver is displayable in car mode
6204                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6205                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6206                return ri;
6207            }
6208        }
6209        return null;
6210    }
6211
6212    /**
6213     * Return true if the given list is not empty and all of its contents have
6214     * an activityInfo with the given package name.
6215     */
6216    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6217        if (ArrayUtils.isEmpty(list)) {
6218            return false;
6219        }
6220        for (int i = 0, N = list.size(); i < N; i++) {
6221            final ResolveInfo ri = list.get(i);
6222            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6223            if (ai == null || !packageName.equals(ai.packageName)) {
6224                return false;
6225            }
6226        }
6227        return true;
6228    }
6229
6230    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6231            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6232        final int N = query.size();
6233        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6234                .get(userId);
6235        // Get the list of persistent preferred activities that handle the intent
6236        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6237        List<PersistentPreferredActivity> pprefs = ppir != null
6238                ? ppir.queryIntent(intent, resolvedType,
6239                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6240                        userId)
6241                : null;
6242        if (pprefs != null && pprefs.size() > 0) {
6243            final int M = pprefs.size();
6244            for (int i=0; i<M; i++) {
6245                final PersistentPreferredActivity ppa = pprefs.get(i);
6246                if (DEBUG_PREFERRED || debug) {
6247                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6248                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6249                            + "\n  component=" + ppa.mComponent);
6250                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6251                }
6252                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6253                        flags | MATCH_DISABLED_COMPONENTS, userId);
6254                if (DEBUG_PREFERRED || debug) {
6255                    Slog.v(TAG, "Found persistent preferred activity:");
6256                    if (ai != null) {
6257                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6258                    } else {
6259                        Slog.v(TAG, "  null");
6260                    }
6261                }
6262                if (ai == null) {
6263                    // This previously registered persistent preferred activity
6264                    // component is no longer known. Ignore it and do NOT remove it.
6265                    continue;
6266                }
6267                for (int j=0; j<N; j++) {
6268                    final ResolveInfo ri = query.get(j);
6269                    if (!ri.activityInfo.applicationInfo.packageName
6270                            .equals(ai.applicationInfo.packageName)) {
6271                        continue;
6272                    }
6273                    if (!ri.activityInfo.name.equals(ai.name)) {
6274                        continue;
6275                    }
6276                    //  Found a persistent preference that can handle the intent.
6277                    if (DEBUG_PREFERRED || debug) {
6278                        Slog.v(TAG, "Returning persistent preferred activity: " +
6279                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6280                    }
6281                    return ri;
6282                }
6283            }
6284        }
6285        return null;
6286    }
6287
6288    // TODO: handle preferred activities missing while user has amnesia
6289    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6290            List<ResolveInfo> query, int priority, boolean always,
6291            boolean removeMatches, boolean debug, int userId) {
6292        if (!sUserManager.exists(userId)) return null;
6293        final int callingUid = Binder.getCallingUid();
6294        flags = updateFlagsForResolve(
6295                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6296        intent = updateIntentForResolve(intent);
6297        // writer
6298        synchronized (mPackages) {
6299            // Try to find a matching persistent preferred activity.
6300            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6301                    debug, userId);
6302
6303            // If a persistent preferred activity matched, use it.
6304            if (pri != null) {
6305                return pri;
6306            }
6307
6308            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6309            // Get the list of preferred activities that handle the intent
6310            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6311            List<PreferredActivity> prefs = pir != null
6312                    ? pir.queryIntent(intent, resolvedType,
6313                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6314                            userId)
6315                    : null;
6316            if (prefs != null && prefs.size() > 0) {
6317                boolean changed = false;
6318                try {
6319                    // First figure out how good the original match set is.
6320                    // We will only allow preferred activities that came
6321                    // from the same match quality.
6322                    int match = 0;
6323
6324                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6325
6326                    final int N = query.size();
6327                    for (int j=0; j<N; j++) {
6328                        final ResolveInfo ri = query.get(j);
6329                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6330                                + ": 0x" + Integer.toHexString(match));
6331                        if (ri.match > match) {
6332                            match = ri.match;
6333                        }
6334                    }
6335
6336                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6337                            + Integer.toHexString(match));
6338
6339                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6340                    final int M = prefs.size();
6341                    for (int i=0; i<M; i++) {
6342                        final PreferredActivity pa = prefs.get(i);
6343                        if (DEBUG_PREFERRED || debug) {
6344                            Slog.v(TAG, "Checking PreferredActivity ds="
6345                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6346                                    + "\n  component=" + pa.mPref.mComponent);
6347                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6348                        }
6349                        if (pa.mPref.mMatch != match) {
6350                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6351                                    + Integer.toHexString(pa.mPref.mMatch));
6352                            continue;
6353                        }
6354                        // If it's not an "always" type preferred activity and that's what we're
6355                        // looking for, skip it.
6356                        if (always && !pa.mPref.mAlways) {
6357                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6358                            continue;
6359                        }
6360                        final ActivityInfo ai = getActivityInfo(
6361                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6362                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6363                                userId);
6364                        if (DEBUG_PREFERRED || debug) {
6365                            Slog.v(TAG, "Found preferred activity:");
6366                            if (ai != null) {
6367                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6368                            } else {
6369                                Slog.v(TAG, "  null");
6370                            }
6371                        }
6372                        if (ai == null) {
6373                            // This previously registered preferred activity
6374                            // component is no longer known.  Most likely an update
6375                            // to the app was installed and in the new version this
6376                            // component no longer exists.  Clean it up by removing
6377                            // it from the preferred activities list, and skip it.
6378                            Slog.w(TAG, "Removing dangling preferred activity: "
6379                                    + pa.mPref.mComponent);
6380                            pir.removeFilter(pa);
6381                            changed = true;
6382                            continue;
6383                        }
6384                        for (int j=0; j<N; j++) {
6385                            final ResolveInfo ri = query.get(j);
6386                            if (!ri.activityInfo.applicationInfo.packageName
6387                                    .equals(ai.applicationInfo.packageName)) {
6388                                continue;
6389                            }
6390                            if (!ri.activityInfo.name.equals(ai.name)) {
6391                                continue;
6392                            }
6393
6394                            if (removeMatches) {
6395                                pir.removeFilter(pa);
6396                                changed = true;
6397                                if (DEBUG_PREFERRED) {
6398                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6399                                }
6400                                break;
6401                            }
6402
6403                            // Okay we found a previously set preferred or last chosen app.
6404                            // If the result set is different from when this
6405                            // was created, we need to clear it and re-ask the
6406                            // user their preference, if we're looking for an "always" type entry.
6407                            if (always && !pa.mPref.sameSet(query)) {
6408                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6409                                        + intent + " type " + resolvedType);
6410                                if (DEBUG_PREFERRED) {
6411                                    Slog.v(TAG, "Removing preferred activity since set changed "
6412                                            + pa.mPref.mComponent);
6413                                }
6414                                pir.removeFilter(pa);
6415                                // Re-add the filter as a "last chosen" entry (!always)
6416                                PreferredActivity lastChosen = new PreferredActivity(
6417                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6418                                pir.addFilter(lastChosen);
6419                                changed = true;
6420                                return null;
6421                            }
6422
6423                            // Yay! Either the set matched or we're looking for the last chosen
6424                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6425                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6426                            return ri;
6427                        }
6428                    }
6429                } finally {
6430                    if (changed) {
6431                        if (DEBUG_PREFERRED) {
6432                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6433                        }
6434                        scheduleWritePackageRestrictionsLocked(userId);
6435                    }
6436                }
6437            }
6438        }
6439        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6440        return null;
6441    }
6442
6443    /*
6444     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6445     */
6446    @Override
6447    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6448            int targetUserId) {
6449        mContext.enforceCallingOrSelfPermission(
6450                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6451        List<CrossProfileIntentFilter> matches =
6452                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6453        if (matches != null) {
6454            int size = matches.size();
6455            for (int i = 0; i < size; i++) {
6456                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6457            }
6458        }
6459        if (hasWebURI(intent)) {
6460            // cross-profile app linking works only towards the parent.
6461            final int callingUid = Binder.getCallingUid();
6462            final UserInfo parent = getProfileParent(sourceUserId);
6463            synchronized(mPackages) {
6464                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6465                        false /*includeInstantApps*/);
6466                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6467                        intent, resolvedType, flags, sourceUserId, parent.id);
6468                return xpDomainInfo != null;
6469            }
6470        }
6471        return false;
6472    }
6473
6474    private UserInfo getProfileParent(int userId) {
6475        final long identity = Binder.clearCallingIdentity();
6476        try {
6477            return sUserManager.getProfileParent(userId);
6478        } finally {
6479            Binder.restoreCallingIdentity(identity);
6480        }
6481    }
6482
6483    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6484            String resolvedType, int userId) {
6485        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6486        if (resolver != null) {
6487            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6488        }
6489        return null;
6490    }
6491
6492    @Override
6493    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6494            String resolvedType, int flags, int userId) {
6495        try {
6496            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6497
6498            return new ParceledListSlice<>(
6499                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6500        } finally {
6501            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6502        }
6503    }
6504
6505    /**
6506     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6507     * instant, returns {@code null}.
6508     */
6509    private String getInstantAppPackageName(int callingUid) {
6510        synchronized (mPackages) {
6511            // If the caller is an isolated app use the owner's uid for the lookup.
6512            if (Process.isIsolated(callingUid)) {
6513                callingUid = mIsolatedOwners.get(callingUid);
6514            }
6515            final int appId = UserHandle.getAppId(callingUid);
6516            final Object obj = mSettings.getUserIdLPr(appId);
6517            if (obj instanceof PackageSetting) {
6518                final PackageSetting ps = (PackageSetting) obj;
6519                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6520                return isInstantApp ? ps.pkg.packageName : null;
6521            }
6522        }
6523        return null;
6524    }
6525
6526    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6527            String resolvedType, int flags, int userId) {
6528        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6529    }
6530
6531    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6532            String resolvedType, int flags, int userId, boolean resolveForStart) {
6533        if (!sUserManager.exists(userId)) return Collections.emptyList();
6534        final int callingUid = Binder.getCallingUid();
6535        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6536        enforceCrossUserPermission(callingUid, userId,
6537                false /* requireFullPermission */, false /* checkShell */,
6538                "query intent activities");
6539        final String pkgName = intent.getPackage();
6540        ComponentName comp = intent.getComponent();
6541        if (comp == null) {
6542            if (intent.getSelector() != null) {
6543                intent = intent.getSelector();
6544                comp = intent.getComponent();
6545            }
6546        }
6547
6548        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
6549                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6550        if (comp != null) {
6551            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6552            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6553            if (ai != null) {
6554                // When specifying an explicit component, we prevent the activity from being
6555                // used when either 1) the calling package is normal and the activity is within
6556                // an ephemeral application or 2) the calling package is ephemeral and the
6557                // activity is not visible to ephemeral applications.
6558                final boolean matchInstantApp =
6559                        (flags & PackageManager.MATCH_INSTANT) != 0;
6560                final boolean matchVisibleToInstantAppOnly =
6561                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6562                final boolean matchExplicitlyVisibleOnly =
6563                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6564                final boolean isCallerInstantApp =
6565                        instantAppPkgName != null;
6566                final boolean isTargetSameInstantApp =
6567                        comp.getPackageName().equals(instantAppPkgName);
6568                final boolean isTargetInstantApp =
6569                        (ai.applicationInfo.privateFlags
6570                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6571                final boolean isTargetVisibleToInstantApp =
6572                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6573                final boolean isTargetExplicitlyVisibleToInstantApp =
6574                        isTargetVisibleToInstantApp
6575                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6576                final boolean isTargetHiddenFromInstantApp =
6577                        !isTargetVisibleToInstantApp
6578                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6579                final boolean blockResolution =
6580                        !isTargetSameInstantApp
6581                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6582                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6583                                        && isTargetHiddenFromInstantApp));
6584                if (!blockResolution) {
6585                    final ResolveInfo ri = new ResolveInfo();
6586                    ri.activityInfo = ai;
6587                    list.add(ri);
6588                }
6589            }
6590            return applyPostResolutionFilter(list, instantAppPkgName);
6591        }
6592
6593        // reader
6594        boolean sortResult = false;
6595        boolean addEphemeral = false;
6596        List<ResolveInfo> result;
6597        final boolean ephemeralDisabled = isEphemeralDisabled();
6598        synchronized (mPackages) {
6599            if (pkgName == null) {
6600                List<CrossProfileIntentFilter> matchingFilters =
6601                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6602                // Check for results that need to skip the current profile.
6603                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6604                        resolvedType, flags, userId);
6605                if (xpResolveInfo != null) {
6606                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6607                    xpResult.add(xpResolveInfo);
6608                    return applyPostResolutionFilter(
6609                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6610                }
6611
6612                // Check for results in the current profile.
6613                result = filterIfNotSystemUser(mActivities.queryIntent(
6614                        intent, resolvedType, flags, userId), userId);
6615                addEphemeral = !ephemeralDisabled
6616                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6617                // Check for cross profile results.
6618                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6619                xpResolveInfo = queryCrossProfileIntents(
6620                        matchingFilters, intent, resolvedType, flags, userId,
6621                        hasNonNegativePriorityResult);
6622                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6623                    boolean isVisibleToUser = filterIfNotSystemUser(
6624                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6625                    if (isVisibleToUser) {
6626                        result.add(xpResolveInfo);
6627                        sortResult = true;
6628                    }
6629                }
6630                if (hasWebURI(intent)) {
6631                    CrossProfileDomainInfo xpDomainInfo = null;
6632                    final UserInfo parent = getProfileParent(userId);
6633                    if (parent != null) {
6634                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6635                                flags, userId, parent.id);
6636                    }
6637                    if (xpDomainInfo != null) {
6638                        if (xpResolveInfo != null) {
6639                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6640                            // in the result.
6641                            result.remove(xpResolveInfo);
6642                        }
6643                        if (result.size() == 0 && !addEphemeral) {
6644                            // No result in current profile, but found candidate in parent user.
6645                            // And we are not going to add emphemeral app, so we can return the
6646                            // result straight away.
6647                            result.add(xpDomainInfo.resolveInfo);
6648                            return applyPostResolutionFilter(result, instantAppPkgName);
6649                        }
6650                    } else if (result.size() <= 1 && !addEphemeral) {
6651                        // No result in parent user and <= 1 result in current profile, and we
6652                        // are not going to add emphemeral app, so we can return the result without
6653                        // further processing.
6654                        return applyPostResolutionFilter(result, instantAppPkgName);
6655                    }
6656                    // We have more than one candidate (combining results from current and parent
6657                    // profile), so we need filtering and sorting.
6658                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6659                            intent, flags, result, xpDomainInfo, userId);
6660                    sortResult = true;
6661                }
6662            } else {
6663                final PackageParser.Package pkg = mPackages.get(pkgName);
6664                result = null;
6665                if (pkg != null) {
6666                    result = filterIfNotSystemUser(
6667                            mActivities.queryIntentForPackage(
6668                                    intent, resolvedType, flags, pkg.activities, userId),
6669                            userId);
6670                }
6671                if (result == null || result.size() == 0) {
6672                    // the caller wants to resolve for a particular package; however, there
6673                    // were no installed results, so, try to find an ephemeral result
6674                    addEphemeral = !ephemeralDisabled
6675                            && isInstantAppAllowed(
6676                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6677                    if (result == null) {
6678                        result = new ArrayList<>();
6679                    }
6680                }
6681            }
6682        }
6683        if (addEphemeral) {
6684            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
6685        }
6686        if (sortResult) {
6687            Collections.sort(result, mResolvePrioritySorter);
6688        }
6689        return applyPostResolutionFilter(result, instantAppPkgName);
6690    }
6691
6692    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6693            String resolvedType, int flags, int userId) {
6694        // first, check to see if we've got an instant app already installed
6695        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6696        ResolveInfo localInstantApp = null;
6697        boolean blockResolution = false;
6698        if (!alreadyResolvedLocally) {
6699            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6700                    flags
6701                        | PackageManager.GET_RESOLVED_FILTER
6702                        | PackageManager.MATCH_INSTANT
6703                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6704                    userId);
6705            for (int i = instantApps.size() - 1; i >= 0; --i) {
6706                final ResolveInfo info = instantApps.get(i);
6707                final String packageName = info.activityInfo.packageName;
6708                final PackageSetting ps = mSettings.mPackages.get(packageName);
6709                if (ps.getInstantApp(userId)) {
6710                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6711                    final int status = (int)(packedStatus >> 32);
6712                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6713                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6714                        // there's a local instant application installed, but, the user has
6715                        // chosen to never use it; skip resolution and don't acknowledge
6716                        // an instant application is even available
6717                        if (DEBUG_EPHEMERAL) {
6718                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6719                        }
6720                        blockResolution = true;
6721                        break;
6722                    } else {
6723                        // we have a locally installed instant application; skip resolution
6724                        // but acknowledge there's an instant application available
6725                        if (DEBUG_EPHEMERAL) {
6726                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6727                        }
6728                        localInstantApp = info;
6729                        break;
6730                    }
6731                }
6732            }
6733        }
6734        // no app installed, let's see if one's available
6735        AuxiliaryResolveInfo auxiliaryResponse = null;
6736        if (!blockResolution) {
6737            if (localInstantApp == null) {
6738                // we don't have an instant app locally, resolve externally
6739                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6740                final InstantAppRequest requestObject = new InstantAppRequest(
6741                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6742                        null /*callingPackage*/, userId, null /*verificationBundle*/);
6743                auxiliaryResponse =
6744                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6745                                mContext, mInstantAppResolverConnection, requestObject);
6746                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6747            } else {
6748                // we have an instant application locally, but, we can't admit that since
6749                // callers shouldn't be able to determine prior browsing. create a dummy
6750                // auxiliary response so the downstream code behaves as if there's an
6751                // instant application available externally. when it comes time to start
6752                // the instant application, we'll do the right thing.
6753                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6754                auxiliaryResponse = new AuxiliaryResolveInfo(
6755                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
6756            }
6757        }
6758        if (auxiliaryResponse != null) {
6759            if (DEBUG_EPHEMERAL) {
6760                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6761            }
6762            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6763            final PackageSetting ps =
6764                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6765            if (ps != null) {
6766                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6767                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6768                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6769                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6770                // make sure this resolver is the default
6771                ephemeralInstaller.isDefault = true;
6772                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6773                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6774                // add a non-generic filter
6775                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6776                ephemeralInstaller.filter.addDataPath(
6777                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6778                ephemeralInstaller.isInstantAppAvailable = true;
6779                result.add(ephemeralInstaller);
6780            }
6781        }
6782        return result;
6783    }
6784
6785    private static class CrossProfileDomainInfo {
6786        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6787        ResolveInfo resolveInfo;
6788        /* Best domain verification status of the activities found in the other profile */
6789        int bestDomainVerificationStatus;
6790    }
6791
6792    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6793            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6794        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6795                sourceUserId)) {
6796            return null;
6797        }
6798        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6799                resolvedType, flags, parentUserId);
6800
6801        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6802            return null;
6803        }
6804        CrossProfileDomainInfo result = null;
6805        int size = resultTargetUser.size();
6806        for (int i = 0; i < size; i++) {
6807            ResolveInfo riTargetUser = resultTargetUser.get(i);
6808            // Intent filter verification is only for filters that specify a host. So don't return
6809            // those that handle all web uris.
6810            if (riTargetUser.handleAllWebDataURI) {
6811                continue;
6812            }
6813            String packageName = riTargetUser.activityInfo.packageName;
6814            PackageSetting ps = mSettings.mPackages.get(packageName);
6815            if (ps == null) {
6816                continue;
6817            }
6818            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6819            int status = (int)(verificationState >> 32);
6820            if (result == null) {
6821                result = new CrossProfileDomainInfo();
6822                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6823                        sourceUserId, parentUserId);
6824                result.bestDomainVerificationStatus = status;
6825            } else {
6826                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6827                        result.bestDomainVerificationStatus);
6828            }
6829        }
6830        // Don't consider matches with status NEVER across profiles.
6831        if (result != null && result.bestDomainVerificationStatus
6832                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6833            return null;
6834        }
6835        return result;
6836    }
6837
6838    /**
6839     * Verification statuses are ordered from the worse to the best, except for
6840     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6841     */
6842    private int bestDomainVerificationStatus(int status1, int status2) {
6843        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6844            return status2;
6845        }
6846        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6847            return status1;
6848        }
6849        return (int) MathUtils.max(status1, status2);
6850    }
6851
6852    private boolean isUserEnabled(int userId) {
6853        long callingId = Binder.clearCallingIdentity();
6854        try {
6855            UserInfo userInfo = sUserManager.getUserInfo(userId);
6856            return userInfo != null && userInfo.isEnabled();
6857        } finally {
6858            Binder.restoreCallingIdentity(callingId);
6859        }
6860    }
6861
6862    /**
6863     * Filter out activities with systemUserOnly flag set, when current user is not System.
6864     *
6865     * @return filtered list
6866     */
6867    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6868        if (userId == UserHandle.USER_SYSTEM) {
6869            return resolveInfos;
6870        }
6871        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6872            ResolveInfo info = resolveInfos.get(i);
6873            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6874                resolveInfos.remove(i);
6875            }
6876        }
6877        return resolveInfos;
6878    }
6879
6880    /**
6881     * Filters out ephemeral activities.
6882     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6883     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6884     *
6885     * @param resolveInfos The pre-filtered list of resolved activities
6886     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6887     *          is performed.
6888     * @return A filtered list of resolved activities.
6889     */
6890    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6891            String ephemeralPkgName) {
6892        // TODO: When adding on-demand split support for non-instant apps, remove this check
6893        // and always apply post filtering
6894        if (ephemeralPkgName == null) {
6895            return resolveInfos;
6896        }
6897        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6898            final ResolveInfo info = resolveInfos.get(i);
6899            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6900            // allow activities that are defined in the provided package
6901            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6902                if (info.activityInfo.splitName != null
6903                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6904                                info.activityInfo.splitName)) {
6905                    // requested activity is defined in a split that hasn't been installed yet.
6906                    // add the installer to the resolve list
6907                    if (DEBUG_EPHEMERAL) {
6908                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6909                    }
6910                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6911                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6912                            info.activityInfo.packageName, info.activityInfo.splitName,
6913                            info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
6914                    // make sure this resolver is the default
6915                    installerInfo.isDefault = true;
6916                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6917                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6918                    // add a non-generic filter
6919                    installerInfo.filter = new IntentFilter();
6920                    // load resources from the correct package
6921                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6922                    resolveInfos.set(i, installerInfo);
6923                }
6924                continue;
6925            }
6926            // allow activities that have been explicitly exposed to ephemeral apps
6927            if (!isEphemeralApp
6928                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6929                continue;
6930            }
6931            resolveInfos.remove(i);
6932        }
6933        return resolveInfos;
6934    }
6935
6936    /**
6937     * @param resolveInfos list of resolve infos in descending priority order
6938     * @return if the list contains a resolve info with non-negative priority
6939     */
6940    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6941        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6942    }
6943
6944    private static boolean hasWebURI(Intent intent) {
6945        if (intent.getData() == null) {
6946            return false;
6947        }
6948        final String scheme = intent.getScheme();
6949        if (TextUtils.isEmpty(scheme)) {
6950            return false;
6951        }
6952        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6953    }
6954
6955    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6956            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6957            int userId) {
6958        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6959
6960        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6961            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6962                    candidates.size());
6963        }
6964
6965        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6966        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6967        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6968        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6969        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6970        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6971
6972        synchronized (mPackages) {
6973            final int count = candidates.size();
6974            // First, try to use linked apps. Partition the candidates into four lists:
6975            // one for the final results, one for the "do not use ever", one for "undefined status"
6976            // and finally one for "browser app type".
6977            for (int n=0; n<count; n++) {
6978                ResolveInfo info = candidates.get(n);
6979                String packageName = info.activityInfo.packageName;
6980                PackageSetting ps = mSettings.mPackages.get(packageName);
6981                if (ps != null) {
6982                    // Add to the special match all list (Browser use case)
6983                    if (info.handleAllWebDataURI) {
6984                        matchAllList.add(info);
6985                        continue;
6986                    }
6987                    // Try to get the status from User settings first
6988                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6989                    int status = (int)(packedStatus >> 32);
6990                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6991                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6992                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6993                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6994                                    + " : linkgen=" + linkGeneration);
6995                        }
6996                        // Use link-enabled generation as preferredOrder, i.e.
6997                        // prefer newly-enabled over earlier-enabled.
6998                        info.preferredOrder = linkGeneration;
6999                        alwaysList.add(info);
7000                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7001                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7002                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7003                        }
7004                        neverList.add(info);
7005                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7006                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7007                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7008                        }
7009                        alwaysAskList.add(info);
7010                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7011                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7012                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7013                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7014                        }
7015                        undefinedList.add(info);
7016                    }
7017                }
7018            }
7019
7020            // We'll want to include browser possibilities in a few cases
7021            boolean includeBrowser = false;
7022
7023            // First try to add the "always" resolution(s) for the current user, if any
7024            if (alwaysList.size() > 0) {
7025                result.addAll(alwaysList);
7026            } else {
7027                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7028                result.addAll(undefinedList);
7029                // Maybe add one for the other profile.
7030                if (xpDomainInfo != null && (
7031                        xpDomainInfo.bestDomainVerificationStatus
7032                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7033                    result.add(xpDomainInfo.resolveInfo);
7034                }
7035                includeBrowser = true;
7036            }
7037
7038            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7039            // If there were 'always' entries their preferred order has been set, so we also
7040            // back that off to make the alternatives equivalent
7041            if (alwaysAskList.size() > 0) {
7042                for (ResolveInfo i : result) {
7043                    i.preferredOrder = 0;
7044                }
7045                result.addAll(alwaysAskList);
7046                includeBrowser = true;
7047            }
7048
7049            if (includeBrowser) {
7050                // Also add browsers (all of them or only the default one)
7051                if (DEBUG_DOMAIN_VERIFICATION) {
7052                    Slog.v(TAG, "   ...including browsers in candidate set");
7053                }
7054                if ((matchFlags & MATCH_ALL) != 0) {
7055                    result.addAll(matchAllList);
7056                } else {
7057                    // Browser/generic handling case.  If there's a default browser, go straight
7058                    // to that (but only if there is no other higher-priority match).
7059                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7060                    int maxMatchPrio = 0;
7061                    ResolveInfo defaultBrowserMatch = null;
7062                    final int numCandidates = matchAllList.size();
7063                    for (int n = 0; n < numCandidates; n++) {
7064                        ResolveInfo info = matchAllList.get(n);
7065                        // track the highest overall match priority...
7066                        if (info.priority > maxMatchPrio) {
7067                            maxMatchPrio = info.priority;
7068                        }
7069                        // ...and the highest-priority default browser match
7070                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7071                            if (defaultBrowserMatch == null
7072                                    || (defaultBrowserMatch.priority < info.priority)) {
7073                                if (debug) {
7074                                    Slog.v(TAG, "Considering default browser match " + info);
7075                                }
7076                                defaultBrowserMatch = info;
7077                            }
7078                        }
7079                    }
7080                    if (defaultBrowserMatch != null
7081                            && defaultBrowserMatch.priority >= maxMatchPrio
7082                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7083                    {
7084                        if (debug) {
7085                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7086                        }
7087                        result.add(defaultBrowserMatch);
7088                    } else {
7089                        result.addAll(matchAllList);
7090                    }
7091                }
7092
7093                // If there is nothing selected, add all candidates and remove the ones that the user
7094                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7095                if (result.size() == 0) {
7096                    result.addAll(candidates);
7097                    result.removeAll(neverList);
7098                }
7099            }
7100        }
7101        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7102            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7103                    result.size());
7104            for (ResolveInfo info : result) {
7105                Slog.v(TAG, "  + " + info.activityInfo);
7106            }
7107        }
7108        return result;
7109    }
7110
7111    // Returns a packed value as a long:
7112    //
7113    // high 'int'-sized word: link status: undefined/ask/never/always.
7114    // low 'int'-sized word: relative priority among 'always' results.
7115    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7116        long result = ps.getDomainVerificationStatusForUser(userId);
7117        // if none available, get the master status
7118        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7119            if (ps.getIntentFilterVerificationInfo() != null) {
7120                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7121            }
7122        }
7123        return result;
7124    }
7125
7126    private ResolveInfo querySkipCurrentProfileIntents(
7127            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7128            int flags, int sourceUserId) {
7129        if (matchingFilters != null) {
7130            int size = matchingFilters.size();
7131            for (int i = 0; i < size; i ++) {
7132                CrossProfileIntentFilter filter = matchingFilters.get(i);
7133                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7134                    // Checking if there are activities in the target user that can handle the
7135                    // intent.
7136                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7137                            resolvedType, flags, sourceUserId);
7138                    if (resolveInfo != null) {
7139                        return resolveInfo;
7140                    }
7141                }
7142            }
7143        }
7144        return null;
7145    }
7146
7147    // Return matching ResolveInfo in target user if any.
7148    private ResolveInfo queryCrossProfileIntents(
7149            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7150            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7151        if (matchingFilters != null) {
7152            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7153            // match the same intent. For performance reasons, it is better not to
7154            // run queryIntent twice for the same userId
7155            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7156            int size = matchingFilters.size();
7157            for (int i = 0; i < size; i++) {
7158                CrossProfileIntentFilter filter = matchingFilters.get(i);
7159                int targetUserId = filter.getTargetUserId();
7160                boolean skipCurrentProfile =
7161                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7162                boolean skipCurrentProfileIfNoMatchFound =
7163                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7164                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7165                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7166                    // Checking if there are activities in the target user that can handle the
7167                    // intent.
7168                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7169                            resolvedType, flags, sourceUserId);
7170                    if (resolveInfo != null) return resolveInfo;
7171                    alreadyTriedUserIds.put(targetUserId, true);
7172                }
7173            }
7174        }
7175        return null;
7176    }
7177
7178    /**
7179     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7180     * will forward the intent to the filter's target user.
7181     * Otherwise, returns null.
7182     */
7183    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7184            String resolvedType, int flags, int sourceUserId) {
7185        int targetUserId = filter.getTargetUserId();
7186        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7187                resolvedType, flags, targetUserId);
7188        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7189            // If all the matches in the target profile are suspended, return null.
7190            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7191                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7192                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7193                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7194                            targetUserId);
7195                }
7196            }
7197        }
7198        return null;
7199    }
7200
7201    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7202            int sourceUserId, int targetUserId) {
7203        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7204        long ident = Binder.clearCallingIdentity();
7205        boolean targetIsProfile;
7206        try {
7207            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7208        } finally {
7209            Binder.restoreCallingIdentity(ident);
7210        }
7211        String className;
7212        if (targetIsProfile) {
7213            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7214        } else {
7215            className = FORWARD_INTENT_TO_PARENT;
7216        }
7217        ComponentName forwardingActivityComponentName = new ComponentName(
7218                mAndroidApplication.packageName, className);
7219        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7220                sourceUserId);
7221        if (!targetIsProfile) {
7222            forwardingActivityInfo.showUserIcon = targetUserId;
7223            forwardingResolveInfo.noResourceId = true;
7224        }
7225        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7226        forwardingResolveInfo.priority = 0;
7227        forwardingResolveInfo.preferredOrder = 0;
7228        forwardingResolveInfo.match = 0;
7229        forwardingResolveInfo.isDefault = true;
7230        forwardingResolveInfo.filter = filter;
7231        forwardingResolveInfo.targetUserId = targetUserId;
7232        return forwardingResolveInfo;
7233    }
7234
7235    @Override
7236    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7237            Intent[] specifics, String[] specificTypes, Intent intent,
7238            String resolvedType, int flags, int userId) {
7239        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7240                specificTypes, intent, resolvedType, flags, userId));
7241    }
7242
7243    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7244            Intent[] specifics, String[] specificTypes, Intent intent,
7245            String resolvedType, int flags, int userId) {
7246        if (!sUserManager.exists(userId)) return Collections.emptyList();
7247        final int callingUid = Binder.getCallingUid();
7248        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7249                false /*includeInstantApps*/);
7250        enforceCrossUserPermission(callingUid, userId,
7251                false /*requireFullPermission*/, false /*checkShell*/,
7252                "query intent activity options");
7253        final String resultsAction = intent.getAction();
7254
7255        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7256                | PackageManager.GET_RESOLVED_FILTER, userId);
7257
7258        if (DEBUG_INTENT_MATCHING) {
7259            Log.v(TAG, "Query " + intent + ": " + results);
7260        }
7261
7262        int specificsPos = 0;
7263        int N;
7264
7265        // todo: note that the algorithm used here is O(N^2).  This
7266        // isn't a problem in our current environment, but if we start running
7267        // into situations where we have more than 5 or 10 matches then this
7268        // should probably be changed to something smarter...
7269
7270        // First we go through and resolve each of the specific items
7271        // that were supplied, taking care of removing any corresponding
7272        // duplicate items in the generic resolve list.
7273        if (specifics != null) {
7274            for (int i=0; i<specifics.length; i++) {
7275                final Intent sintent = specifics[i];
7276                if (sintent == null) {
7277                    continue;
7278                }
7279
7280                if (DEBUG_INTENT_MATCHING) {
7281                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7282                }
7283
7284                String action = sintent.getAction();
7285                if (resultsAction != null && resultsAction.equals(action)) {
7286                    // If this action was explicitly requested, then don't
7287                    // remove things that have it.
7288                    action = null;
7289                }
7290
7291                ResolveInfo ri = null;
7292                ActivityInfo ai = null;
7293
7294                ComponentName comp = sintent.getComponent();
7295                if (comp == null) {
7296                    ri = resolveIntent(
7297                        sintent,
7298                        specificTypes != null ? specificTypes[i] : null,
7299                            flags, userId);
7300                    if (ri == null) {
7301                        continue;
7302                    }
7303                    if (ri == mResolveInfo) {
7304                        // ACK!  Must do something better with this.
7305                    }
7306                    ai = ri.activityInfo;
7307                    comp = new ComponentName(ai.applicationInfo.packageName,
7308                            ai.name);
7309                } else {
7310                    ai = getActivityInfo(comp, flags, userId);
7311                    if (ai == null) {
7312                        continue;
7313                    }
7314                }
7315
7316                // Look for any generic query activities that are duplicates
7317                // of this specific one, and remove them from the results.
7318                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7319                N = results.size();
7320                int j;
7321                for (j=specificsPos; j<N; j++) {
7322                    ResolveInfo sri = results.get(j);
7323                    if ((sri.activityInfo.name.equals(comp.getClassName())
7324                            && sri.activityInfo.applicationInfo.packageName.equals(
7325                                    comp.getPackageName()))
7326                        || (action != null && sri.filter.matchAction(action))) {
7327                        results.remove(j);
7328                        if (DEBUG_INTENT_MATCHING) Log.v(
7329                            TAG, "Removing duplicate item from " + j
7330                            + " due to specific " + specificsPos);
7331                        if (ri == null) {
7332                            ri = sri;
7333                        }
7334                        j--;
7335                        N--;
7336                    }
7337                }
7338
7339                // Add this specific item to its proper place.
7340                if (ri == null) {
7341                    ri = new ResolveInfo();
7342                    ri.activityInfo = ai;
7343                }
7344                results.add(specificsPos, ri);
7345                ri.specificIndex = i;
7346                specificsPos++;
7347            }
7348        }
7349
7350        // Now we go through the remaining generic results and remove any
7351        // duplicate actions that are found here.
7352        N = results.size();
7353        for (int i=specificsPos; i<N-1; i++) {
7354            final ResolveInfo rii = results.get(i);
7355            if (rii.filter == null) {
7356                continue;
7357            }
7358
7359            // Iterate over all of the actions of this result's intent
7360            // filter...  typically this should be just one.
7361            final Iterator<String> it = rii.filter.actionsIterator();
7362            if (it == null) {
7363                continue;
7364            }
7365            while (it.hasNext()) {
7366                final String action = it.next();
7367                if (resultsAction != null && resultsAction.equals(action)) {
7368                    // If this action was explicitly requested, then don't
7369                    // remove things that have it.
7370                    continue;
7371                }
7372                for (int j=i+1; j<N; j++) {
7373                    final ResolveInfo rij = results.get(j);
7374                    if (rij.filter != null && rij.filter.hasAction(action)) {
7375                        results.remove(j);
7376                        if (DEBUG_INTENT_MATCHING) Log.v(
7377                            TAG, "Removing duplicate item from " + j
7378                            + " due to action " + action + " at " + i);
7379                        j--;
7380                        N--;
7381                    }
7382                }
7383            }
7384
7385            // If the caller didn't request filter information, drop it now
7386            // so we don't have to marshall/unmarshall it.
7387            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7388                rii.filter = null;
7389            }
7390        }
7391
7392        // Filter out the caller activity if so requested.
7393        if (caller != null) {
7394            N = results.size();
7395            for (int i=0; i<N; i++) {
7396                ActivityInfo ainfo = results.get(i).activityInfo;
7397                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7398                        && caller.getClassName().equals(ainfo.name)) {
7399                    results.remove(i);
7400                    break;
7401                }
7402            }
7403        }
7404
7405        // If the caller didn't request filter information,
7406        // drop them now so we don't have to
7407        // marshall/unmarshall it.
7408        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7409            N = results.size();
7410            for (int i=0; i<N; i++) {
7411                results.get(i).filter = null;
7412            }
7413        }
7414
7415        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7416        return results;
7417    }
7418
7419    @Override
7420    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7421            String resolvedType, int flags, int userId) {
7422        return new ParceledListSlice<>(
7423                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7424    }
7425
7426    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7427            String resolvedType, int flags, int userId) {
7428        if (!sUserManager.exists(userId)) return Collections.emptyList();
7429        final int callingUid = Binder.getCallingUid();
7430        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7431                false /*includeInstantApps*/);
7432        ComponentName comp = intent.getComponent();
7433        if (comp == null) {
7434            if (intent.getSelector() != null) {
7435                intent = intent.getSelector();
7436                comp = intent.getComponent();
7437            }
7438        }
7439        if (comp != null) {
7440            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7441            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7442            if (ai != null) {
7443                ResolveInfo ri = new ResolveInfo();
7444                ri.activityInfo = ai;
7445                list.add(ri);
7446            }
7447            return list;
7448        }
7449
7450        // reader
7451        synchronized (mPackages) {
7452            String pkgName = intent.getPackage();
7453            if (pkgName == null) {
7454                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7455            }
7456            final PackageParser.Package pkg = mPackages.get(pkgName);
7457            if (pkg != null) {
7458                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7459                        userId);
7460            }
7461            return Collections.emptyList();
7462        }
7463    }
7464
7465    @Override
7466    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7467        final int callingUid = Binder.getCallingUid();
7468        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7469    }
7470
7471    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7472            int userId, int callingUid) {
7473        if (!sUserManager.exists(userId)) return null;
7474        flags = updateFlagsForResolve(
7475                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7476        List<ResolveInfo> query = queryIntentServicesInternal(
7477                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7478        if (query != null) {
7479            if (query.size() >= 1) {
7480                // If there is more than one service with the same priority,
7481                // just arbitrarily pick the first one.
7482                return query.get(0);
7483            }
7484        }
7485        return null;
7486    }
7487
7488    @Override
7489    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7490            String resolvedType, int flags, int userId) {
7491        final int callingUid = Binder.getCallingUid();
7492        return new ParceledListSlice<>(queryIntentServicesInternal(
7493                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7494    }
7495
7496    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7497            String resolvedType, int flags, int userId, int callingUid,
7498            boolean includeInstantApps) {
7499        if (!sUserManager.exists(userId)) return Collections.emptyList();
7500        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7501        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7502        ComponentName comp = intent.getComponent();
7503        if (comp == null) {
7504            if (intent.getSelector() != null) {
7505                intent = intent.getSelector();
7506                comp = intent.getComponent();
7507            }
7508        }
7509        if (comp != null) {
7510            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7511            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7512            if (si != null) {
7513                // When specifying an explicit component, we prevent the service from being
7514                // used when either 1) the service is in an instant application and the
7515                // caller is not the same instant application or 2) the calling package is
7516                // ephemeral and the activity is not visible to ephemeral applications.
7517                final boolean matchInstantApp =
7518                        (flags & PackageManager.MATCH_INSTANT) != 0;
7519                final boolean matchVisibleToInstantAppOnly =
7520                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7521                final boolean isCallerInstantApp =
7522                        instantAppPkgName != null;
7523                final boolean isTargetSameInstantApp =
7524                        comp.getPackageName().equals(instantAppPkgName);
7525                final boolean isTargetInstantApp =
7526                        (si.applicationInfo.privateFlags
7527                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7528                final boolean isTargetHiddenFromInstantApp =
7529                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7530                final boolean blockResolution =
7531                        !isTargetSameInstantApp
7532                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7533                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7534                                        && isTargetHiddenFromInstantApp));
7535                if (!blockResolution) {
7536                    final ResolveInfo ri = new ResolveInfo();
7537                    ri.serviceInfo = si;
7538                    list.add(ri);
7539                }
7540            }
7541            return list;
7542        }
7543
7544        // reader
7545        synchronized (mPackages) {
7546            String pkgName = intent.getPackage();
7547            if (pkgName == null) {
7548                return applyPostServiceResolutionFilter(
7549                        mServices.queryIntent(intent, resolvedType, flags, userId),
7550                        instantAppPkgName);
7551            }
7552            final PackageParser.Package pkg = mPackages.get(pkgName);
7553            if (pkg != null) {
7554                return applyPostServiceResolutionFilter(
7555                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7556                                userId),
7557                        instantAppPkgName);
7558            }
7559            return Collections.emptyList();
7560        }
7561    }
7562
7563    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7564            String instantAppPkgName) {
7565        // TODO: When adding on-demand split support for non-instant apps, remove this check
7566        // and always apply post filtering
7567        if (instantAppPkgName == null) {
7568            return resolveInfos;
7569        }
7570        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7571            final ResolveInfo info = resolveInfos.get(i);
7572            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7573            // allow services that are defined in the provided package
7574            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7575                if (info.serviceInfo.splitName != null
7576                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7577                                info.serviceInfo.splitName)) {
7578                    // requested service is defined in a split that hasn't been installed yet.
7579                    // add the installer to the resolve list
7580                    if (DEBUG_EPHEMERAL) {
7581                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7582                    }
7583                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7584                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7585                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7586                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
7587                    // make sure this resolver is the default
7588                    installerInfo.isDefault = true;
7589                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7590                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7591                    // add a non-generic filter
7592                    installerInfo.filter = new IntentFilter();
7593                    // load resources from the correct package
7594                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7595                    resolveInfos.set(i, installerInfo);
7596                }
7597                continue;
7598            }
7599            // allow services that have been explicitly exposed to ephemeral apps
7600            if (!isEphemeralApp
7601                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7602                continue;
7603            }
7604            resolveInfos.remove(i);
7605        }
7606        return resolveInfos;
7607    }
7608
7609    @Override
7610    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7611            String resolvedType, int flags, int userId) {
7612        return new ParceledListSlice<>(
7613                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7614    }
7615
7616    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7617            Intent intent, 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 ProviderInfo pi = getProviderInfo(comp, flags, userId);
7633            if (pi != null) {
7634                // When specifying an explicit component, we prevent the provider from being
7635                // used when either 1) the provider is in an instant application and the
7636                // caller is not the same instant application or 2) the calling package is an
7637                // instant application and the provider 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 isCallerInstantApp =
7643                        instantAppPkgName != null;
7644                final boolean isTargetSameInstantApp =
7645                        comp.getPackageName().equals(instantAppPkgName);
7646                final boolean isTargetInstantApp =
7647                        (pi.applicationInfo.privateFlags
7648                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7649                final boolean isTargetHiddenFromInstantApp =
7650                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7651                final boolean blockResolution =
7652                        !isTargetSameInstantApp
7653                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7654                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7655                                        && isTargetHiddenFromInstantApp));
7656                if (!blockResolution) {
7657                    final ResolveInfo ri = new ResolveInfo();
7658                    ri.providerInfo = pi;
7659                    list.add(ri);
7660                }
7661            }
7662            return list;
7663        }
7664
7665        // reader
7666        synchronized (mPackages) {
7667            String pkgName = intent.getPackage();
7668            if (pkgName == null) {
7669                return applyPostContentProviderResolutionFilter(
7670                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7671                        instantAppPkgName);
7672            }
7673            final PackageParser.Package pkg = mPackages.get(pkgName);
7674            if (pkg != null) {
7675                return applyPostContentProviderResolutionFilter(
7676                        mProviders.queryIntentForPackage(
7677                        intent, resolvedType, flags, pkg.providers, userId),
7678                        instantAppPkgName);
7679            }
7680            return Collections.emptyList();
7681        }
7682    }
7683
7684    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7685            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7686        // TODO: When adding on-demand split support for non-instant applications, remove
7687        // this check and always apply post filtering
7688        if (instantAppPkgName == null) {
7689            return resolveInfos;
7690        }
7691        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7692            final ResolveInfo info = resolveInfos.get(i);
7693            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7694            // allow providers that are defined in the provided package
7695            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7696                if (info.providerInfo.splitName != null
7697                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7698                                info.providerInfo.splitName)) {
7699                    // requested provider is defined in a split that hasn't been installed yet.
7700                    // add the installer to the resolve list
7701                    if (DEBUG_EPHEMERAL) {
7702                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7703                    }
7704                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7705                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7706                            info.providerInfo.packageName, info.providerInfo.splitName,
7707                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
7708                    // make sure this resolver is the default
7709                    installerInfo.isDefault = true;
7710                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7711                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7712                    // add a non-generic filter
7713                    installerInfo.filter = new IntentFilter();
7714                    // load resources from the correct package
7715                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7716                    resolveInfos.set(i, installerInfo);
7717                }
7718                continue;
7719            }
7720            // allow providers that have been explicitly exposed to instant applications
7721            if (!isEphemeralApp
7722                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7723                continue;
7724            }
7725            resolveInfos.remove(i);
7726        }
7727        return resolveInfos;
7728    }
7729
7730    @Override
7731    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7732        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7733            return ParceledListSlice.emptyList();
7734        }
7735        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7736        flags = updateFlagsForPackage(flags, userId, null);
7737        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7738        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7739                true /* requireFullPermission */, false /* checkShell */,
7740                "get installed packages");
7741
7742        // writer
7743        synchronized (mPackages) {
7744            ArrayList<PackageInfo> list;
7745            if (listUninstalled) {
7746                list = new ArrayList<>(mSettings.mPackages.size());
7747                for (PackageSetting ps : mSettings.mPackages.values()) {
7748                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7749                        continue;
7750                    }
7751                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7752                    if (pi != null) {
7753                        list.add(pi);
7754                    }
7755                }
7756            } else {
7757                list = new ArrayList<>(mPackages.size());
7758                for (PackageParser.Package p : mPackages.values()) {
7759                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7760                            Binder.getCallingUid(), userId, flags)) {
7761                        continue;
7762                    }
7763                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7764                            p.mExtras, flags, userId);
7765                    if (pi != null) {
7766                        list.add(pi);
7767                    }
7768                }
7769            }
7770
7771            return new ParceledListSlice<>(list);
7772        }
7773    }
7774
7775    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7776            String[] permissions, boolean[] tmp, int flags, int userId) {
7777        int numMatch = 0;
7778        final PermissionsState permissionsState = ps.getPermissionsState();
7779        for (int i=0; i<permissions.length; i++) {
7780            final String permission = permissions[i];
7781            if (permissionsState.hasPermission(permission, userId)) {
7782                tmp[i] = true;
7783                numMatch++;
7784            } else {
7785                tmp[i] = false;
7786            }
7787        }
7788        if (numMatch == 0) {
7789            return;
7790        }
7791        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7792
7793        // The above might return null in cases of uninstalled apps or install-state
7794        // skew across users/profiles.
7795        if (pi != null) {
7796            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7797                if (numMatch == permissions.length) {
7798                    pi.requestedPermissions = permissions;
7799                } else {
7800                    pi.requestedPermissions = new String[numMatch];
7801                    numMatch = 0;
7802                    for (int i=0; i<permissions.length; i++) {
7803                        if (tmp[i]) {
7804                            pi.requestedPermissions[numMatch] = permissions[i];
7805                            numMatch++;
7806                        }
7807                    }
7808                }
7809            }
7810            list.add(pi);
7811        }
7812    }
7813
7814    @Override
7815    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7816            String[] permissions, int flags, int userId) {
7817        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7818        flags = updateFlagsForPackage(flags, userId, permissions);
7819        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7820                true /* requireFullPermission */, false /* checkShell */,
7821                "get packages holding permissions");
7822        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7823
7824        // writer
7825        synchronized (mPackages) {
7826            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7827            boolean[] tmpBools = new boolean[permissions.length];
7828            if (listUninstalled) {
7829                for (PackageSetting ps : mSettings.mPackages.values()) {
7830                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7831                            userId);
7832                }
7833            } else {
7834                for (PackageParser.Package pkg : mPackages.values()) {
7835                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7836                    if (ps != null) {
7837                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7838                                userId);
7839                    }
7840                }
7841            }
7842
7843            return new ParceledListSlice<PackageInfo>(list);
7844        }
7845    }
7846
7847    @Override
7848    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7849        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7850            return ParceledListSlice.emptyList();
7851        }
7852        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7853        flags = updateFlagsForApplication(flags, userId, null);
7854        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7855
7856        // writer
7857        synchronized (mPackages) {
7858            ArrayList<ApplicationInfo> list;
7859            if (listUninstalled) {
7860                list = new ArrayList<>(mSettings.mPackages.size());
7861                for (PackageSetting ps : mSettings.mPackages.values()) {
7862                    ApplicationInfo ai;
7863                    int effectiveFlags = flags;
7864                    if (ps.isSystem()) {
7865                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7866                    }
7867                    if (ps.pkg != null) {
7868                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7869                            continue;
7870                        }
7871                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7872                                ps.readUserState(userId), userId);
7873                        if (ai != null) {
7874                            rebaseEnabledOverlays(ai, userId);
7875                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7876                        }
7877                    } else {
7878                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7879                        // and already converts to externally visible package name
7880                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7881                                Binder.getCallingUid(), effectiveFlags, userId);
7882                    }
7883                    if (ai != null) {
7884                        list.add(ai);
7885                    }
7886                }
7887            } else {
7888                list = new ArrayList<>(mPackages.size());
7889                for (PackageParser.Package p : mPackages.values()) {
7890                    if (p.mExtras != null) {
7891                        PackageSetting ps = (PackageSetting) p.mExtras;
7892                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7893                            continue;
7894                        }
7895                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7896                                ps.readUserState(userId), userId);
7897                        if (ai != null) {
7898                            rebaseEnabledOverlays(ai, userId);
7899                            ai.packageName = resolveExternalPackageNameLPr(p);
7900                            list.add(ai);
7901                        }
7902                    }
7903                }
7904            }
7905
7906            return new ParceledListSlice<>(list);
7907        }
7908    }
7909
7910    @Override
7911    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7912        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7913            return null;
7914        }
7915        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7916                "getEphemeralApplications");
7917        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7918                true /* requireFullPermission */, false /* checkShell */,
7919                "getEphemeralApplications");
7920        synchronized (mPackages) {
7921            List<InstantAppInfo> instantApps = mInstantAppRegistry
7922                    .getInstantAppsLPr(userId);
7923            if (instantApps != null) {
7924                return new ParceledListSlice<>(instantApps);
7925            }
7926        }
7927        return null;
7928    }
7929
7930    @Override
7931    public boolean isInstantApp(String packageName, int userId) {
7932        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7933                true /* requireFullPermission */, false /* checkShell */,
7934                "isInstantApp");
7935        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7936            return false;
7937        }
7938        int callingUid = Binder.getCallingUid();
7939        if (Process.isIsolated(callingUid)) {
7940            callingUid = mIsolatedOwners.get(callingUid);
7941        }
7942
7943        synchronized (mPackages) {
7944            final PackageSetting ps = mSettings.mPackages.get(packageName);
7945            PackageParser.Package pkg = mPackages.get(packageName);
7946            final boolean returnAllowed =
7947                    ps != null
7948                    && (isCallerSameApp(packageName, callingUid)
7949                            || mContext.checkCallingOrSelfPermission(
7950                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
7951                                            == PERMISSION_GRANTED
7952                            || mInstantAppRegistry.isInstantAccessGranted(
7953                                    userId, UserHandle.getAppId(callingUid), ps.appId));
7954            if (returnAllowed) {
7955                return ps.getInstantApp(userId);
7956            }
7957        }
7958        return false;
7959    }
7960
7961    @Override
7962    public byte[] getInstantAppCookie(String packageName, int userId) {
7963        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7964            return null;
7965        }
7966
7967        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7968                true /* requireFullPermission */, false /* checkShell */,
7969                "getInstantAppCookie");
7970        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7971            return null;
7972        }
7973        synchronized (mPackages) {
7974            return mInstantAppRegistry.getInstantAppCookieLPw(
7975                    packageName, userId);
7976        }
7977    }
7978
7979    @Override
7980    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7981        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7982            return true;
7983        }
7984
7985        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7986                true /* requireFullPermission */, true /* checkShell */,
7987                "setInstantAppCookie");
7988        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7989            return false;
7990        }
7991        synchronized (mPackages) {
7992            return mInstantAppRegistry.setInstantAppCookieLPw(
7993                    packageName, cookie, userId);
7994        }
7995    }
7996
7997    @Override
7998    public Bitmap getInstantAppIcon(String packageName, int userId) {
7999        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8000            return null;
8001        }
8002
8003        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8004                "getInstantAppIcon");
8005
8006        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8007                true /* requireFullPermission */, false /* checkShell */,
8008                "getInstantAppIcon");
8009
8010        synchronized (mPackages) {
8011            return mInstantAppRegistry.getInstantAppIconLPw(
8012                    packageName, userId);
8013        }
8014    }
8015
8016    private boolean isCallerSameApp(String packageName, int uid) {
8017        PackageParser.Package pkg = mPackages.get(packageName);
8018        return pkg != null
8019                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8020    }
8021
8022    @Override
8023    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8024        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8025            return ParceledListSlice.emptyList();
8026        }
8027        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8028    }
8029
8030    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8031        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8032
8033        // reader
8034        synchronized (mPackages) {
8035            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8036            final int userId = UserHandle.getCallingUserId();
8037            while (i.hasNext()) {
8038                final PackageParser.Package p = i.next();
8039                if (p.applicationInfo == null) continue;
8040
8041                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8042                        && !p.applicationInfo.isDirectBootAware();
8043                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8044                        && p.applicationInfo.isDirectBootAware();
8045
8046                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8047                        && (!mSafeMode || isSystemApp(p))
8048                        && (matchesUnaware || matchesAware)) {
8049                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8050                    if (ps != null) {
8051                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8052                                ps.readUserState(userId), userId);
8053                        if (ai != null) {
8054                            rebaseEnabledOverlays(ai, userId);
8055                            finalList.add(ai);
8056                        }
8057                    }
8058                }
8059            }
8060        }
8061
8062        return finalList;
8063    }
8064
8065    @Override
8066    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8067        if (!sUserManager.exists(userId)) return null;
8068        flags = updateFlagsForComponent(flags, userId, name);
8069        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8070        // reader
8071        synchronized (mPackages) {
8072            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8073            PackageSetting ps = provider != null
8074                    ? mSettings.mPackages.get(provider.owner.packageName)
8075                    : null;
8076            if (ps != null) {
8077                final boolean isInstantApp = ps.getInstantApp(userId);
8078                // normal application; filter out instant application provider
8079                if (instantAppPkgName == null && isInstantApp) {
8080                    return null;
8081                }
8082                // instant application; filter out other instant applications
8083                if (instantAppPkgName != null
8084                        && isInstantApp
8085                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8086                    return null;
8087                }
8088                // instant application; filter out non-exposed provider
8089                if (instantAppPkgName != null
8090                        && !isInstantApp
8091                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8092                    return null;
8093                }
8094                // provider not enabled
8095                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8096                    return null;
8097                }
8098                return PackageParser.generateProviderInfo(
8099                        provider, flags, ps.readUserState(userId), userId);
8100            }
8101            return null;
8102        }
8103    }
8104
8105    /**
8106     * @deprecated
8107     */
8108    @Deprecated
8109    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8110        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8111            return;
8112        }
8113        // reader
8114        synchronized (mPackages) {
8115            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8116                    .entrySet().iterator();
8117            final int userId = UserHandle.getCallingUserId();
8118            while (i.hasNext()) {
8119                Map.Entry<String, PackageParser.Provider> entry = i.next();
8120                PackageParser.Provider p = entry.getValue();
8121                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8122
8123                if (ps != null && p.syncable
8124                        && (!mSafeMode || (p.info.applicationInfo.flags
8125                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8126                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8127                            ps.readUserState(userId), userId);
8128                    if (info != null) {
8129                        outNames.add(entry.getKey());
8130                        outInfo.add(info);
8131                    }
8132                }
8133            }
8134        }
8135    }
8136
8137    @Override
8138    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8139            int uid, int flags, String metaDataKey) {
8140        final int userId = processName != null ? UserHandle.getUserId(uid)
8141                : UserHandle.getCallingUserId();
8142        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8143        flags = updateFlagsForComponent(flags, userId, processName);
8144
8145        ArrayList<ProviderInfo> finalList = null;
8146        // reader
8147        synchronized (mPackages) {
8148            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8149            while (i.hasNext()) {
8150                final PackageParser.Provider p = i.next();
8151                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8152                if (ps != null && p.info.authority != null
8153                        && (processName == null
8154                                || (p.info.processName.equals(processName)
8155                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8156                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8157
8158                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8159                    // parameter.
8160                    if (metaDataKey != null
8161                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8162                        continue;
8163                    }
8164
8165                    if (finalList == null) {
8166                        finalList = new ArrayList<ProviderInfo>(3);
8167                    }
8168                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8169                            ps.readUserState(userId), userId);
8170                    if (info != null) {
8171                        finalList.add(info);
8172                    }
8173                }
8174            }
8175        }
8176
8177        if (finalList != null) {
8178            Collections.sort(finalList, mProviderInitOrderSorter);
8179            return new ParceledListSlice<ProviderInfo>(finalList);
8180        }
8181
8182        return ParceledListSlice.emptyList();
8183    }
8184
8185    @Override
8186    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
8187        // reader
8188        synchronized (mPackages) {
8189            final PackageParser.Instrumentation i = mInstrumentation.get(name);
8190            return PackageParser.generateInstrumentationInfo(i, flags);
8191        }
8192    }
8193
8194    @Override
8195    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8196            String targetPackage, int flags) {
8197        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8198    }
8199
8200    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8201            int flags) {
8202        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8203
8204        // reader
8205        synchronized (mPackages) {
8206            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8207            while (i.hasNext()) {
8208                final PackageParser.Instrumentation p = i.next();
8209                if (targetPackage == null
8210                        || targetPackage.equals(p.info.targetPackage)) {
8211                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8212                            flags);
8213                    if (ii != null) {
8214                        finalList.add(ii);
8215                    }
8216                }
8217            }
8218        }
8219
8220        return finalList;
8221    }
8222
8223    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8224        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8225        try {
8226            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8227        } finally {
8228            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8229        }
8230    }
8231
8232    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8233        final File[] files = dir.listFiles();
8234        if (ArrayUtils.isEmpty(files)) {
8235            Log.d(TAG, "No files in app dir " + dir);
8236            return;
8237        }
8238
8239        if (DEBUG_PACKAGE_SCANNING) {
8240            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8241                    + " flags=0x" + Integer.toHexString(parseFlags));
8242        }
8243        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8244                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8245                mParallelPackageParserCallback);
8246
8247        // Submit files for parsing in parallel
8248        int fileCount = 0;
8249        for (File file : files) {
8250            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8251                    && !PackageInstallerService.isStageName(file.getName());
8252            if (!isPackage) {
8253                // Ignore entries which are not packages
8254                continue;
8255            }
8256            parallelPackageParser.submit(file, parseFlags);
8257            fileCount++;
8258        }
8259
8260        // Process results one by one
8261        for (; fileCount > 0; fileCount--) {
8262            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8263            Throwable throwable = parseResult.throwable;
8264            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8265
8266            if (throwable == null) {
8267                // Static shared libraries have synthetic package names
8268                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8269                    renameStaticSharedLibraryPackage(parseResult.pkg);
8270                }
8271                try {
8272                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8273                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8274                                currentTime, null);
8275                    }
8276                } catch (PackageManagerException e) {
8277                    errorCode = e.error;
8278                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8279                }
8280            } else if (throwable instanceof PackageParser.PackageParserException) {
8281                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8282                        throwable;
8283                errorCode = e.error;
8284                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8285            } else {
8286                throw new IllegalStateException("Unexpected exception occurred while parsing "
8287                        + parseResult.scanFile, throwable);
8288            }
8289
8290            // Delete invalid userdata apps
8291            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8292                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8293                logCriticalInfo(Log.WARN,
8294                        "Deleting invalid package at " + parseResult.scanFile);
8295                removeCodePathLI(parseResult.scanFile);
8296            }
8297        }
8298        parallelPackageParser.close();
8299    }
8300
8301    private static File getSettingsProblemFile() {
8302        File dataDir = Environment.getDataDirectory();
8303        File systemDir = new File(dataDir, "system");
8304        File fname = new File(systemDir, "uiderrors.txt");
8305        return fname;
8306    }
8307
8308    static void reportSettingsProblem(int priority, String msg) {
8309        logCriticalInfo(priority, msg);
8310    }
8311
8312    public static void logCriticalInfo(int priority, String msg) {
8313        Slog.println(priority, TAG, msg);
8314        EventLogTags.writePmCriticalInfo(msg);
8315        try {
8316            File fname = getSettingsProblemFile();
8317            FileOutputStream out = new FileOutputStream(fname, true);
8318            PrintWriter pw = new FastPrintWriter(out);
8319            SimpleDateFormat formatter = new SimpleDateFormat();
8320            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8321            pw.println(dateString + ": " + msg);
8322            pw.close();
8323            FileUtils.setPermissions(
8324                    fname.toString(),
8325                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8326                    -1, -1);
8327        } catch (java.io.IOException e) {
8328        }
8329    }
8330
8331    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8332        if (srcFile.isDirectory()) {
8333            final File baseFile = new File(pkg.baseCodePath);
8334            long maxModifiedTime = baseFile.lastModified();
8335            if (pkg.splitCodePaths != null) {
8336                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8337                    final File splitFile = new File(pkg.splitCodePaths[i]);
8338                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8339                }
8340            }
8341            return maxModifiedTime;
8342        }
8343        return srcFile.lastModified();
8344    }
8345
8346    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8347            final int policyFlags) throws PackageManagerException {
8348        // When upgrading from pre-N MR1, verify the package time stamp using the package
8349        // directory and not the APK file.
8350        final long lastModifiedTime = mIsPreNMR1Upgrade
8351                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8352        if (ps != null
8353                && ps.codePath.equals(srcFile)
8354                && ps.timeStamp == lastModifiedTime
8355                && !isCompatSignatureUpdateNeeded(pkg)
8356                && !isRecoverSignatureUpdateNeeded(pkg)) {
8357            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8358            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8359            ArraySet<PublicKey> signingKs;
8360            synchronized (mPackages) {
8361                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8362            }
8363            if (ps.signatures.mSignatures != null
8364                    && ps.signatures.mSignatures.length != 0
8365                    && signingKs != null) {
8366                // Optimization: reuse the existing cached certificates
8367                // if the package appears to be unchanged.
8368                pkg.mSignatures = ps.signatures.mSignatures;
8369                pkg.mSigningKeys = signingKs;
8370                return;
8371            }
8372
8373            Slog.w(TAG, "PackageSetting for " + ps.name
8374                    + " is missing signatures.  Collecting certs again to recover them.");
8375        } else {
8376            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
8377        }
8378
8379        try {
8380            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8381            PackageParser.collectCertificates(pkg, policyFlags);
8382        } catch (PackageParserException e) {
8383            throw PackageManagerException.from(e);
8384        } finally {
8385            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8386        }
8387    }
8388
8389    /**
8390     *  Traces a package scan.
8391     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8392     */
8393    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8394            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8395        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8396        try {
8397            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8398        } finally {
8399            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8400        }
8401    }
8402
8403    /**
8404     *  Scans a package and returns the newly parsed package.
8405     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8406     */
8407    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8408            long currentTime, UserHandle user) throws PackageManagerException {
8409        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8410        PackageParser pp = new PackageParser();
8411        pp.setSeparateProcesses(mSeparateProcesses);
8412        pp.setOnlyCoreApps(mOnlyCore);
8413        pp.setDisplayMetrics(mMetrics);
8414        pp.setCallback(mPackageParserCallback);
8415
8416        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8417            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8418        }
8419
8420        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8421        final PackageParser.Package pkg;
8422        try {
8423            pkg = pp.parsePackage(scanFile, parseFlags);
8424        } catch (PackageParserException e) {
8425            throw PackageManagerException.from(e);
8426        } finally {
8427            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8428        }
8429
8430        // Static shared libraries have synthetic package names
8431        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8432            renameStaticSharedLibraryPackage(pkg);
8433        }
8434
8435        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8436    }
8437
8438    /**
8439     *  Scans a package and returns the newly parsed package.
8440     *  @throws PackageManagerException on a parse error.
8441     */
8442    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8443            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8444            throws PackageManagerException {
8445        // If the package has children and this is the first dive in the function
8446        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8447        // packages (parent and children) would be successfully scanned before the
8448        // actual scan since scanning mutates internal state and we want to atomically
8449        // install the package and its children.
8450        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8451            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8452                scanFlags |= SCAN_CHECK_ONLY;
8453            }
8454        } else {
8455            scanFlags &= ~SCAN_CHECK_ONLY;
8456        }
8457
8458        // Scan the parent
8459        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8460                scanFlags, currentTime, user);
8461
8462        // Scan the children
8463        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8464        for (int i = 0; i < childCount; i++) {
8465            PackageParser.Package childPackage = pkg.childPackages.get(i);
8466            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8467                    currentTime, user);
8468        }
8469
8470
8471        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8472            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8473        }
8474
8475        return scannedPkg;
8476    }
8477
8478    /**
8479     *  Scans a package and returns the newly parsed package.
8480     *  @throws PackageManagerException on a parse error.
8481     */
8482    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8483            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8484            throws PackageManagerException {
8485        PackageSetting ps = null;
8486        PackageSetting updatedPkg;
8487        // reader
8488        synchronized (mPackages) {
8489            // Look to see if we already know about this package.
8490            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8491            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8492                // This package has been renamed to its original name.  Let's
8493                // use that.
8494                ps = mSettings.getPackageLPr(oldName);
8495            }
8496            // If there was no original package, see one for the real package name.
8497            if (ps == null) {
8498                ps = mSettings.getPackageLPr(pkg.packageName);
8499            }
8500            // Check to see if this package could be hiding/updating a system
8501            // package.  Must look for it either under the original or real
8502            // package name depending on our state.
8503            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8504            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8505
8506            // If this is a package we don't know about on the system partition, we
8507            // may need to remove disabled child packages on the system partition
8508            // or may need to not add child packages if the parent apk is updated
8509            // on the data partition and no longer defines this child package.
8510            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8511                // If this is a parent package for an updated system app and this system
8512                // app got an OTA update which no longer defines some of the child packages
8513                // we have to prune them from the disabled system packages.
8514                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8515                if (disabledPs != null) {
8516                    final int scannedChildCount = (pkg.childPackages != null)
8517                            ? pkg.childPackages.size() : 0;
8518                    final int disabledChildCount = disabledPs.childPackageNames != null
8519                            ? disabledPs.childPackageNames.size() : 0;
8520                    for (int i = 0; i < disabledChildCount; i++) {
8521                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8522                        boolean disabledPackageAvailable = false;
8523                        for (int j = 0; j < scannedChildCount; j++) {
8524                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8525                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8526                                disabledPackageAvailable = true;
8527                                break;
8528                            }
8529                         }
8530                         if (!disabledPackageAvailable) {
8531                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8532                         }
8533                    }
8534                }
8535            }
8536        }
8537
8538        boolean updatedPkgBetter = false;
8539        // First check if this is a system package that may involve an update
8540        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8541            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8542            // it needs to drop FLAG_PRIVILEGED.
8543            if (locationIsPrivileged(scanFile)) {
8544                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8545            } else {
8546                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8547            }
8548
8549            if (ps != null && !ps.codePath.equals(scanFile)) {
8550                // The path has changed from what was last scanned...  check the
8551                // version of the new path against what we have stored to determine
8552                // what to do.
8553                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8554                if (pkg.mVersionCode <= ps.versionCode) {
8555                    // The system package has been updated and the code path does not match
8556                    // Ignore entry. Skip it.
8557                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8558                            + " ignored: updated version " + ps.versionCode
8559                            + " better than this " + pkg.mVersionCode);
8560                    if (!updatedPkg.codePath.equals(scanFile)) {
8561                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8562                                + ps.name + " changing from " + updatedPkg.codePathString
8563                                + " to " + scanFile);
8564                        updatedPkg.codePath = scanFile;
8565                        updatedPkg.codePathString = scanFile.toString();
8566                        updatedPkg.resourcePath = scanFile;
8567                        updatedPkg.resourcePathString = scanFile.toString();
8568                    }
8569                    updatedPkg.pkg = pkg;
8570                    updatedPkg.versionCode = pkg.mVersionCode;
8571
8572                    // Update the disabled system child packages to point to the package too.
8573                    final int childCount = updatedPkg.childPackageNames != null
8574                            ? updatedPkg.childPackageNames.size() : 0;
8575                    for (int i = 0; i < childCount; i++) {
8576                        String childPackageName = updatedPkg.childPackageNames.get(i);
8577                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8578                                childPackageName);
8579                        if (updatedChildPkg != null) {
8580                            updatedChildPkg.pkg = pkg;
8581                            updatedChildPkg.versionCode = pkg.mVersionCode;
8582                        }
8583                    }
8584
8585                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8586                            + scanFile + " ignored: updated version " + ps.versionCode
8587                            + " better than this " + pkg.mVersionCode);
8588                } else {
8589                    // The current app on the system partition is better than
8590                    // what we have updated to on the data partition; switch
8591                    // back to the system partition version.
8592                    // At this point, its safely assumed that package installation for
8593                    // apps in system partition will go through. If not there won't be a working
8594                    // version of the app
8595                    // writer
8596                    synchronized (mPackages) {
8597                        // Just remove the loaded entries from package lists.
8598                        mPackages.remove(ps.name);
8599                    }
8600
8601                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8602                            + " reverting from " + ps.codePathString
8603                            + ": new version " + pkg.mVersionCode
8604                            + " better than installed " + ps.versionCode);
8605
8606                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8607                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8608                    synchronized (mInstallLock) {
8609                        args.cleanUpResourcesLI();
8610                    }
8611                    synchronized (mPackages) {
8612                        mSettings.enableSystemPackageLPw(ps.name);
8613                    }
8614                    updatedPkgBetter = true;
8615                }
8616            }
8617        }
8618
8619        if (updatedPkg != null) {
8620            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8621            // initially
8622            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8623
8624            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8625            // flag set initially
8626            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8627                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8628            }
8629        }
8630
8631        // Verify certificates against what was last scanned
8632        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8633
8634        /*
8635         * A new system app appeared, but we already had a non-system one of the
8636         * same name installed earlier.
8637         */
8638        boolean shouldHideSystemApp = false;
8639        if (updatedPkg == null && ps != null
8640                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8641            /*
8642             * Check to make sure the signatures match first. If they don't,
8643             * wipe the installed application and its data.
8644             */
8645            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8646                    != PackageManager.SIGNATURE_MATCH) {
8647                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8648                        + " signatures don't match existing userdata copy; removing");
8649                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8650                        "scanPackageInternalLI")) {
8651                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8652                }
8653                ps = null;
8654            } else {
8655                /*
8656                 * If the newly-added system app is an older version than the
8657                 * already installed version, hide it. It will be scanned later
8658                 * and re-added like an update.
8659                 */
8660                if (pkg.mVersionCode <= ps.versionCode) {
8661                    shouldHideSystemApp = true;
8662                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8663                            + " but new version " + pkg.mVersionCode + " better than installed "
8664                            + ps.versionCode + "; hiding system");
8665                } else {
8666                    /*
8667                     * The newly found system app is a newer version that the
8668                     * one previously installed. Simply remove the
8669                     * already-installed application and replace it with our own
8670                     * while keeping the application data.
8671                     */
8672                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8673                            + " reverting from " + ps.codePathString + ": new version "
8674                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8675                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8676                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8677                    synchronized (mInstallLock) {
8678                        args.cleanUpResourcesLI();
8679                    }
8680                }
8681            }
8682        }
8683
8684        // The apk is forward locked (not public) if its code and resources
8685        // are kept in different files. (except for app in either system or
8686        // vendor path).
8687        // TODO grab this value from PackageSettings
8688        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8689            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8690                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8691            }
8692        }
8693
8694        // TODO: extend to support forward-locked splits
8695        String resourcePath = null;
8696        String baseResourcePath = null;
8697        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8698            if (ps != null && ps.resourcePathString != null) {
8699                resourcePath = ps.resourcePathString;
8700                baseResourcePath = ps.resourcePathString;
8701            } else {
8702                // Should not happen at all. Just log an error.
8703                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8704            }
8705        } else {
8706            resourcePath = pkg.codePath;
8707            baseResourcePath = pkg.baseCodePath;
8708        }
8709
8710        // Set application objects path explicitly.
8711        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8712        pkg.setApplicationInfoCodePath(pkg.codePath);
8713        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8714        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8715        pkg.setApplicationInfoResourcePath(resourcePath);
8716        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8717        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8718
8719        final int userId = ((user == null) ? 0 : user.getIdentifier());
8720        if (ps != null && ps.getInstantApp(userId)) {
8721            scanFlags |= SCAN_AS_INSTANT_APP;
8722        }
8723
8724        // Note that we invoke the following method only if we are about to unpack an application
8725        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8726                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8727
8728        /*
8729         * If the system app should be overridden by a previously installed
8730         * data, hide the system app now and let the /data/app scan pick it up
8731         * again.
8732         */
8733        if (shouldHideSystemApp) {
8734            synchronized (mPackages) {
8735                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8736            }
8737        }
8738
8739        return scannedPkg;
8740    }
8741
8742    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8743        // Derive the new package synthetic package name
8744        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8745                + pkg.staticSharedLibVersion);
8746    }
8747
8748    private static String fixProcessName(String defProcessName,
8749            String processName) {
8750        if (processName == null) {
8751            return defProcessName;
8752        }
8753        return processName;
8754    }
8755
8756    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8757            throws PackageManagerException {
8758        if (pkgSetting.signatures.mSignatures != null) {
8759            // Already existing package. Make sure signatures match
8760            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8761                    == PackageManager.SIGNATURE_MATCH;
8762            if (!match) {
8763                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8764                        == PackageManager.SIGNATURE_MATCH;
8765            }
8766            if (!match) {
8767                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8768                        == PackageManager.SIGNATURE_MATCH;
8769            }
8770            if (!match) {
8771                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8772                        + pkg.packageName + " signatures do not match the "
8773                        + "previously installed version; ignoring!");
8774            }
8775        }
8776
8777        // Check for shared user signatures
8778        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8779            // Already existing package. Make sure signatures match
8780            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8781                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8782            if (!match) {
8783                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8784                        == PackageManager.SIGNATURE_MATCH;
8785            }
8786            if (!match) {
8787                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8788                        == PackageManager.SIGNATURE_MATCH;
8789            }
8790            if (!match) {
8791                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8792                        "Package " + pkg.packageName
8793                        + " has no signatures that match those in shared user "
8794                        + pkgSetting.sharedUser.name + "; ignoring!");
8795            }
8796        }
8797    }
8798
8799    /**
8800     * Enforces that only the system UID or root's UID can call a method exposed
8801     * via Binder.
8802     *
8803     * @param message used as message if SecurityException is thrown
8804     * @throws SecurityException if the caller is not system or root
8805     */
8806    private static final void enforceSystemOrRoot(String message) {
8807        final int uid = Binder.getCallingUid();
8808        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8809            throw new SecurityException(message);
8810        }
8811    }
8812
8813    @Override
8814    public void performFstrimIfNeeded() {
8815        enforceSystemOrRoot("Only the system can request fstrim");
8816
8817        // Before everything else, see whether we need to fstrim.
8818        try {
8819            IStorageManager sm = PackageHelper.getStorageManager();
8820            if (sm != null) {
8821                boolean doTrim = false;
8822                final long interval = android.provider.Settings.Global.getLong(
8823                        mContext.getContentResolver(),
8824                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8825                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8826                if (interval > 0) {
8827                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8828                    if (timeSinceLast > interval) {
8829                        doTrim = true;
8830                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8831                                + "; running immediately");
8832                    }
8833                }
8834                if (doTrim) {
8835                    final boolean dexOptDialogShown;
8836                    synchronized (mPackages) {
8837                        dexOptDialogShown = mDexOptDialogShown;
8838                    }
8839                    if (!isFirstBoot() && dexOptDialogShown) {
8840                        try {
8841                            ActivityManager.getService().showBootMessage(
8842                                    mContext.getResources().getString(
8843                                            R.string.android_upgrading_fstrim), true);
8844                        } catch (RemoteException e) {
8845                        }
8846                    }
8847                    sm.runMaintenance();
8848                }
8849            } else {
8850                Slog.e(TAG, "storageManager service unavailable!");
8851            }
8852        } catch (RemoteException e) {
8853            // Can't happen; StorageManagerService is local
8854        }
8855    }
8856
8857    @Override
8858    public void updatePackagesIfNeeded() {
8859        enforceSystemOrRoot("Only the system can request package update");
8860
8861        // We need to re-extract after an OTA.
8862        boolean causeUpgrade = isUpgrade();
8863
8864        // First boot or factory reset.
8865        // Note: we also handle devices that are upgrading to N right now as if it is their
8866        //       first boot, as they do not have profile data.
8867        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8868
8869        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8870        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8871
8872        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8873            return;
8874        }
8875
8876        List<PackageParser.Package> pkgs;
8877        synchronized (mPackages) {
8878            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8879        }
8880
8881        final long startTime = System.nanoTime();
8882        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8883                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8884
8885        final int elapsedTimeSeconds =
8886                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8887
8888        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8889        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8890        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8891        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8892        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8893    }
8894
8895    /**
8896     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8897     * containing statistics about the invocation. The array consists of three elements,
8898     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8899     * and {@code numberOfPackagesFailed}.
8900     */
8901    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8902            String compilerFilter) {
8903
8904        int numberOfPackagesVisited = 0;
8905        int numberOfPackagesOptimized = 0;
8906        int numberOfPackagesSkipped = 0;
8907        int numberOfPackagesFailed = 0;
8908        final int numberOfPackagesToDexopt = pkgs.size();
8909
8910        for (PackageParser.Package pkg : pkgs) {
8911            numberOfPackagesVisited++;
8912
8913            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8914                if (DEBUG_DEXOPT) {
8915                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8916                }
8917                numberOfPackagesSkipped++;
8918                continue;
8919            }
8920
8921            if (DEBUG_DEXOPT) {
8922                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8923                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8924            }
8925
8926            if (showDialog) {
8927                try {
8928                    ActivityManager.getService().showBootMessage(
8929                            mContext.getResources().getString(R.string.android_upgrading_apk,
8930                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8931                } catch (RemoteException e) {
8932                }
8933                synchronized (mPackages) {
8934                    mDexOptDialogShown = true;
8935                }
8936            }
8937
8938            // If the OTA updates a system app which was previously preopted to a non-preopted state
8939            // the app might end up being verified at runtime. That's because by default the apps
8940            // are verify-profile but for preopted apps there's no profile.
8941            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8942            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8943            // filter (by default 'quicken').
8944            // Note that at this stage unused apps are already filtered.
8945            if (isSystemApp(pkg) &&
8946                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8947                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8948                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8949            }
8950
8951            // checkProfiles is false to avoid merging profiles during boot which
8952            // might interfere with background compilation (b/28612421).
8953            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8954            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8955            // trade-off worth doing to save boot time work.
8956            int dexOptStatus = performDexOptTraced(pkg.packageName,
8957                    false /* checkProfiles */,
8958                    compilerFilter,
8959                    false /* force */);
8960            switch (dexOptStatus) {
8961                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8962                    numberOfPackagesOptimized++;
8963                    break;
8964                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8965                    numberOfPackagesSkipped++;
8966                    break;
8967                case PackageDexOptimizer.DEX_OPT_FAILED:
8968                    numberOfPackagesFailed++;
8969                    break;
8970                default:
8971                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8972                    break;
8973            }
8974        }
8975
8976        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8977                numberOfPackagesFailed };
8978    }
8979
8980    @Override
8981    public void notifyPackageUse(String packageName, int reason) {
8982        synchronized (mPackages) {
8983            PackageParser.Package p = mPackages.get(packageName);
8984            if (p == null) {
8985                return;
8986            }
8987            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8988        }
8989    }
8990
8991    @Override
8992    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8993        int userId = UserHandle.getCallingUserId();
8994        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8995        if (ai == null) {
8996            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8997                + loadingPackageName + ", user=" + userId);
8998            return;
8999        }
9000        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
9001    }
9002
9003    @Override
9004    public boolean performDexOpt(String packageName,
9005            boolean checkProfiles, int compileReason, boolean force) {
9006        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
9007                getCompilerFilterForReason(compileReason), force);
9008        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9009    }
9010
9011    @Override
9012    public boolean performDexOptMode(String packageName,
9013            boolean checkProfiles, String targetCompilerFilter, boolean force) {
9014        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9015            return false;
9016        }
9017        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
9018                targetCompilerFilter, force);
9019        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9020    }
9021
9022    private int performDexOptTraced(String packageName,
9023                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9024        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9025        try {
9026            return performDexOptInternal(packageName, checkProfiles,
9027                    targetCompilerFilter, force);
9028        } finally {
9029            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9030        }
9031    }
9032
9033    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9034    // if the package can now be considered up to date for the given filter.
9035    private int performDexOptInternal(String packageName,
9036                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9037        PackageParser.Package p;
9038        synchronized (mPackages) {
9039            p = mPackages.get(packageName);
9040            if (p == null) {
9041                // Package could not be found. Report failure.
9042                return PackageDexOptimizer.DEX_OPT_FAILED;
9043            }
9044            mPackageUsage.maybeWriteAsync(mPackages);
9045            mCompilerStats.maybeWriteAsync();
9046        }
9047        long callingId = Binder.clearCallingIdentity();
9048        try {
9049            synchronized (mInstallLock) {
9050                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
9051                        targetCompilerFilter, force);
9052            }
9053        } finally {
9054            Binder.restoreCallingIdentity(callingId);
9055        }
9056    }
9057
9058    public ArraySet<String> getOptimizablePackages() {
9059        ArraySet<String> pkgs = new ArraySet<String>();
9060        synchronized (mPackages) {
9061            for (PackageParser.Package p : mPackages.values()) {
9062                if (PackageDexOptimizer.canOptimizePackage(p)) {
9063                    pkgs.add(p.packageName);
9064                }
9065            }
9066        }
9067        return pkgs;
9068    }
9069
9070    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9071            boolean checkProfiles, String targetCompilerFilter,
9072            boolean force) {
9073        // Select the dex optimizer based on the force parameter.
9074        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9075        //       allocate an object here.
9076        PackageDexOptimizer pdo = force
9077                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9078                : mPackageDexOptimizer;
9079
9080        // Dexopt all dependencies first. Note: we ignore the return value and march on
9081        // on errors.
9082        // Note that we are going to call performDexOpt on those libraries as many times as
9083        // they are referenced in packages. When we do a batch of performDexOpt (for example
9084        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9085        // and the first package that uses the library will dexopt it. The
9086        // others will see that the compiled code for the library is up to date.
9087        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9088        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9089        if (!deps.isEmpty()) {
9090            for (PackageParser.Package depPackage : deps) {
9091                // TODO: Analyze and investigate if we (should) profile libraries.
9092                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9093                        false /* checkProfiles */,
9094                        targetCompilerFilter,
9095                        getOrCreateCompilerPackageStats(depPackage),
9096                        true /* isUsedByOtherApps */);
9097            }
9098        }
9099        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
9100                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
9101                mDexManager.isUsedByOtherApps(p.packageName));
9102    }
9103
9104    // Performs dexopt on the used secondary dex files belonging to the given package.
9105    // Returns true if all dex files were process successfully (which could mean either dexopt or
9106    // skip). Returns false if any of the files caused errors.
9107    @Override
9108    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9109            boolean force) {
9110        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9111            return false;
9112        }
9113        mDexManager.reconcileSecondaryDexFiles(packageName);
9114        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
9115    }
9116
9117    public boolean performDexOptSecondary(String packageName, int compileReason,
9118            boolean force) {
9119        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
9120    }
9121
9122    /**
9123     * Reconcile the information we have about the secondary dex files belonging to
9124     * {@code packagName} and the actual dex files. For all dex files that were
9125     * deleted, update the internal records and delete the generated oat files.
9126     */
9127    @Override
9128    public void reconcileSecondaryDexFiles(String packageName) {
9129        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9130            return;
9131        }
9132        mDexManager.reconcileSecondaryDexFiles(packageName);
9133    }
9134
9135    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9136    // a reference there.
9137    /*package*/ DexManager getDexManager() {
9138        return mDexManager;
9139    }
9140
9141    /**
9142     * Execute the background dexopt job immediately.
9143     */
9144    @Override
9145    public boolean runBackgroundDexoptJob() {
9146        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9147            return false;
9148        }
9149        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9150    }
9151
9152    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9153        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9154                || p.usesStaticLibraries != null) {
9155            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9156            Set<String> collectedNames = new HashSet<>();
9157            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9158
9159            retValue.remove(p);
9160
9161            return retValue;
9162        } else {
9163            return Collections.emptyList();
9164        }
9165    }
9166
9167    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9168            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9169        if (!collectedNames.contains(p.packageName)) {
9170            collectedNames.add(p.packageName);
9171            collected.add(p);
9172
9173            if (p.usesLibraries != null) {
9174                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9175                        null, collected, collectedNames);
9176            }
9177            if (p.usesOptionalLibraries != null) {
9178                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9179                        null, collected, collectedNames);
9180            }
9181            if (p.usesStaticLibraries != null) {
9182                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9183                        p.usesStaticLibrariesVersions, collected, collectedNames);
9184            }
9185        }
9186    }
9187
9188    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9189            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9190        final int libNameCount = libs.size();
9191        for (int i = 0; i < libNameCount; i++) {
9192            String libName = libs.get(i);
9193            int version = (versions != null && versions.length == libNameCount)
9194                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9195            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9196            if (libPkg != null) {
9197                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9198            }
9199        }
9200    }
9201
9202    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9203        synchronized (mPackages) {
9204            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9205            if (libEntry != null) {
9206                return mPackages.get(libEntry.apk);
9207            }
9208            return null;
9209        }
9210    }
9211
9212    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9213        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9214        if (versionedLib == null) {
9215            return null;
9216        }
9217        return versionedLib.get(version);
9218    }
9219
9220    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9221        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9222                pkg.staticSharedLibName);
9223        if (versionedLib == null) {
9224            return null;
9225        }
9226        int previousLibVersion = -1;
9227        final int versionCount = versionedLib.size();
9228        for (int i = 0; i < versionCount; i++) {
9229            final int libVersion = versionedLib.keyAt(i);
9230            if (libVersion < pkg.staticSharedLibVersion) {
9231                previousLibVersion = Math.max(previousLibVersion, libVersion);
9232            }
9233        }
9234        if (previousLibVersion >= 0) {
9235            return versionedLib.get(previousLibVersion);
9236        }
9237        return null;
9238    }
9239
9240    public void shutdown() {
9241        mPackageUsage.writeNow(mPackages);
9242        mCompilerStats.writeNow();
9243    }
9244
9245    @Override
9246    public void dumpProfiles(String packageName) {
9247        PackageParser.Package pkg;
9248        synchronized (mPackages) {
9249            pkg = mPackages.get(packageName);
9250            if (pkg == null) {
9251                throw new IllegalArgumentException("Unknown package: " + packageName);
9252            }
9253        }
9254        /* Only the shell, root, or the app user should be able to dump profiles. */
9255        int callingUid = Binder.getCallingUid();
9256        if (callingUid != Process.SHELL_UID &&
9257            callingUid != Process.ROOT_UID &&
9258            callingUid != pkg.applicationInfo.uid) {
9259            throw new SecurityException("dumpProfiles");
9260        }
9261
9262        synchronized (mInstallLock) {
9263            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9264            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9265            try {
9266                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9267                String codePaths = TextUtils.join(";", allCodePaths);
9268                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9269            } catch (InstallerException e) {
9270                Slog.w(TAG, "Failed to dump profiles", e);
9271            }
9272            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9273        }
9274    }
9275
9276    @Override
9277    public void forceDexOpt(String packageName) {
9278        enforceSystemOrRoot("forceDexOpt");
9279
9280        PackageParser.Package pkg;
9281        synchronized (mPackages) {
9282            pkg = mPackages.get(packageName);
9283            if (pkg == null) {
9284                throw new IllegalArgumentException("Unknown package: " + packageName);
9285            }
9286        }
9287
9288        synchronized (mInstallLock) {
9289            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9290
9291            // Whoever is calling forceDexOpt wants a compiled package.
9292            // Don't use profiles since that may cause compilation to be skipped.
9293            final int res = performDexOptInternalWithDependenciesLI(pkg,
9294                    false /* checkProfiles */, getDefaultCompilerFilter(),
9295                    true /* force */);
9296
9297            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9298            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9299                throw new IllegalStateException("Failed to dexopt: " + res);
9300            }
9301        }
9302    }
9303
9304    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9305        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9306            Slog.w(TAG, "Unable to update from " + oldPkg.name
9307                    + " to " + newPkg.packageName
9308                    + ": old package not in system partition");
9309            return false;
9310        } else if (mPackages.get(oldPkg.name) != null) {
9311            Slog.w(TAG, "Unable to update from " + oldPkg.name
9312                    + " to " + newPkg.packageName
9313                    + ": old package still exists");
9314            return false;
9315        }
9316        return true;
9317    }
9318
9319    void removeCodePathLI(File codePath) {
9320        if (codePath.isDirectory()) {
9321            try {
9322                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9323            } catch (InstallerException e) {
9324                Slog.w(TAG, "Failed to remove code path", e);
9325            }
9326        } else {
9327            codePath.delete();
9328        }
9329    }
9330
9331    private int[] resolveUserIds(int userId) {
9332        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9333    }
9334
9335    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9336        if (pkg == null) {
9337            Slog.wtf(TAG, "Package was null!", new Throwable());
9338            return;
9339        }
9340        clearAppDataLeafLIF(pkg, userId, flags);
9341        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9342        for (int i = 0; i < childCount; i++) {
9343            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9344        }
9345    }
9346
9347    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9348        final PackageSetting ps;
9349        synchronized (mPackages) {
9350            ps = mSettings.mPackages.get(pkg.packageName);
9351        }
9352        for (int realUserId : resolveUserIds(userId)) {
9353            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9354            try {
9355                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9356                        ceDataInode);
9357            } catch (InstallerException e) {
9358                Slog.w(TAG, String.valueOf(e));
9359            }
9360        }
9361    }
9362
9363    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9364        if (pkg == null) {
9365            Slog.wtf(TAG, "Package was null!", new Throwable());
9366            return;
9367        }
9368        destroyAppDataLeafLIF(pkg, userId, flags);
9369        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9370        for (int i = 0; i < childCount; i++) {
9371            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9372        }
9373    }
9374
9375    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9376        final PackageSetting ps;
9377        synchronized (mPackages) {
9378            ps = mSettings.mPackages.get(pkg.packageName);
9379        }
9380        for (int realUserId : resolveUserIds(userId)) {
9381            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9382            try {
9383                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9384                        ceDataInode);
9385            } catch (InstallerException e) {
9386                Slog.w(TAG, String.valueOf(e));
9387            }
9388            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9389        }
9390    }
9391
9392    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9393        if (pkg == null) {
9394            Slog.wtf(TAG, "Package was null!", new Throwable());
9395            return;
9396        }
9397        destroyAppProfilesLeafLIF(pkg);
9398        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9399        for (int i = 0; i < childCount; i++) {
9400            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9401        }
9402    }
9403
9404    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9405        try {
9406            mInstaller.destroyAppProfiles(pkg.packageName);
9407        } catch (InstallerException e) {
9408            Slog.w(TAG, String.valueOf(e));
9409        }
9410    }
9411
9412    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9413        if (pkg == null) {
9414            Slog.wtf(TAG, "Package was null!", new Throwable());
9415            return;
9416        }
9417        clearAppProfilesLeafLIF(pkg);
9418        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9419        for (int i = 0; i < childCount; i++) {
9420            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9421        }
9422    }
9423
9424    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9425        try {
9426            mInstaller.clearAppProfiles(pkg.packageName);
9427        } catch (InstallerException e) {
9428            Slog.w(TAG, String.valueOf(e));
9429        }
9430    }
9431
9432    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9433            long lastUpdateTime) {
9434        // Set parent install/update time
9435        PackageSetting ps = (PackageSetting) pkg.mExtras;
9436        if (ps != null) {
9437            ps.firstInstallTime = firstInstallTime;
9438            ps.lastUpdateTime = lastUpdateTime;
9439        }
9440        // Set children install/update time
9441        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9442        for (int i = 0; i < childCount; i++) {
9443            PackageParser.Package childPkg = pkg.childPackages.get(i);
9444            ps = (PackageSetting) childPkg.mExtras;
9445            if (ps != null) {
9446                ps.firstInstallTime = firstInstallTime;
9447                ps.lastUpdateTime = lastUpdateTime;
9448            }
9449        }
9450    }
9451
9452    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9453            PackageParser.Package changingLib) {
9454        if (file.path != null) {
9455            usesLibraryFiles.add(file.path);
9456            return;
9457        }
9458        PackageParser.Package p = mPackages.get(file.apk);
9459        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9460            // If we are doing this while in the middle of updating a library apk,
9461            // then we need to make sure to use that new apk for determining the
9462            // dependencies here.  (We haven't yet finished committing the new apk
9463            // to the package manager state.)
9464            if (p == null || p.packageName.equals(changingLib.packageName)) {
9465                p = changingLib;
9466            }
9467        }
9468        if (p != null) {
9469            usesLibraryFiles.addAll(p.getAllCodePaths());
9470            if (p.usesLibraryFiles != null) {
9471                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9472            }
9473        }
9474    }
9475
9476    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9477            PackageParser.Package changingLib) throws PackageManagerException {
9478        if (pkg == null) {
9479            return;
9480        }
9481        ArraySet<String> usesLibraryFiles = null;
9482        if (pkg.usesLibraries != null) {
9483            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9484                    null, null, pkg.packageName, changingLib, true, null);
9485        }
9486        if (pkg.usesStaticLibraries != null) {
9487            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9488                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9489                    pkg.packageName, changingLib, true, usesLibraryFiles);
9490        }
9491        if (pkg.usesOptionalLibraries != null) {
9492            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9493                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9494        }
9495        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9496            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9497        } else {
9498            pkg.usesLibraryFiles = null;
9499        }
9500    }
9501
9502    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9503            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9504            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9505            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9506            throws PackageManagerException {
9507        final int libCount = requestedLibraries.size();
9508        for (int i = 0; i < libCount; i++) {
9509            final String libName = requestedLibraries.get(i);
9510            final int libVersion = requiredVersions != null ? requiredVersions[i]
9511                    : SharedLibraryInfo.VERSION_UNDEFINED;
9512            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9513            if (libEntry == null) {
9514                if (required) {
9515                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9516                            "Package " + packageName + " requires unavailable shared library "
9517                                    + libName + "; failing!");
9518                } else if (DEBUG_SHARED_LIBRARIES) {
9519                    Slog.i(TAG, "Package " + packageName
9520                            + " desires unavailable shared library "
9521                            + libName + "; ignoring!");
9522                }
9523            } else {
9524                if (requiredVersions != null && requiredCertDigests != null) {
9525                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9526                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9527                            "Package " + packageName + " requires unavailable static shared"
9528                                    + " library " + libName + " version "
9529                                    + libEntry.info.getVersion() + "; failing!");
9530                    }
9531
9532                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9533                    if (libPkg == null) {
9534                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9535                                "Package " + packageName + " requires unavailable static shared"
9536                                        + " library; failing!");
9537                    }
9538
9539                    String expectedCertDigest = requiredCertDigests[i];
9540                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9541                                libPkg.mSignatures[0]);
9542                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9543                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9544                                "Package " + packageName + " requires differently signed" +
9545                                        " static shared library; failing!");
9546                    }
9547                }
9548
9549                if (outUsedLibraries == null) {
9550                    outUsedLibraries = new ArraySet<>();
9551                }
9552                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9553            }
9554        }
9555        return outUsedLibraries;
9556    }
9557
9558    private static boolean hasString(List<String> list, List<String> which) {
9559        if (list == null) {
9560            return false;
9561        }
9562        for (int i=list.size()-1; i>=0; i--) {
9563            for (int j=which.size()-1; j>=0; j--) {
9564                if (which.get(j).equals(list.get(i))) {
9565                    return true;
9566                }
9567            }
9568        }
9569        return false;
9570    }
9571
9572    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9573            PackageParser.Package changingPkg) {
9574        ArrayList<PackageParser.Package> res = null;
9575        for (PackageParser.Package pkg : mPackages.values()) {
9576            if (changingPkg != null
9577                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9578                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9579                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9580                            changingPkg.staticSharedLibName)) {
9581                return null;
9582            }
9583            if (res == null) {
9584                res = new ArrayList<>();
9585            }
9586            res.add(pkg);
9587            try {
9588                updateSharedLibrariesLPr(pkg, changingPkg);
9589            } catch (PackageManagerException e) {
9590                // If a system app update or an app and a required lib missing we
9591                // delete the package and for updated system apps keep the data as
9592                // it is better for the user to reinstall than to be in an limbo
9593                // state. Also libs disappearing under an app should never happen
9594                // - just in case.
9595                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9596                    final int flags = pkg.isUpdatedSystemApp()
9597                            ? PackageManager.DELETE_KEEP_DATA : 0;
9598                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9599                            flags , null, true, null);
9600                }
9601                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9602            }
9603        }
9604        return res;
9605    }
9606
9607    /**
9608     * Derive the value of the {@code cpuAbiOverride} based on the provided
9609     * value and an optional stored value from the package settings.
9610     */
9611    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9612        String cpuAbiOverride = null;
9613
9614        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9615            cpuAbiOverride = null;
9616        } else if (abiOverride != null) {
9617            cpuAbiOverride = abiOverride;
9618        } else if (settings != null) {
9619            cpuAbiOverride = settings.cpuAbiOverrideString;
9620        }
9621
9622        return cpuAbiOverride;
9623    }
9624
9625    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9626            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9627                    throws PackageManagerException {
9628        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9629        // If the package has children and this is the first dive in the function
9630        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9631        // whether all packages (parent and children) would be successfully scanned
9632        // before the actual scan since scanning mutates internal state and we want
9633        // to atomically install the package and its children.
9634        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9635            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9636                scanFlags |= SCAN_CHECK_ONLY;
9637            }
9638        } else {
9639            scanFlags &= ~SCAN_CHECK_ONLY;
9640        }
9641
9642        final PackageParser.Package scannedPkg;
9643        try {
9644            // Scan the parent
9645            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9646            // Scan the children
9647            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9648            for (int i = 0; i < childCount; i++) {
9649                PackageParser.Package childPkg = pkg.childPackages.get(i);
9650                scanPackageLI(childPkg, policyFlags,
9651                        scanFlags, currentTime, user);
9652            }
9653        } finally {
9654            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9655        }
9656
9657        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9658            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9659        }
9660
9661        return scannedPkg;
9662    }
9663
9664    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9665            int scanFlags, long currentTime, @Nullable UserHandle user)
9666                    throws PackageManagerException {
9667        boolean success = false;
9668        try {
9669            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9670                    currentTime, user);
9671            success = true;
9672            return res;
9673        } finally {
9674            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9675                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9676                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9677                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9678                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9679            }
9680        }
9681    }
9682
9683    /**
9684     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9685     */
9686    private static boolean apkHasCode(String fileName) {
9687        StrictJarFile jarFile = null;
9688        try {
9689            jarFile = new StrictJarFile(fileName,
9690                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9691            return jarFile.findEntry("classes.dex") != null;
9692        } catch (IOException ignore) {
9693        } finally {
9694            try {
9695                if (jarFile != null) {
9696                    jarFile.close();
9697                }
9698            } catch (IOException ignore) {}
9699        }
9700        return false;
9701    }
9702
9703    /**
9704     * Enforces code policy for the package. This ensures that if an APK has
9705     * declared hasCode="true" in its manifest that the APK actually contains
9706     * code.
9707     *
9708     * @throws PackageManagerException If bytecode could not be found when it should exist
9709     */
9710    private static void assertCodePolicy(PackageParser.Package pkg)
9711            throws PackageManagerException {
9712        final boolean shouldHaveCode =
9713                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9714        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9715            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9716                    "Package " + pkg.baseCodePath + " code is missing");
9717        }
9718
9719        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9720            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9721                final boolean splitShouldHaveCode =
9722                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9723                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9724                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9725                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9726                }
9727            }
9728        }
9729    }
9730
9731    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9732            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9733                    throws PackageManagerException {
9734        if (DEBUG_PACKAGE_SCANNING) {
9735            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9736                Log.d(TAG, "Scanning package " + pkg.packageName);
9737        }
9738
9739        applyPolicy(pkg, policyFlags);
9740
9741        assertPackageIsValid(pkg, policyFlags, scanFlags);
9742
9743        // Initialize package source and resource directories
9744        final File scanFile = new File(pkg.codePath);
9745        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9746        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9747
9748        SharedUserSetting suid = null;
9749        PackageSetting pkgSetting = null;
9750
9751        // Getting the package setting may have a side-effect, so if we
9752        // are only checking if scan would succeed, stash a copy of the
9753        // old setting to restore at the end.
9754        PackageSetting nonMutatedPs = null;
9755
9756        // We keep references to the derived CPU Abis from settings in oder to reuse
9757        // them in the case where we're not upgrading or booting for the first time.
9758        String primaryCpuAbiFromSettings = null;
9759        String secondaryCpuAbiFromSettings = null;
9760
9761        // writer
9762        synchronized (mPackages) {
9763            if (pkg.mSharedUserId != null) {
9764                // SIDE EFFECTS; may potentially allocate a new shared user
9765                suid = mSettings.getSharedUserLPw(
9766                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9767                if (DEBUG_PACKAGE_SCANNING) {
9768                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9769                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9770                                + "): packages=" + suid.packages);
9771                }
9772            }
9773
9774            // Check if we are renaming from an original package name.
9775            PackageSetting origPackage = null;
9776            String realName = null;
9777            if (pkg.mOriginalPackages != null) {
9778                // This package may need to be renamed to a previously
9779                // installed name.  Let's check on that...
9780                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9781                if (pkg.mOriginalPackages.contains(renamed)) {
9782                    // This package had originally been installed as the
9783                    // original name, and we have already taken care of
9784                    // transitioning to the new one.  Just update the new
9785                    // one to continue using the old name.
9786                    realName = pkg.mRealPackage;
9787                    if (!pkg.packageName.equals(renamed)) {
9788                        // Callers into this function may have already taken
9789                        // care of renaming the package; only do it here if
9790                        // it is not already done.
9791                        pkg.setPackageName(renamed);
9792                    }
9793                } else {
9794                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9795                        if ((origPackage = mSettings.getPackageLPr(
9796                                pkg.mOriginalPackages.get(i))) != null) {
9797                            // We do have the package already installed under its
9798                            // original name...  should we use it?
9799                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9800                                // New package is not compatible with original.
9801                                origPackage = null;
9802                                continue;
9803                            } else if (origPackage.sharedUser != null) {
9804                                // Make sure uid is compatible between packages.
9805                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9806                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9807                                            + " to " + pkg.packageName + ": old uid "
9808                                            + origPackage.sharedUser.name
9809                                            + " differs from " + pkg.mSharedUserId);
9810                                    origPackage = null;
9811                                    continue;
9812                                }
9813                                // TODO: Add case when shared user id is added [b/28144775]
9814                            } else {
9815                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9816                                        + pkg.packageName + " to old name " + origPackage.name);
9817                            }
9818                            break;
9819                        }
9820                    }
9821                }
9822            }
9823
9824            if (mTransferedPackages.contains(pkg.packageName)) {
9825                Slog.w(TAG, "Package " + pkg.packageName
9826                        + " was transferred to another, but its .apk remains");
9827            }
9828
9829            // See comments in nonMutatedPs declaration
9830            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9831                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9832                if (foundPs != null) {
9833                    nonMutatedPs = new PackageSetting(foundPs);
9834                }
9835            }
9836
9837            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9838                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9839                if (foundPs != null) {
9840                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9841                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9842                }
9843            }
9844
9845            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9846            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9847                PackageManagerService.reportSettingsProblem(Log.WARN,
9848                        "Package " + pkg.packageName + " shared user changed from "
9849                                + (pkgSetting.sharedUser != null
9850                                        ? pkgSetting.sharedUser.name : "<nothing>")
9851                                + " to "
9852                                + (suid != null ? suid.name : "<nothing>")
9853                                + "; replacing with new");
9854                pkgSetting = null;
9855            }
9856            final PackageSetting oldPkgSetting =
9857                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9858            final PackageSetting disabledPkgSetting =
9859                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9860
9861            String[] usesStaticLibraries = null;
9862            if (pkg.usesStaticLibraries != null) {
9863                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9864                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9865            }
9866
9867            if (pkgSetting == null) {
9868                final String parentPackageName = (pkg.parentPackage != null)
9869                        ? pkg.parentPackage.packageName : null;
9870                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9871                // REMOVE SharedUserSetting from method; update in a separate call
9872                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9873                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9874                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9875                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9876                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9877                        true /*allowInstall*/, instantApp, parentPackageName,
9878                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
9879                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9880                // SIDE EFFECTS; updates system state; move elsewhere
9881                if (origPackage != null) {
9882                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9883                }
9884                mSettings.addUserToSettingLPw(pkgSetting);
9885            } else {
9886                // REMOVE SharedUserSetting from method; update in a separate call.
9887                //
9888                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9889                // secondaryCpuAbi are not known at this point so we always update them
9890                // to null here, only to reset them at a later point.
9891                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9892                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9893                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9894                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9895                        UserManagerService.getInstance(), usesStaticLibraries,
9896                        pkg.usesStaticLibrariesVersions);
9897            }
9898            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9899            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9900
9901            // SIDE EFFECTS; modifies system state; move elsewhere
9902            if (pkgSetting.origPackage != null) {
9903                // If we are first transitioning from an original package,
9904                // fix up the new package's name now.  We need to do this after
9905                // looking up the package under its new name, so getPackageLP
9906                // can take care of fiddling things correctly.
9907                pkg.setPackageName(origPackage.name);
9908
9909                // File a report about this.
9910                String msg = "New package " + pkgSetting.realName
9911                        + " renamed to replace old package " + pkgSetting.name;
9912                reportSettingsProblem(Log.WARN, msg);
9913
9914                // Make a note of it.
9915                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9916                    mTransferedPackages.add(origPackage.name);
9917                }
9918
9919                // No longer need to retain this.
9920                pkgSetting.origPackage = null;
9921            }
9922
9923            // SIDE EFFECTS; modifies system state; move elsewhere
9924            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9925                // Make a note of it.
9926                mTransferedPackages.add(pkg.packageName);
9927            }
9928
9929            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9930                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9931            }
9932
9933            if ((scanFlags & SCAN_BOOTING) == 0
9934                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9935                // Check all shared libraries and map to their actual file path.
9936                // We only do this here for apps not on a system dir, because those
9937                // are the only ones that can fail an install due to this.  We
9938                // will take care of the system apps by updating all of their
9939                // library paths after the scan is done. Also during the initial
9940                // scan don't update any libs as we do this wholesale after all
9941                // apps are scanned to avoid dependency based scanning.
9942                updateSharedLibrariesLPr(pkg, null);
9943            }
9944
9945            if (mFoundPolicyFile) {
9946                SELinuxMMAC.assignSeInfoValue(pkg);
9947            }
9948            pkg.applicationInfo.uid = pkgSetting.appId;
9949            pkg.mExtras = pkgSetting;
9950
9951
9952            // Static shared libs have same package with different versions where
9953            // we internally use a synthetic package name to allow multiple versions
9954            // of the same package, therefore we need to compare signatures against
9955            // the package setting for the latest library version.
9956            PackageSetting signatureCheckPs = pkgSetting;
9957            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9958                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9959                if (libraryEntry != null) {
9960                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9961                }
9962            }
9963
9964            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9965                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9966                    // We just determined the app is signed correctly, so bring
9967                    // over the latest parsed certs.
9968                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9969                } else {
9970                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9971                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9972                                "Package " + pkg.packageName + " upgrade keys do not match the "
9973                                + "previously installed version");
9974                    } else {
9975                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9976                        String msg = "System package " + pkg.packageName
9977                                + " signature changed; retaining data.";
9978                        reportSettingsProblem(Log.WARN, msg);
9979                    }
9980                }
9981            } else {
9982                try {
9983                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9984                    verifySignaturesLP(signatureCheckPs, pkg);
9985                    // We just determined the app is signed correctly, so bring
9986                    // over the latest parsed certs.
9987                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9988                } catch (PackageManagerException e) {
9989                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9990                        throw e;
9991                    }
9992                    // The signature has changed, but this package is in the system
9993                    // image...  let's recover!
9994                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9995                    // However...  if this package is part of a shared user, but it
9996                    // doesn't match the signature of the shared user, let's fail.
9997                    // What this means is that you can't change the signatures
9998                    // associated with an overall shared user, which doesn't seem all
9999                    // that unreasonable.
10000                    if (signatureCheckPs.sharedUser != null) {
10001                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10002                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10003                            throw new PackageManagerException(
10004                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10005                                    "Signature mismatch for shared user: "
10006                                            + pkgSetting.sharedUser);
10007                        }
10008                    }
10009                    // File a report about this.
10010                    String msg = "System package " + pkg.packageName
10011                            + " signature changed; retaining data.";
10012                    reportSettingsProblem(Log.WARN, msg);
10013                }
10014            }
10015
10016            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10017                // This package wants to adopt ownership of permissions from
10018                // another package.
10019                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10020                    final String origName = pkg.mAdoptPermissions.get(i);
10021                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10022                    if (orig != null) {
10023                        if (verifyPackageUpdateLPr(orig, pkg)) {
10024                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10025                                    + pkg.packageName);
10026                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10027                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10028                        }
10029                    }
10030                }
10031            }
10032        }
10033
10034        pkg.applicationInfo.processName = fixProcessName(
10035                pkg.applicationInfo.packageName,
10036                pkg.applicationInfo.processName);
10037
10038        if (pkg != mPlatformPackage) {
10039            // Get all of our default paths setup
10040            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10041        }
10042
10043        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10044
10045        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10046            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10047                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10048                derivePackageAbi(
10049                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
10050                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10051
10052                // Some system apps still use directory structure for native libraries
10053                // in which case we might end up not detecting abi solely based on apk
10054                // structure. Try to detect abi based on directory structure.
10055                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10056                        pkg.applicationInfo.primaryCpuAbi == null) {
10057                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10058                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10059                }
10060            } else {
10061                // This is not a first boot or an upgrade, don't bother deriving the
10062                // ABI during the scan. Instead, trust the value that was stored in the
10063                // package setting.
10064                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10065                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10066
10067                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10068
10069                if (DEBUG_ABI_SELECTION) {
10070                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10071                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10072                        pkg.applicationInfo.secondaryCpuAbi);
10073                }
10074            }
10075        } else {
10076            if ((scanFlags & SCAN_MOVE) != 0) {
10077                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10078                // but we already have this packages package info in the PackageSetting. We just
10079                // use that and derive the native library path based on the new codepath.
10080                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10081                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10082            }
10083
10084            // Set native library paths again. For moves, the path will be updated based on the
10085            // ABIs we've determined above. For non-moves, the path will be updated based on the
10086            // ABIs we determined during compilation, but the path will depend on the final
10087            // package path (after the rename away from the stage path).
10088            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10089        }
10090
10091        // This is a special case for the "system" package, where the ABI is
10092        // dictated by the zygote configuration (and init.rc). We should keep track
10093        // of this ABI so that we can deal with "normal" applications that run under
10094        // the same UID correctly.
10095        if (mPlatformPackage == pkg) {
10096            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10097                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10098        }
10099
10100        // If there's a mismatch between the abi-override in the package setting
10101        // and the abiOverride specified for the install. Warn about this because we
10102        // would've already compiled the app without taking the package setting into
10103        // account.
10104        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10105            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10106                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10107                        " for package " + pkg.packageName);
10108            }
10109        }
10110
10111        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10112        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10113        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10114
10115        // Copy the derived override back to the parsed package, so that we can
10116        // update the package settings accordingly.
10117        pkg.cpuAbiOverride = cpuAbiOverride;
10118
10119        if (DEBUG_ABI_SELECTION) {
10120            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10121                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10122                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10123        }
10124
10125        // Push the derived path down into PackageSettings so we know what to
10126        // clean up at uninstall time.
10127        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10128
10129        if (DEBUG_ABI_SELECTION) {
10130            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10131                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10132                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10133        }
10134
10135        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10136        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10137            // We don't do this here during boot because we can do it all
10138            // at once after scanning all existing packages.
10139            //
10140            // We also do this *before* we perform dexopt on this package, so that
10141            // we can avoid redundant dexopts, and also to make sure we've got the
10142            // code and package path correct.
10143            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10144        }
10145
10146        if (mFactoryTest && pkg.requestedPermissions.contains(
10147                android.Manifest.permission.FACTORY_TEST)) {
10148            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10149        }
10150
10151        if (isSystemApp(pkg)) {
10152            pkgSetting.isOrphaned = true;
10153        }
10154
10155        // Take care of first install / last update times.
10156        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10157        if (currentTime != 0) {
10158            if (pkgSetting.firstInstallTime == 0) {
10159                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10160            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10161                pkgSetting.lastUpdateTime = currentTime;
10162            }
10163        } else if (pkgSetting.firstInstallTime == 0) {
10164            // We need *something*.  Take time time stamp of the file.
10165            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10166        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10167            if (scanFileTime != pkgSetting.timeStamp) {
10168                // A package on the system image has changed; consider this
10169                // to be an update.
10170                pkgSetting.lastUpdateTime = scanFileTime;
10171            }
10172        }
10173        pkgSetting.setTimeStamp(scanFileTime);
10174
10175        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10176            if (nonMutatedPs != null) {
10177                synchronized (mPackages) {
10178                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10179                }
10180            }
10181        } else {
10182            final int userId = user == null ? 0 : user.getIdentifier();
10183            // Modify state for the given package setting
10184            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10185                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10186            if (pkgSetting.getInstantApp(userId)) {
10187                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10188            }
10189        }
10190        return pkg;
10191    }
10192
10193    /**
10194     * Applies policy to the parsed package based upon the given policy flags.
10195     * Ensures the package is in a good state.
10196     * <p>
10197     * Implementation detail: This method must NOT have any side effect. It would
10198     * ideally be static, but, it requires locks to read system state.
10199     */
10200    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10201        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10202            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10203            if (pkg.applicationInfo.isDirectBootAware()) {
10204                // we're direct boot aware; set for all components
10205                for (PackageParser.Service s : pkg.services) {
10206                    s.info.encryptionAware = s.info.directBootAware = true;
10207                }
10208                for (PackageParser.Provider p : pkg.providers) {
10209                    p.info.encryptionAware = p.info.directBootAware = true;
10210                }
10211                for (PackageParser.Activity a : pkg.activities) {
10212                    a.info.encryptionAware = a.info.directBootAware = true;
10213                }
10214                for (PackageParser.Activity r : pkg.receivers) {
10215                    r.info.encryptionAware = r.info.directBootAware = true;
10216                }
10217            }
10218        } else {
10219            // Only allow system apps to be flagged as core apps.
10220            pkg.coreApp = false;
10221            // clear flags not applicable to regular apps
10222            pkg.applicationInfo.privateFlags &=
10223                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10224            pkg.applicationInfo.privateFlags &=
10225                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10226        }
10227        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10228
10229        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10230            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10231        }
10232
10233        if (!isSystemApp(pkg)) {
10234            // Only system apps can use these features.
10235            pkg.mOriginalPackages = null;
10236            pkg.mRealPackage = null;
10237            pkg.mAdoptPermissions = null;
10238        }
10239    }
10240
10241    /**
10242     * Asserts the parsed package is valid according to the given policy. If the
10243     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10244     * <p>
10245     * Implementation detail: This method must NOT have any side effects. It would
10246     * ideally be static, but, it requires locks to read system state.
10247     *
10248     * @throws PackageManagerException If the package fails any of the validation checks
10249     */
10250    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10251            throws PackageManagerException {
10252        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10253            assertCodePolicy(pkg);
10254        }
10255
10256        if (pkg.applicationInfo.getCodePath() == null ||
10257                pkg.applicationInfo.getResourcePath() == null) {
10258            // Bail out. The resource and code paths haven't been set.
10259            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10260                    "Code and resource paths haven't been set correctly");
10261        }
10262
10263        // Make sure we're not adding any bogus keyset info
10264        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10265        ksms.assertScannedPackageValid(pkg);
10266
10267        synchronized (mPackages) {
10268            // The special "android" package can only be defined once
10269            if (pkg.packageName.equals("android")) {
10270                if (mAndroidApplication != null) {
10271                    Slog.w(TAG, "*************************************************");
10272                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10273                    Slog.w(TAG, " codePath=" + pkg.codePath);
10274                    Slog.w(TAG, "*************************************************");
10275                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10276                            "Core android package being redefined.  Skipping.");
10277                }
10278            }
10279
10280            // A package name must be unique; don't allow duplicates
10281            if (mPackages.containsKey(pkg.packageName)) {
10282                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10283                        "Application package " + pkg.packageName
10284                        + " already installed.  Skipping duplicate.");
10285            }
10286
10287            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10288                // Static libs have a synthetic package name containing the version
10289                // but we still want the base name to be unique.
10290                if (mPackages.containsKey(pkg.manifestPackageName)) {
10291                    throw new PackageManagerException(
10292                            "Duplicate static shared lib provider package");
10293                }
10294
10295                // Static shared libraries should have at least O target SDK
10296                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10297                    throw new PackageManagerException(
10298                            "Packages declaring static-shared libs must target O SDK or higher");
10299                }
10300
10301                // Package declaring static a shared lib cannot be instant apps
10302                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10303                    throw new PackageManagerException(
10304                            "Packages declaring static-shared libs cannot be instant apps");
10305                }
10306
10307                // Package declaring static a shared lib cannot be renamed since the package
10308                // name is synthetic and apps can't code around package manager internals.
10309                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10310                    throw new PackageManagerException(
10311                            "Packages declaring static-shared libs cannot be renamed");
10312                }
10313
10314                // Package declaring static a shared lib cannot declare child packages
10315                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10316                    throw new PackageManagerException(
10317                            "Packages declaring static-shared libs cannot have child packages");
10318                }
10319
10320                // Package declaring static a shared lib cannot declare dynamic libs
10321                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10322                    throw new PackageManagerException(
10323                            "Packages declaring static-shared libs cannot declare dynamic libs");
10324                }
10325
10326                // Package declaring static a shared lib cannot declare shared users
10327                if (pkg.mSharedUserId != null) {
10328                    throw new PackageManagerException(
10329                            "Packages declaring static-shared libs cannot declare shared users");
10330                }
10331
10332                // Static shared libs cannot declare activities
10333                if (!pkg.activities.isEmpty()) {
10334                    throw new PackageManagerException(
10335                            "Static shared libs cannot declare activities");
10336                }
10337
10338                // Static shared libs cannot declare services
10339                if (!pkg.services.isEmpty()) {
10340                    throw new PackageManagerException(
10341                            "Static shared libs cannot declare services");
10342                }
10343
10344                // Static shared libs cannot declare providers
10345                if (!pkg.providers.isEmpty()) {
10346                    throw new PackageManagerException(
10347                            "Static shared libs cannot declare content providers");
10348                }
10349
10350                // Static shared libs cannot declare receivers
10351                if (!pkg.receivers.isEmpty()) {
10352                    throw new PackageManagerException(
10353                            "Static shared libs cannot declare broadcast receivers");
10354                }
10355
10356                // Static shared libs cannot declare permission groups
10357                if (!pkg.permissionGroups.isEmpty()) {
10358                    throw new PackageManagerException(
10359                            "Static shared libs cannot declare permission groups");
10360                }
10361
10362                // Static shared libs cannot declare permissions
10363                if (!pkg.permissions.isEmpty()) {
10364                    throw new PackageManagerException(
10365                            "Static shared libs cannot declare permissions");
10366                }
10367
10368                // Static shared libs cannot declare protected broadcasts
10369                if (pkg.protectedBroadcasts != null) {
10370                    throw new PackageManagerException(
10371                            "Static shared libs cannot declare protected broadcasts");
10372                }
10373
10374                // Static shared libs cannot be overlay targets
10375                if (pkg.mOverlayTarget != null) {
10376                    throw new PackageManagerException(
10377                            "Static shared libs cannot be overlay targets");
10378                }
10379
10380                // The version codes must be ordered as lib versions
10381                int minVersionCode = Integer.MIN_VALUE;
10382                int maxVersionCode = Integer.MAX_VALUE;
10383
10384                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10385                        pkg.staticSharedLibName);
10386                if (versionedLib != null) {
10387                    final int versionCount = versionedLib.size();
10388                    for (int i = 0; i < versionCount; i++) {
10389                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10390                        // TODO: We will change version code to long, so in the new API it is long
10391                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
10392                                .getVersionCode();
10393                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
10394                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10395                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
10396                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10397                        } else {
10398                            minVersionCode = maxVersionCode = libVersionCode;
10399                            break;
10400                        }
10401                    }
10402                }
10403                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
10404                    throw new PackageManagerException("Static shared"
10405                            + " lib version codes must be ordered as lib versions");
10406                }
10407            }
10408
10409            // Only privileged apps and updated privileged apps can add child packages.
10410            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10411                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
10412                    throw new PackageManagerException("Only privileged apps can add child "
10413                            + "packages. Ignoring package " + pkg.packageName);
10414                }
10415                final int childCount = pkg.childPackages.size();
10416                for (int i = 0; i < childCount; i++) {
10417                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10418                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10419                            childPkg.packageName)) {
10420                        throw new PackageManagerException("Can't override child of "
10421                                + "another disabled app. Ignoring package " + pkg.packageName);
10422                    }
10423                }
10424            }
10425
10426            // If we're only installing presumed-existing packages, require that the
10427            // scanned APK is both already known and at the path previously established
10428            // for it.  Previously unknown packages we pick up normally, but if we have an
10429            // a priori expectation about this package's install presence, enforce it.
10430            // With a singular exception for new system packages. When an OTA contains
10431            // a new system package, we allow the codepath to change from a system location
10432            // to the user-installed location. If we don't allow this change, any newer,
10433            // user-installed version of the application will be ignored.
10434            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10435                if (mExpectingBetter.containsKey(pkg.packageName)) {
10436                    logCriticalInfo(Log.WARN,
10437                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10438                } else {
10439                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10440                    if (known != null) {
10441                        if (DEBUG_PACKAGE_SCANNING) {
10442                            Log.d(TAG, "Examining " + pkg.codePath
10443                                    + " and requiring known paths " + known.codePathString
10444                                    + " & " + known.resourcePathString);
10445                        }
10446                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10447                                || !pkg.applicationInfo.getResourcePath().equals(
10448                                        known.resourcePathString)) {
10449                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10450                                    "Application package " + pkg.packageName
10451                                    + " found at " + pkg.applicationInfo.getCodePath()
10452                                    + " but expected at " + known.codePathString
10453                                    + "; ignoring.");
10454                        }
10455                    }
10456                }
10457            }
10458
10459            // Verify that this new package doesn't have any content providers
10460            // that conflict with existing packages.  Only do this if the
10461            // package isn't already installed, since we don't want to break
10462            // things that are installed.
10463            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10464                final int N = pkg.providers.size();
10465                int i;
10466                for (i=0; i<N; i++) {
10467                    PackageParser.Provider p = pkg.providers.get(i);
10468                    if (p.info.authority != null) {
10469                        String names[] = p.info.authority.split(";");
10470                        for (int j = 0; j < names.length; j++) {
10471                            if (mProvidersByAuthority.containsKey(names[j])) {
10472                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10473                                final String otherPackageName =
10474                                        ((other != null && other.getComponentName() != null) ?
10475                                                other.getComponentName().getPackageName() : "?");
10476                                throw new PackageManagerException(
10477                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10478                                        "Can't install because provider name " + names[j]
10479                                                + " (in package " + pkg.applicationInfo.packageName
10480                                                + ") is already used by " + otherPackageName);
10481                            }
10482                        }
10483                    }
10484                }
10485            }
10486        }
10487    }
10488
10489    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10490            int type, String declaringPackageName, int declaringVersionCode) {
10491        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10492        if (versionedLib == null) {
10493            versionedLib = new SparseArray<>();
10494            mSharedLibraries.put(name, versionedLib);
10495            if (type == SharedLibraryInfo.TYPE_STATIC) {
10496                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10497            }
10498        } else if (versionedLib.indexOfKey(version) >= 0) {
10499            return false;
10500        }
10501        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10502                version, type, declaringPackageName, declaringVersionCode);
10503        versionedLib.put(version, libEntry);
10504        return true;
10505    }
10506
10507    private boolean removeSharedLibraryLPw(String name, int version) {
10508        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10509        if (versionedLib == null) {
10510            return false;
10511        }
10512        final int libIdx = versionedLib.indexOfKey(version);
10513        if (libIdx < 0) {
10514            return false;
10515        }
10516        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10517        versionedLib.remove(version);
10518        if (versionedLib.size() <= 0) {
10519            mSharedLibraries.remove(name);
10520            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10521                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10522                        .getPackageName());
10523            }
10524        }
10525        return true;
10526    }
10527
10528    /**
10529     * Adds a scanned package to the system. When this method is finished, the package will
10530     * be available for query, resolution, etc...
10531     */
10532    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10533            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10534        final String pkgName = pkg.packageName;
10535        if (mCustomResolverComponentName != null &&
10536                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10537            setUpCustomResolverActivity(pkg);
10538        }
10539
10540        if (pkg.packageName.equals("android")) {
10541            synchronized (mPackages) {
10542                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10543                    // Set up information for our fall-back user intent resolution activity.
10544                    mPlatformPackage = pkg;
10545                    pkg.mVersionCode = mSdkVersion;
10546                    mAndroidApplication = pkg.applicationInfo;
10547                    if (!mResolverReplaced) {
10548                        mResolveActivity.applicationInfo = mAndroidApplication;
10549                        mResolveActivity.name = ResolverActivity.class.getName();
10550                        mResolveActivity.packageName = mAndroidApplication.packageName;
10551                        mResolveActivity.processName = "system:ui";
10552                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10553                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10554                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10555                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10556                        mResolveActivity.exported = true;
10557                        mResolveActivity.enabled = true;
10558                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10559                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10560                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10561                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10562                                | ActivityInfo.CONFIG_ORIENTATION
10563                                | ActivityInfo.CONFIG_KEYBOARD
10564                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10565                        mResolveInfo.activityInfo = mResolveActivity;
10566                        mResolveInfo.priority = 0;
10567                        mResolveInfo.preferredOrder = 0;
10568                        mResolveInfo.match = 0;
10569                        mResolveComponentName = new ComponentName(
10570                                mAndroidApplication.packageName, mResolveActivity.name);
10571                    }
10572                }
10573            }
10574        }
10575
10576        ArrayList<PackageParser.Package> clientLibPkgs = null;
10577        // writer
10578        synchronized (mPackages) {
10579            boolean hasStaticSharedLibs = false;
10580
10581            // Any app can add new static shared libraries
10582            if (pkg.staticSharedLibName != null) {
10583                // Static shared libs don't allow renaming as they have synthetic package
10584                // names to allow install of multiple versions, so use name from manifest.
10585                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10586                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10587                        pkg.manifestPackageName, pkg.mVersionCode)) {
10588                    hasStaticSharedLibs = true;
10589                } else {
10590                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10591                                + pkg.staticSharedLibName + " already exists; skipping");
10592                }
10593                // Static shared libs cannot be updated once installed since they
10594                // use synthetic package name which includes the version code, so
10595                // not need to update other packages's shared lib dependencies.
10596            }
10597
10598            if (!hasStaticSharedLibs
10599                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10600                // Only system apps can add new dynamic shared libraries.
10601                if (pkg.libraryNames != null) {
10602                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10603                        String name = pkg.libraryNames.get(i);
10604                        boolean allowed = false;
10605                        if (pkg.isUpdatedSystemApp()) {
10606                            // New library entries can only be added through the
10607                            // system image.  This is important to get rid of a lot
10608                            // of nasty edge cases: for example if we allowed a non-
10609                            // system update of the app to add a library, then uninstalling
10610                            // the update would make the library go away, and assumptions
10611                            // we made such as through app install filtering would now
10612                            // have allowed apps on the device which aren't compatible
10613                            // with it.  Better to just have the restriction here, be
10614                            // conservative, and create many fewer cases that can negatively
10615                            // impact the user experience.
10616                            final PackageSetting sysPs = mSettings
10617                                    .getDisabledSystemPkgLPr(pkg.packageName);
10618                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10619                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10620                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10621                                        allowed = true;
10622                                        break;
10623                                    }
10624                                }
10625                            }
10626                        } else {
10627                            allowed = true;
10628                        }
10629                        if (allowed) {
10630                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10631                                    SharedLibraryInfo.VERSION_UNDEFINED,
10632                                    SharedLibraryInfo.TYPE_DYNAMIC,
10633                                    pkg.packageName, pkg.mVersionCode)) {
10634                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10635                                        + name + " already exists; skipping");
10636                            }
10637                        } else {
10638                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10639                                    + name + " that is not declared on system image; skipping");
10640                        }
10641                    }
10642
10643                    if ((scanFlags & SCAN_BOOTING) == 0) {
10644                        // If we are not booting, we need to update any applications
10645                        // that are clients of our shared library.  If we are booting,
10646                        // this will all be done once the scan is complete.
10647                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10648                    }
10649                }
10650            }
10651        }
10652
10653        if ((scanFlags & SCAN_BOOTING) != 0) {
10654            // No apps can run during boot scan, so they don't need to be frozen
10655        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10656            // Caller asked to not kill app, so it's probably not frozen
10657        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10658            // Caller asked us to ignore frozen check for some reason; they
10659            // probably didn't know the package name
10660        } else {
10661            // We're doing major surgery on this package, so it better be frozen
10662            // right now to keep it from launching
10663            checkPackageFrozen(pkgName);
10664        }
10665
10666        // Also need to kill any apps that are dependent on the library.
10667        if (clientLibPkgs != null) {
10668            for (int i=0; i<clientLibPkgs.size(); i++) {
10669                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10670                killApplication(clientPkg.applicationInfo.packageName,
10671                        clientPkg.applicationInfo.uid, "update lib");
10672            }
10673        }
10674
10675        // writer
10676        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10677
10678        synchronized (mPackages) {
10679            // We don't expect installation to fail beyond this point
10680
10681            // Add the new setting to mSettings
10682            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10683            // Add the new setting to mPackages
10684            mPackages.put(pkg.applicationInfo.packageName, pkg);
10685            // Make sure we don't accidentally delete its data.
10686            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10687            while (iter.hasNext()) {
10688                PackageCleanItem item = iter.next();
10689                if (pkgName.equals(item.packageName)) {
10690                    iter.remove();
10691                }
10692            }
10693
10694            // Add the package's KeySets to the global KeySetManagerService
10695            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10696            ksms.addScannedPackageLPw(pkg);
10697
10698            int N = pkg.providers.size();
10699            StringBuilder r = null;
10700            int i;
10701            for (i=0; i<N; i++) {
10702                PackageParser.Provider p = pkg.providers.get(i);
10703                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10704                        p.info.processName);
10705                mProviders.addProvider(p);
10706                p.syncable = p.info.isSyncable;
10707                if (p.info.authority != null) {
10708                    String names[] = p.info.authority.split(";");
10709                    p.info.authority = null;
10710                    for (int j = 0; j < names.length; j++) {
10711                        if (j == 1 && p.syncable) {
10712                            // We only want the first authority for a provider to possibly be
10713                            // syncable, so if we already added this provider using a different
10714                            // authority clear the syncable flag. We copy the provider before
10715                            // changing it because the mProviders object contains a reference
10716                            // to a provider that we don't want to change.
10717                            // Only do this for the second authority since the resulting provider
10718                            // object can be the same for all future authorities for this provider.
10719                            p = new PackageParser.Provider(p);
10720                            p.syncable = false;
10721                        }
10722                        if (!mProvidersByAuthority.containsKey(names[j])) {
10723                            mProvidersByAuthority.put(names[j], p);
10724                            if (p.info.authority == null) {
10725                                p.info.authority = names[j];
10726                            } else {
10727                                p.info.authority = p.info.authority + ";" + names[j];
10728                            }
10729                            if (DEBUG_PACKAGE_SCANNING) {
10730                                if (chatty)
10731                                    Log.d(TAG, "Registered content provider: " + names[j]
10732                                            + ", className = " + p.info.name + ", isSyncable = "
10733                                            + p.info.isSyncable);
10734                            }
10735                        } else {
10736                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10737                            Slog.w(TAG, "Skipping provider name " + names[j] +
10738                                    " (in package " + pkg.applicationInfo.packageName +
10739                                    "): name already used by "
10740                                    + ((other != null && other.getComponentName() != null)
10741                                            ? other.getComponentName().getPackageName() : "?"));
10742                        }
10743                    }
10744                }
10745                if (chatty) {
10746                    if (r == null) {
10747                        r = new StringBuilder(256);
10748                    } else {
10749                        r.append(' ');
10750                    }
10751                    r.append(p.info.name);
10752                }
10753            }
10754            if (r != null) {
10755                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10756            }
10757
10758            N = pkg.services.size();
10759            r = null;
10760            for (i=0; i<N; i++) {
10761                PackageParser.Service s = pkg.services.get(i);
10762                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10763                        s.info.processName);
10764                mServices.addService(s);
10765                if (chatty) {
10766                    if (r == null) {
10767                        r = new StringBuilder(256);
10768                    } else {
10769                        r.append(' ');
10770                    }
10771                    r.append(s.info.name);
10772                }
10773            }
10774            if (r != null) {
10775                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10776            }
10777
10778            N = pkg.receivers.size();
10779            r = null;
10780            for (i=0; i<N; i++) {
10781                PackageParser.Activity a = pkg.receivers.get(i);
10782                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10783                        a.info.processName);
10784                mReceivers.addActivity(a, "receiver");
10785                if (chatty) {
10786                    if (r == null) {
10787                        r = new StringBuilder(256);
10788                    } else {
10789                        r.append(' ');
10790                    }
10791                    r.append(a.info.name);
10792                }
10793            }
10794            if (r != null) {
10795                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10796            }
10797
10798            N = pkg.activities.size();
10799            r = null;
10800            for (i=0; i<N; i++) {
10801                PackageParser.Activity a = pkg.activities.get(i);
10802                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10803                        a.info.processName);
10804                mActivities.addActivity(a, "activity");
10805                if (chatty) {
10806                    if (r == null) {
10807                        r = new StringBuilder(256);
10808                    } else {
10809                        r.append(' ');
10810                    }
10811                    r.append(a.info.name);
10812                }
10813            }
10814            if (r != null) {
10815                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10816            }
10817
10818            N = pkg.permissionGroups.size();
10819            r = null;
10820            for (i=0; i<N; i++) {
10821                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10822                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10823                final String curPackageName = cur == null ? null : cur.info.packageName;
10824                // Dont allow ephemeral apps to define new permission groups.
10825                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10826                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10827                            + pg.info.packageName
10828                            + " ignored: instant apps cannot define new permission groups.");
10829                    continue;
10830                }
10831                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10832                if (cur == null || isPackageUpdate) {
10833                    mPermissionGroups.put(pg.info.name, pg);
10834                    if (chatty) {
10835                        if (r == null) {
10836                            r = new StringBuilder(256);
10837                        } else {
10838                            r.append(' ');
10839                        }
10840                        if (isPackageUpdate) {
10841                            r.append("UPD:");
10842                        }
10843                        r.append(pg.info.name);
10844                    }
10845                } else {
10846                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10847                            + pg.info.packageName + " ignored: original from "
10848                            + cur.info.packageName);
10849                    if (chatty) {
10850                        if (r == null) {
10851                            r = new StringBuilder(256);
10852                        } else {
10853                            r.append(' ');
10854                        }
10855                        r.append("DUP:");
10856                        r.append(pg.info.name);
10857                    }
10858                }
10859            }
10860            if (r != null) {
10861                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10862            }
10863
10864            N = pkg.permissions.size();
10865            r = null;
10866            for (i=0; i<N; i++) {
10867                PackageParser.Permission p = pkg.permissions.get(i);
10868
10869                // Dont allow ephemeral apps to define new permissions.
10870                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10871                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10872                            + p.info.packageName
10873                            + " ignored: instant apps cannot define new permissions.");
10874                    continue;
10875                }
10876
10877                // Assume by default that we did not install this permission into the system.
10878                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10879
10880                // Now that permission groups have a special meaning, we ignore permission
10881                // groups for legacy apps to prevent unexpected behavior. In particular,
10882                // permissions for one app being granted to someone just because they happen
10883                // to be in a group defined by another app (before this had no implications).
10884                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10885                    p.group = mPermissionGroups.get(p.info.group);
10886                    // Warn for a permission in an unknown group.
10887                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
10888                        Slog.i(TAG, "Permission " + p.info.name + " from package "
10889                                + p.info.packageName + " in an unknown group " + p.info.group);
10890                    }
10891                }
10892
10893                ArrayMap<String, BasePermission> permissionMap =
10894                        p.tree ? mSettings.mPermissionTrees
10895                                : mSettings.mPermissions;
10896                BasePermission bp = permissionMap.get(p.info.name);
10897
10898                // Allow system apps to redefine non-system permissions
10899                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10900                    final boolean currentOwnerIsSystem = (bp.perm != null
10901                            && isSystemApp(bp.perm.owner));
10902                    if (isSystemApp(p.owner)) {
10903                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10904                            // It's a built-in permission and no owner, take ownership now
10905                            bp.packageSetting = pkgSetting;
10906                            bp.perm = p;
10907                            bp.uid = pkg.applicationInfo.uid;
10908                            bp.sourcePackage = p.info.packageName;
10909                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10910                        } else if (!currentOwnerIsSystem) {
10911                            String msg = "New decl " + p.owner + " of permission  "
10912                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10913                            reportSettingsProblem(Log.WARN, msg);
10914                            bp = null;
10915                        }
10916                    }
10917                }
10918
10919                if (bp == null) {
10920                    bp = new BasePermission(p.info.name, p.info.packageName,
10921                            BasePermission.TYPE_NORMAL);
10922                    permissionMap.put(p.info.name, bp);
10923                }
10924
10925                if (bp.perm == null) {
10926                    if (bp.sourcePackage == null
10927                            || bp.sourcePackage.equals(p.info.packageName)) {
10928                        BasePermission tree = findPermissionTreeLP(p.info.name);
10929                        if (tree == null
10930                                || tree.sourcePackage.equals(p.info.packageName)) {
10931                            bp.packageSetting = pkgSetting;
10932                            bp.perm = p;
10933                            bp.uid = pkg.applicationInfo.uid;
10934                            bp.sourcePackage = p.info.packageName;
10935                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10936                            if (chatty) {
10937                                if (r == null) {
10938                                    r = new StringBuilder(256);
10939                                } else {
10940                                    r.append(' ');
10941                                }
10942                                r.append(p.info.name);
10943                            }
10944                        } else {
10945                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10946                                    + p.info.packageName + " ignored: base tree "
10947                                    + tree.name + " is from package "
10948                                    + tree.sourcePackage);
10949                        }
10950                    } else {
10951                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10952                                + p.info.packageName + " ignored: original from "
10953                                + bp.sourcePackage);
10954                    }
10955                } else if (chatty) {
10956                    if (r == null) {
10957                        r = new StringBuilder(256);
10958                    } else {
10959                        r.append(' ');
10960                    }
10961                    r.append("DUP:");
10962                    r.append(p.info.name);
10963                }
10964                if (bp.perm == p) {
10965                    bp.protectionLevel = p.info.protectionLevel;
10966                }
10967            }
10968
10969            if (r != null) {
10970                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10971            }
10972
10973            N = pkg.instrumentation.size();
10974            r = null;
10975            for (i=0; i<N; i++) {
10976                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10977                a.info.packageName = pkg.applicationInfo.packageName;
10978                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10979                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10980                a.info.splitNames = pkg.splitNames;
10981                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10982                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10983                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10984                a.info.dataDir = pkg.applicationInfo.dataDir;
10985                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10986                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10987                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10988                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10989                mInstrumentation.put(a.getComponentName(), a);
10990                if (chatty) {
10991                    if (r == null) {
10992                        r = new StringBuilder(256);
10993                    } else {
10994                        r.append(' ');
10995                    }
10996                    r.append(a.info.name);
10997                }
10998            }
10999            if (r != null) {
11000                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11001            }
11002
11003            if (pkg.protectedBroadcasts != null) {
11004                N = pkg.protectedBroadcasts.size();
11005                for (i=0; i<N; i++) {
11006                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11007                }
11008            }
11009        }
11010
11011        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11012    }
11013
11014    /**
11015     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11016     * is derived purely on the basis of the contents of {@code scanFile} and
11017     * {@code cpuAbiOverride}.
11018     *
11019     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11020     */
11021    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11022                                 String cpuAbiOverride, boolean extractLibs,
11023                                 File appLib32InstallDir)
11024            throws PackageManagerException {
11025        // Give ourselves some initial paths; we'll come back for another
11026        // pass once we've determined ABI below.
11027        setNativeLibraryPaths(pkg, appLib32InstallDir);
11028
11029        // We would never need to extract libs for forward-locked and external packages,
11030        // since the container service will do it for us. We shouldn't attempt to
11031        // extract libs from system app when it was not updated.
11032        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11033                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11034            extractLibs = false;
11035        }
11036
11037        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11038        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11039
11040        NativeLibraryHelper.Handle handle = null;
11041        try {
11042            handle = NativeLibraryHelper.Handle.create(pkg);
11043            // TODO(multiArch): This can be null for apps that didn't go through the
11044            // usual installation process. We can calculate it again, like we
11045            // do during install time.
11046            //
11047            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11048            // unnecessary.
11049            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11050
11051            // Null out the abis so that they can be recalculated.
11052            pkg.applicationInfo.primaryCpuAbi = null;
11053            pkg.applicationInfo.secondaryCpuAbi = null;
11054            if (isMultiArch(pkg.applicationInfo)) {
11055                // Warn if we've set an abiOverride for multi-lib packages..
11056                // By definition, we need to copy both 32 and 64 bit libraries for
11057                // such packages.
11058                if (pkg.cpuAbiOverride != null
11059                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11060                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11061                }
11062
11063                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11064                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11065                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11066                    if (extractLibs) {
11067                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11068                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11069                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11070                                useIsaSpecificSubdirs);
11071                    } else {
11072                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11073                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11074                    }
11075                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11076                }
11077
11078                maybeThrowExceptionForMultiArchCopy(
11079                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11080
11081                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11082                    if (extractLibs) {
11083                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11084                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11085                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11086                                useIsaSpecificSubdirs);
11087                    } else {
11088                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11089                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11090                    }
11091                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11092                }
11093
11094                maybeThrowExceptionForMultiArchCopy(
11095                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11096
11097                if (abi64 >= 0) {
11098                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11099                }
11100
11101                if (abi32 >= 0) {
11102                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11103                    if (abi64 >= 0) {
11104                        if (pkg.use32bitAbi) {
11105                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11106                            pkg.applicationInfo.primaryCpuAbi = abi;
11107                        } else {
11108                            pkg.applicationInfo.secondaryCpuAbi = abi;
11109                        }
11110                    } else {
11111                        pkg.applicationInfo.primaryCpuAbi = abi;
11112                    }
11113                }
11114
11115            } else {
11116                String[] abiList = (cpuAbiOverride != null) ?
11117                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11118
11119                // Enable gross and lame hacks for apps that are built with old
11120                // SDK tools. We must scan their APKs for renderscript bitcode and
11121                // not launch them if it's present. Don't bother checking on devices
11122                // that don't have 64 bit support.
11123                boolean needsRenderScriptOverride = false;
11124                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11125                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11126                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11127                    needsRenderScriptOverride = true;
11128                }
11129
11130                final int copyRet;
11131                if (extractLibs) {
11132                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11133                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11134                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11135                } else {
11136                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11137                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11138                }
11139                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11140
11141                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11142                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11143                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11144                }
11145
11146                if (copyRet >= 0) {
11147                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11148                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11149                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11150                } else if (needsRenderScriptOverride) {
11151                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11152                }
11153            }
11154        } catch (IOException ioe) {
11155            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11156        } finally {
11157            IoUtils.closeQuietly(handle);
11158        }
11159
11160        // Now that we've calculated the ABIs and determined if it's an internal app,
11161        // we will go ahead and populate the nativeLibraryPath.
11162        setNativeLibraryPaths(pkg, appLib32InstallDir);
11163    }
11164
11165    /**
11166     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11167     * i.e, so that all packages can be run inside a single process if required.
11168     *
11169     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11170     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11171     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11172     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11173     * updating a package that belongs to a shared user.
11174     *
11175     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11176     * adds unnecessary complexity.
11177     */
11178    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11179            PackageParser.Package scannedPackage) {
11180        String requiredInstructionSet = null;
11181        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11182            requiredInstructionSet = VMRuntime.getInstructionSet(
11183                     scannedPackage.applicationInfo.primaryCpuAbi);
11184        }
11185
11186        PackageSetting requirer = null;
11187        for (PackageSetting ps : packagesForUser) {
11188            // If packagesForUser contains scannedPackage, we skip it. This will happen
11189            // when scannedPackage is an update of an existing package. Without this check,
11190            // we will never be able to change the ABI of any package belonging to a shared
11191            // user, even if it's compatible with other packages.
11192            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11193                if (ps.primaryCpuAbiString == null) {
11194                    continue;
11195                }
11196
11197                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11198                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11199                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11200                    // this but there's not much we can do.
11201                    String errorMessage = "Instruction set mismatch, "
11202                            + ((requirer == null) ? "[caller]" : requirer)
11203                            + " requires " + requiredInstructionSet + " whereas " + ps
11204                            + " requires " + instructionSet;
11205                    Slog.w(TAG, errorMessage);
11206                }
11207
11208                if (requiredInstructionSet == null) {
11209                    requiredInstructionSet = instructionSet;
11210                    requirer = ps;
11211                }
11212            }
11213        }
11214
11215        if (requiredInstructionSet != null) {
11216            String adjustedAbi;
11217            if (requirer != null) {
11218                // requirer != null implies that either scannedPackage was null or that scannedPackage
11219                // did not require an ABI, in which case we have to adjust scannedPackage to match
11220                // the ABI of the set (which is the same as requirer's ABI)
11221                adjustedAbi = requirer.primaryCpuAbiString;
11222                if (scannedPackage != null) {
11223                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11224                }
11225            } else {
11226                // requirer == null implies that we're updating all ABIs in the set to
11227                // match scannedPackage.
11228                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11229            }
11230
11231            for (PackageSetting ps : packagesForUser) {
11232                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11233                    if (ps.primaryCpuAbiString != null) {
11234                        continue;
11235                    }
11236
11237                    ps.primaryCpuAbiString = adjustedAbi;
11238                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11239                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11240                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11241                        if (DEBUG_ABI_SELECTION) {
11242                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11243                                    + " (requirer="
11244                                    + (requirer != null ? requirer.pkg : "null")
11245                                    + ", scannedPackage="
11246                                    + (scannedPackage != null ? scannedPackage : "null")
11247                                    + ")");
11248                        }
11249                        try {
11250                            mInstaller.rmdex(ps.codePathString,
11251                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11252                        } catch (InstallerException ignored) {
11253                        }
11254                    }
11255                }
11256            }
11257        }
11258    }
11259
11260    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11261        synchronized (mPackages) {
11262            mResolverReplaced = true;
11263            // Set up information for custom user intent resolution activity.
11264            mResolveActivity.applicationInfo = pkg.applicationInfo;
11265            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11266            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11267            mResolveActivity.processName = pkg.applicationInfo.packageName;
11268            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11269            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11270                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11271            mResolveActivity.theme = 0;
11272            mResolveActivity.exported = true;
11273            mResolveActivity.enabled = true;
11274            mResolveInfo.activityInfo = mResolveActivity;
11275            mResolveInfo.priority = 0;
11276            mResolveInfo.preferredOrder = 0;
11277            mResolveInfo.match = 0;
11278            mResolveComponentName = mCustomResolverComponentName;
11279            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11280                    mResolveComponentName);
11281        }
11282    }
11283
11284    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11285        if (installerActivity == null) {
11286            if (DEBUG_EPHEMERAL) {
11287                Slog.d(TAG, "Clear ephemeral installer activity");
11288            }
11289            mInstantAppInstallerActivity = null;
11290            return;
11291        }
11292
11293        if (DEBUG_EPHEMERAL) {
11294            Slog.d(TAG, "Set ephemeral installer activity: "
11295                    + installerActivity.getComponentName());
11296        }
11297        // Set up information for ephemeral installer activity
11298        mInstantAppInstallerActivity = installerActivity;
11299        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11300                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11301        mInstantAppInstallerActivity.exported = true;
11302        mInstantAppInstallerActivity.enabled = true;
11303        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11304        mInstantAppInstallerInfo.priority = 0;
11305        mInstantAppInstallerInfo.preferredOrder = 1;
11306        mInstantAppInstallerInfo.isDefault = true;
11307        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11308                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11309    }
11310
11311    private static String calculateBundledApkRoot(final String codePathString) {
11312        final File codePath = new File(codePathString);
11313        final File codeRoot;
11314        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11315            codeRoot = Environment.getRootDirectory();
11316        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11317            codeRoot = Environment.getOemDirectory();
11318        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11319            codeRoot = Environment.getVendorDirectory();
11320        } else {
11321            // Unrecognized code path; take its top real segment as the apk root:
11322            // e.g. /something/app/blah.apk => /something
11323            try {
11324                File f = codePath.getCanonicalFile();
11325                File parent = f.getParentFile();    // non-null because codePath is a file
11326                File tmp;
11327                while ((tmp = parent.getParentFile()) != null) {
11328                    f = parent;
11329                    parent = tmp;
11330                }
11331                codeRoot = f;
11332                Slog.w(TAG, "Unrecognized code path "
11333                        + codePath + " - using " + codeRoot);
11334            } catch (IOException e) {
11335                // Can't canonicalize the code path -- shenanigans?
11336                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11337                return Environment.getRootDirectory().getPath();
11338            }
11339        }
11340        return codeRoot.getPath();
11341    }
11342
11343    /**
11344     * Derive and set the location of native libraries for the given package,
11345     * which varies depending on where and how the package was installed.
11346     */
11347    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11348        final ApplicationInfo info = pkg.applicationInfo;
11349        final String codePath = pkg.codePath;
11350        final File codeFile = new File(codePath);
11351        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11352        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11353
11354        info.nativeLibraryRootDir = null;
11355        info.nativeLibraryRootRequiresIsa = false;
11356        info.nativeLibraryDir = null;
11357        info.secondaryNativeLibraryDir = null;
11358
11359        if (isApkFile(codeFile)) {
11360            // Monolithic install
11361            if (bundledApp) {
11362                // If "/system/lib64/apkname" exists, assume that is the per-package
11363                // native library directory to use; otherwise use "/system/lib/apkname".
11364                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11365                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11366                        getPrimaryInstructionSet(info));
11367
11368                // This is a bundled system app so choose the path based on the ABI.
11369                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11370                // is just the default path.
11371                final String apkName = deriveCodePathName(codePath);
11372                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11373                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11374                        apkName).getAbsolutePath();
11375
11376                if (info.secondaryCpuAbi != null) {
11377                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11378                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11379                            secondaryLibDir, apkName).getAbsolutePath();
11380                }
11381            } else if (asecApp) {
11382                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11383                        .getAbsolutePath();
11384            } else {
11385                final String apkName = deriveCodePathName(codePath);
11386                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11387                        .getAbsolutePath();
11388            }
11389
11390            info.nativeLibraryRootRequiresIsa = false;
11391            info.nativeLibraryDir = info.nativeLibraryRootDir;
11392        } else {
11393            // Cluster install
11394            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11395            info.nativeLibraryRootRequiresIsa = true;
11396
11397            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11398                    getPrimaryInstructionSet(info)).getAbsolutePath();
11399
11400            if (info.secondaryCpuAbi != null) {
11401                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11402                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11403            }
11404        }
11405    }
11406
11407    /**
11408     * Calculate the abis and roots for a bundled app. These can uniquely
11409     * be determined from the contents of the system partition, i.e whether
11410     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11411     * of this information, and instead assume that the system was built
11412     * sensibly.
11413     */
11414    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11415                                           PackageSetting pkgSetting) {
11416        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11417
11418        // If "/system/lib64/apkname" exists, assume that is the per-package
11419        // native library directory to use; otherwise use "/system/lib/apkname".
11420        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11421        setBundledAppAbi(pkg, apkRoot, apkName);
11422        // pkgSetting might be null during rescan following uninstall of updates
11423        // to a bundled app, so accommodate that possibility.  The settings in
11424        // that case will be established later from the parsed package.
11425        //
11426        // If the settings aren't null, sync them up with what we've just derived.
11427        // note that apkRoot isn't stored in the package settings.
11428        if (pkgSetting != null) {
11429            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11430            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11431        }
11432    }
11433
11434    /**
11435     * Deduces the ABI of a bundled app and sets the relevant fields on the
11436     * parsed pkg object.
11437     *
11438     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11439     *        under which system libraries are installed.
11440     * @param apkName the name of the installed package.
11441     */
11442    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11443        final File codeFile = new File(pkg.codePath);
11444
11445        final boolean has64BitLibs;
11446        final boolean has32BitLibs;
11447        if (isApkFile(codeFile)) {
11448            // Monolithic install
11449            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11450            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11451        } else {
11452            // Cluster install
11453            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11454            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11455                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11456                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11457                has64BitLibs = (new File(rootDir, isa)).exists();
11458            } else {
11459                has64BitLibs = false;
11460            }
11461            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11462                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11463                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11464                has32BitLibs = (new File(rootDir, isa)).exists();
11465            } else {
11466                has32BitLibs = false;
11467            }
11468        }
11469
11470        if (has64BitLibs && !has32BitLibs) {
11471            // The package has 64 bit libs, but not 32 bit libs. Its primary
11472            // ABI should be 64 bit. We can safely assume here that the bundled
11473            // native libraries correspond to the most preferred ABI in the list.
11474
11475            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11476            pkg.applicationInfo.secondaryCpuAbi = null;
11477        } else if (has32BitLibs && !has64BitLibs) {
11478            // The package has 32 bit libs but not 64 bit libs. Its primary
11479            // ABI should be 32 bit.
11480
11481            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11482            pkg.applicationInfo.secondaryCpuAbi = null;
11483        } else if (has32BitLibs && has64BitLibs) {
11484            // The application has both 64 and 32 bit bundled libraries. We check
11485            // here that the app declares multiArch support, and warn if it doesn't.
11486            //
11487            // We will be lenient here and record both ABIs. The primary will be the
11488            // ABI that's higher on the list, i.e, a device that's configured to prefer
11489            // 64 bit apps will see a 64 bit primary ABI,
11490
11491            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11492                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11493            }
11494
11495            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11496                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11497                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11498            } else {
11499                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11500                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11501            }
11502        } else {
11503            pkg.applicationInfo.primaryCpuAbi = null;
11504            pkg.applicationInfo.secondaryCpuAbi = null;
11505        }
11506    }
11507
11508    private void killApplication(String pkgName, int appId, String reason) {
11509        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11510    }
11511
11512    private void killApplication(String pkgName, int appId, int userId, String reason) {
11513        // Request the ActivityManager to kill the process(only for existing packages)
11514        // so that we do not end up in a confused state while the user is still using the older
11515        // version of the application while the new one gets installed.
11516        final long token = Binder.clearCallingIdentity();
11517        try {
11518            IActivityManager am = ActivityManager.getService();
11519            if (am != null) {
11520                try {
11521                    am.killApplication(pkgName, appId, userId, reason);
11522                } catch (RemoteException e) {
11523                }
11524            }
11525        } finally {
11526            Binder.restoreCallingIdentity(token);
11527        }
11528    }
11529
11530    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11531        // Remove the parent package setting
11532        PackageSetting ps = (PackageSetting) pkg.mExtras;
11533        if (ps != null) {
11534            removePackageLI(ps, chatty);
11535        }
11536        // Remove the child package setting
11537        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11538        for (int i = 0; i < childCount; i++) {
11539            PackageParser.Package childPkg = pkg.childPackages.get(i);
11540            ps = (PackageSetting) childPkg.mExtras;
11541            if (ps != null) {
11542                removePackageLI(ps, chatty);
11543            }
11544        }
11545    }
11546
11547    void removePackageLI(PackageSetting ps, boolean chatty) {
11548        if (DEBUG_INSTALL) {
11549            if (chatty)
11550                Log.d(TAG, "Removing package " + ps.name);
11551        }
11552
11553        // writer
11554        synchronized (mPackages) {
11555            mPackages.remove(ps.name);
11556            final PackageParser.Package pkg = ps.pkg;
11557            if (pkg != null) {
11558                cleanPackageDataStructuresLILPw(pkg, chatty);
11559            }
11560        }
11561    }
11562
11563    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11564        if (DEBUG_INSTALL) {
11565            if (chatty)
11566                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11567        }
11568
11569        // writer
11570        synchronized (mPackages) {
11571            // Remove the parent package
11572            mPackages.remove(pkg.applicationInfo.packageName);
11573            cleanPackageDataStructuresLILPw(pkg, chatty);
11574
11575            // Remove the child packages
11576            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11577            for (int i = 0; i < childCount; i++) {
11578                PackageParser.Package childPkg = pkg.childPackages.get(i);
11579                mPackages.remove(childPkg.applicationInfo.packageName);
11580                cleanPackageDataStructuresLILPw(childPkg, chatty);
11581            }
11582        }
11583    }
11584
11585    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11586        int N = pkg.providers.size();
11587        StringBuilder r = null;
11588        int i;
11589        for (i=0; i<N; i++) {
11590            PackageParser.Provider p = pkg.providers.get(i);
11591            mProviders.removeProvider(p);
11592            if (p.info.authority == null) {
11593
11594                /* There was another ContentProvider with this authority when
11595                 * this app was installed so this authority is null,
11596                 * Ignore it as we don't have to unregister the provider.
11597                 */
11598                continue;
11599            }
11600            String names[] = p.info.authority.split(";");
11601            for (int j = 0; j < names.length; j++) {
11602                if (mProvidersByAuthority.get(names[j]) == p) {
11603                    mProvidersByAuthority.remove(names[j]);
11604                    if (DEBUG_REMOVE) {
11605                        if (chatty)
11606                            Log.d(TAG, "Unregistered content provider: " + names[j]
11607                                    + ", className = " + p.info.name + ", isSyncable = "
11608                                    + p.info.isSyncable);
11609                    }
11610                }
11611            }
11612            if (DEBUG_REMOVE && chatty) {
11613                if (r == null) {
11614                    r = new StringBuilder(256);
11615                } else {
11616                    r.append(' ');
11617                }
11618                r.append(p.info.name);
11619            }
11620        }
11621        if (r != null) {
11622            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11623        }
11624
11625        N = pkg.services.size();
11626        r = null;
11627        for (i=0; i<N; i++) {
11628            PackageParser.Service s = pkg.services.get(i);
11629            mServices.removeService(s);
11630            if (chatty) {
11631                if (r == null) {
11632                    r = new StringBuilder(256);
11633                } else {
11634                    r.append(' ');
11635                }
11636                r.append(s.info.name);
11637            }
11638        }
11639        if (r != null) {
11640            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11641        }
11642
11643        N = pkg.receivers.size();
11644        r = null;
11645        for (i=0; i<N; i++) {
11646            PackageParser.Activity a = pkg.receivers.get(i);
11647            mReceivers.removeActivity(a, "receiver");
11648            if (DEBUG_REMOVE && chatty) {
11649                if (r == null) {
11650                    r = new StringBuilder(256);
11651                } else {
11652                    r.append(' ');
11653                }
11654                r.append(a.info.name);
11655            }
11656        }
11657        if (r != null) {
11658            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11659        }
11660
11661        N = pkg.activities.size();
11662        r = null;
11663        for (i=0; i<N; i++) {
11664            PackageParser.Activity a = pkg.activities.get(i);
11665            mActivities.removeActivity(a, "activity");
11666            if (DEBUG_REMOVE && chatty) {
11667                if (r == null) {
11668                    r = new StringBuilder(256);
11669                } else {
11670                    r.append(' ');
11671                }
11672                r.append(a.info.name);
11673            }
11674        }
11675        if (r != null) {
11676            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11677        }
11678
11679        N = pkg.permissions.size();
11680        r = null;
11681        for (i=0; i<N; i++) {
11682            PackageParser.Permission p = pkg.permissions.get(i);
11683            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11684            if (bp == null) {
11685                bp = mSettings.mPermissionTrees.get(p.info.name);
11686            }
11687            if (bp != null && bp.perm == p) {
11688                bp.perm = null;
11689                if (DEBUG_REMOVE && chatty) {
11690                    if (r == null) {
11691                        r = new StringBuilder(256);
11692                    } else {
11693                        r.append(' ');
11694                    }
11695                    r.append(p.info.name);
11696                }
11697            }
11698            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11699                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11700                if (appOpPkgs != null) {
11701                    appOpPkgs.remove(pkg.packageName);
11702                }
11703            }
11704        }
11705        if (r != null) {
11706            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11707        }
11708
11709        N = pkg.requestedPermissions.size();
11710        r = null;
11711        for (i=0; i<N; i++) {
11712            String perm = pkg.requestedPermissions.get(i);
11713            BasePermission bp = mSettings.mPermissions.get(perm);
11714            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11715                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11716                if (appOpPkgs != null) {
11717                    appOpPkgs.remove(pkg.packageName);
11718                    if (appOpPkgs.isEmpty()) {
11719                        mAppOpPermissionPackages.remove(perm);
11720                    }
11721                }
11722            }
11723        }
11724        if (r != null) {
11725            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11726        }
11727
11728        N = pkg.instrumentation.size();
11729        r = null;
11730        for (i=0; i<N; i++) {
11731            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11732            mInstrumentation.remove(a.getComponentName());
11733            if (DEBUG_REMOVE && chatty) {
11734                if (r == null) {
11735                    r = new StringBuilder(256);
11736                } else {
11737                    r.append(' ');
11738                }
11739                r.append(a.info.name);
11740            }
11741        }
11742        if (r != null) {
11743            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11744        }
11745
11746        r = null;
11747        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11748            // Only system apps can hold shared libraries.
11749            if (pkg.libraryNames != null) {
11750                for (i = 0; i < pkg.libraryNames.size(); i++) {
11751                    String name = pkg.libraryNames.get(i);
11752                    if (removeSharedLibraryLPw(name, 0)) {
11753                        if (DEBUG_REMOVE && chatty) {
11754                            if (r == null) {
11755                                r = new StringBuilder(256);
11756                            } else {
11757                                r.append(' ');
11758                            }
11759                            r.append(name);
11760                        }
11761                    }
11762                }
11763            }
11764        }
11765
11766        r = null;
11767
11768        // Any package can hold static shared libraries.
11769        if (pkg.staticSharedLibName != null) {
11770            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11771                if (DEBUG_REMOVE && chatty) {
11772                    if (r == null) {
11773                        r = new StringBuilder(256);
11774                    } else {
11775                        r.append(' ');
11776                    }
11777                    r.append(pkg.staticSharedLibName);
11778                }
11779            }
11780        }
11781
11782        if (r != null) {
11783            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11784        }
11785    }
11786
11787    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11788        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11789            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11790                return true;
11791            }
11792        }
11793        return false;
11794    }
11795
11796    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11797    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11798    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11799
11800    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11801        // Update the parent permissions
11802        updatePermissionsLPw(pkg.packageName, pkg, flags);
11803        // Update the child permissions
11804        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11805        for (int i = 0; i < childCount; i++) {
11806            PackageParser.Package childPkg = pkg.childPackages.get(i);
11807            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11808        }
11809    }
11810
11811    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11812            int flags) {
11813        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11814        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11815    }
11816
11817    private void updatePermissionsLPw(String changingPkg,
11818            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11819        // Make sure there are no dangling permission trees.
11820        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11821        while (it.hasNext()) {
11822            final BasePermission bp = it.next();
11823            if (bp.packageSetting == null) {
11824                // We may not yet have parsed the package, so just see if
11825                // we still know about its settings.
11826                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11827            }
11828            if (bp.packageSetting == null) {
11829                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11830                        + " from package " + bp.sourcePackage);
11831                it.remove();
11832            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11833                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11834                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11835                            + " from package " + bp.sourcePackage);
11836                    flags |= UPDATE_PERMISSIONS_ALL;
11837                    it.remove();
11838                }
11839            }
11840        }
11841
11842        // Make sure all dynamic permissions have been assigned to a package,
11843        // and make sure there are no dangling permissions.
11844        it = mSettings.mPermissions.values().iterator();
11845        while (it.hasNext()) {
11846            final BasePermission bp = it.next();
11847            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11848                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11849                        + bp.name + " pkg=" + bp.sourcePackage
11850                        + " info=" + bp.pendingInfo);
11851                if (bp.packageSetting == null && bp.pendingInfo != null) {
11852                    final BasePermission tree = findPermissionTreeLP(bp.name);
11853                    if (tree != null && tree.perm != null) {
11854                        bp.packageSetting = tree.packageSetting;
11855                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11856                                new PermissionInfo(bp.pendingInfo));
11857                        bp.perm.info.packageName = tree.perm.info.packageName;
11858                        bp.perm.info.name = bp.name;
11859                        bp.uid = tree.uid;
11860                    }
11861                }
11862            }
11863            if (bp.packageSetting == null) {
11864                // We may not yet have parsed the package, so just see if
11865                // we still know about its settings.
11866                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11867            }
11868            if (bp.packageSetting == null) {
11869                Slog.w(TAG, "Removing dangling permission: " + bp.name
11870                        + " from package " + bp.sourcePackage);
11871                it.remove();
11872            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11873                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11874                    Slog.i(TAG, "Removing old permission: " + bp.name
11875                            + " from package " + bp.sourcePackage);
11876                    flags |= UPDATE_PERMISSIONS_ALL;
11877                    it.remove();
11878                }
11879            }
11880        }
11881
11882        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11883        // Now update the permissions for all packages, in particular
11884        // replace the granted permissions of the system packages.
11885        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11886            for (PackageParser.Package pkg : mPackages.values()) {
11887                if (pkg != pkgInfo) {
11888                    // Only replace for packages on requested volume
11889                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11890                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11891                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11892                    grantPermissionsLPw(pkg, replace, changingPkg);
11893                }
11894            }
11895        }
11896
11897        if (pkgInfo != null) {
11898            // Only replace for packages on requested volume
11899            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11900            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11901                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11902            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11903        }
11904        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11905    }
11906
11907    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11908            String packageOfInterest) {
11909        // IMPORTANT: There are two types of permissions: install and runtime.
11910        // Install time permissions are granted when the app is installed to
11911        // all device users and users added in the future. Runtime permissions
11912        // are granted at runtime explicitly to specific users. Normal and signature
11913        // protected permissions are install time permissions. Dangerous permissions
11914        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11915        // otherwise they are runtime permissions. This function does not manage
11916        // runtime permissions except for the case an app targeting Lollipop MR1
11917        // being upgraded to target a newer SDK, in which case dangerous permissions
11918        // are transformed from install time to runtime ones.
11919
11920        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11921        if (ps == null) {
11922            return;
11923        }
11924
11925        PermissionsState permissionsState = ps.getPermissionsState();
11926        PermissionsState origPermissions = permissionsState;
11927
11928        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11929
11930        boolean runtimePermissionsRevoked = false;
11931        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11932
11933        boolean changedInstallPermission = false;
11934
11935        if (replace) {
11936            ps.installPermissionsFixed = false;
11937            if (!ps.isSharedUser()) {
11938                origPermissions = new PermissionsState(permissionsState);
11939                permissionsState.reset();
11940            } else {
11941                // We need to know only about runtime permission changes since the
11942                // calling code always writes the install permissions state but
11943                // the runtime ones are written only if changed. The only cases of
11944                // changed runtime permissions here are promotion of an install to
11945                // runtime and revocation of a runtime from a shared user.
11946                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11947                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11948                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11949                    runtimePermissionsRevoked = true;
11950                }
11951            }
11952        }
11953
11954        permissionsState.setGlobalGids(mGlobalGids);
11955
11956        final int N = pkg.requestedPermissions.size();
11957        for (int i=0; i<N; i++) {
11958            final String name = pkg.requestedPermissions.get(i);
11959            final BasePermission bp = mSettings.mPermissions.get(name);
11960            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11961                    >= Build.VERSION_CODES.M;
11962
11963            if (DEBUG_INSTALL) {
11964                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11965            }
11966
11967            if (bp == null || bp.packageSetting == null) {
11968                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11969                    if (DEBUG_PERMISSIONS) {
11970                        Slog.i(TAG, "Unknown permission " + name
11971                                + " in package " + pkg.packageName);
11972                    }
11973                }
11974                continue;
11975            }
11976
11977
11978            // Limit ephemeral apps to ephemeral allowed permissions.
11979            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11980                if (DEBUG_PERMISSIONS) {
11981                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11982                            + pkg.packageName);
11983                }
11984                continue;
11985            }
11986
11987            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11988                if (DEBUG_PERMISSIONS) {
11989                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11990                            + pkg.packageName);
11991                }
11992                continue;
11993            }
11994
11995            final String perm = bp.name;
11996            boolean allowedSig = false;
11997            int grant = GRANT_DENIED;
11998
11999            // Keep track of app op permissions.
12000            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12001                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12002                if (pkgs == null) {
12003                    pkgs = new ArraySet<>();
12004                    mAppOpPermissionPackages.put(bp.name, pkgs);
12005                }
12006                pkgs.add(pkg.packageName);
12007            }
12008
12009            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12010            switch (level) {
12011                case PermissionInfo.PROTECTION_NORMAL: {
12012                    // For all apps normal permissions are install time ones.
12013                    grant = GRANT_INSTALL;
12014                } break;
12015
12016                case PermissionInfo.PROTECTION_DANGEROUS: {
12017                    // If a permission review is required for legacy apps we represent
12018                    // their permissions as always granted runtime ones since we need
12019                    // to keep the review required permission flag per user while an
12020                    // install permission's state is shared across all users.
12021                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12022                        // For legacy apps dangerous permissions are install time ones.
12023                        grant = GRANT_INSTALL;
12024                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12025                        // For legacy apps that became modern, install becomes runtime.
12026                        grant = GRANT_UPGRADE;
12027                    } else if (mPromoteSystemApps
12028                            && isSystemApp(ps)
12029                            && mExistingSystemPackages.contains(ps.name)) {
12030                        // For legacy system apps, install becomes runtime.
12031                        // We cannot check hasInstallPermission() for system apps since those
12032                        // permissions were granted implicitly and not persisted pre-M.
12033                        grant = GRANT_UPGRADE;
12034                    } else {
12035                        // For modern apps keep runtime permissions unchanged.
12036                        grant = GRANT_RUNTIME;
12037                    }
12038                } break;
12039
12040                case PermissionInfo.PROTECTION_SIGNATURE: {
12041                    // For all apps signature permissions are install time ones.
12042                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12043                    if (allowedSig) {
12044                        grant = GRANT_INSTALL;
12045                    }
12046                } break;
12047            }
12048
12049            if (DEBUG_PERMISSIONS) {
12050                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12051            }
12052
12053            if (grant != GRANT_DENIED) {
12054                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12055                    // If this is an existing, non-system package, then
12056                    // we can't add any new permissions to it.
12057                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12058                        // Except...  if this is a permission that was added
12059                        // to the platform (note: need to only do this when
12060                        // updating the platform).
12061                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12062                            grant = GRANT_DENIED;
12063                        }
12064                    }
12065                }
12066
12067                switch (grant) {
12068                    case GRANT_INSTALL: {
12069                        // Revoke this as runtime permission to handle the case of
12070                        // a runtime permission being downgraded to an install one.
12071                        // Also in permission review mode we keep dangerous permissions
12072                        // for legacy apps
12073                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12074                            if (origPermissions.getRuntimePermissionState(
12075                                    bp.name, userId) != null) {
12076                                // Revoke the runtime permission and clear the flags.
12077                                origPermissions.revokeRuntimePermission(bp, userId);
12078                                origPermissions.updatePermissionFlags(bp, userId,
12079                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12080                                // If we revoked a permission permission, we have to write.
12081                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12082                                        changedRuntimePermissionUserIds, userId);
12083                            }
12084                        }
12085                        // Grant an install permission.
12086                        if (permissionsState.grantInstallPermission(bp) !=
12087                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12088                            changedInstallPermission = true;
12089                        }
12090                    } break;
12091
12092                    case GRANT_RUNTIME: {
12093                        // Grant previously granted runtime permissions.
12094                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12095                            PermissionState permissionState = origPermissions
12096                                    .getRuntimePermissionState(bp.name, userId);
12097                            int flags = permissionState != null
12098                                    ? permissionState.getFlags() : 0;
12099                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12100                                // Don't propagate the permission in a permission review mode if
12101                                // the former was revoked, i.e. marked to not propagate on upgrade.
12102                                // Note that in a permission review mode install permissions are
12103                                // represented as constantly granted runtime ones since we need to
12104                                // keep a per user state associated with the permission. Also the
12105                                // revoke on upgrade flag is no longer applicable and is reset.
12106                                final boolean revokeOnUpgrade = (flags & PackageManager
12107                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12108                                if (revokeOnUpgrade) {
12109                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12110                                    // Since we changed the flags, we have to write.
12111                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12112                                            changedRuntimePermissionUserIds, userId);
12113                                }
12114                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12115                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12116                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12117                                        // If we cannot put the permission as it was,
12118                                        // we have to write.
12119                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12120                                                changedRuntimePermissionUserIds, userId);
12121                                    }
12122                                }
12123
12124                                // If the app supports runtime permissions no need for a review.
12125                                if (mPermissionReviewRequired
12126                                        && appSupportsRuntimePermissions
12127                                        && (flags & PackageManager
12128                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12129                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12130                                    // Since we changed the flags, we have to write.
12131                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12132                                            changedRuntimePermissionUserIds, userId);
12133                                }
12134                            } else if (mPermissionReviewRequired
12135                                    && !appSupportsRuntimePermissions) {
12136                                // For legacy apps that need a permission review, every new
12137                                // runtime permission is granted but it is pending a review.
12138                                // We also need to review only platform defined runtime
12139                                // permissions as these are the only ones the platform knows
12140                                // how to disable the API to simulate revocation as legacy
12141                                // apps don't expect to run with revoked permissions.
12142                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12143                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12144                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12145                                        // We changed the flags, hence have to write.
12146                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12147                                                changedRuntimePermissionUserIds, userId);
12148                                    }
12149                                }
12150                                if (permissionsState.grantRuntimePermission(bp, userId)
12151                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12152                                    // We changed the permission, hence have to write.
12153                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12154                                            changedRuntimePermissionUserIds, userId);
12155                                }
12156                            }
12157                            // Propagate the permission flags.
12158                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12159                        }
12160                    } break;
12161
12162                    case GRANT_UPGRADE: {
12163                        // Grant runtime permissions for a previously held install permission.
12164                        PermissionState permissionState = origPermissions
12165                                .getInstallPermissionState(bp.name);
12166                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12167
12168                        if (origPermissions.revokeInstallPermission(bp)
12169                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12170                            // We will be transferring the permission flags, so clear them.
12171                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12172                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12173                            changedInstallPermission = true;
12174                        }
12175
12176                        // If the permission is not to be promoted to runtime we ignore it and
12177                        // also its other flags as they are not applicable to install permissions.
12178                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12179                            for (int userId : currentUserIds) {
12180                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12181                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12182                                    // Transfer the permission flags.
12183                                    permissionsState.updatePermissionFlags(bp, userId,
12184                                            flags, flags);
12185                                    // If we granted the permission, we have to write.
12186                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12187                                            changedRuntimePermissionUserIds, userId);
12188                                }
12189                            }
12190                        }
12191                    } break;
12192
12193                    default: {
12194                        if (packageOfInterest == null
12195                                || packageOfInterest.equals(pkg.packageName)) {
12196                            if (DEBUG_PERMISSIONS) {
12197                                Slog.i(TAG, "Not granting permission " + perm
12198                                        + " to package " + pkg.packageName
12199                                        + " because it was previously installed without");
12200                            }
12201                        }
12202                    } break;
12203                }
12204            } else {
12205                if (permissionsState.revokeInstallPermission(bp) !=
12206                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12207                    // Also drop the permission flags.
12208                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12209                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12210                    changedInstallPermission = true;
12211                    Slog.i(TAG, "Un-granting permission " + perm
12212                            + " from package " + pkg.packageName
12213                            + " (protectionLevel=" + bp.protectionLevel
12214                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12215                            + ")");
12216                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12217                    // Don't print warning for app op permissions, since it is fine for them
12218                    // not to be granted, there is a UI for the user to decide.
12219                    if (DEBUG_PERMISSIONS
12220                            && (packageOfInterest == null
12221                                    || packageOfInterest.equals(pkg.packageName))) {
12222                        Slog.i(TAG, "Not granting permission " + perm
12223                                + " to package " + pkg.packageName
12224                                + " (protectionLevel=" + bp.protectionLevel
12225                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12226                                + ")");
12227                    }
12228                }
12229            }
12230        }
12231
12232        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12233                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12234            // This is the first that we have heard about this package, so the
12235            // permissions we have now selected are fixed until explicitly
12236            // changed.
12237            ps.installPermissionsFixed = true;
12238        }
12239
12240        // Persist the runtime permissions state for users with changes. If permissions
12241        // were revoked because no app in the shared user declares them we have to
12242        // write synchronously to avoid losing runtime permissions state.
12243        for (int userId : changedRuntimePermissionUserIds) {
12244            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
12245        }
12246    }
12247
12248    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
12249        boolean allowed = false;
12250        final int NP = PackageParser.NEW_PERMISSIONS.length;
12251        for (int ip=0; ip<NP; ip++) {
12252            final PackageParser.NewPermissionInfo npi
12253                    = PackageParser.NEW_PERMISSIONS[ip];
12254            if (npi.name.equals(perm)
12255                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
12256                allowed = true;
12257                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
12258                        + pkg.packageName);
12259                break;
12260            }
12261        }
12262        return allowed;
12263    }
12264
12265    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
12266            BasePermission bp, PermissionsState origPermissions) {
12267        boolean privilegedPermission = (bp.protectionLevel
12268                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
12269        boolean privappPermissionsDisable =
12270                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
12271        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
12272        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
12273        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
12274                && !platformPackage && platformPermission) {
12275            ArraySet<String> wlPermissions = SystemConfig.getInstance()
12276                    .getPrivAppPermissions(pkg.packageName);
12277            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
12278            if (!whitelisted) {
12279                Slog.w(TAG, "Privileged permission " + perm + " for package "
12280                        + pkg.packageName + " - not in privapp-permissions whitelist");
12281                // Only report violations for apps on system image
12282                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
12283                    if (mPrivappPermissionsViolations == null) {
12284                        mPrivappPermissionsViolations = new ArraySet<>();
12285                    }
12286                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
12287                }
12288                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
12289                    return false;
12290                }
12291            }
12292        }
12293        boolean allowed = (compareSignatures(
12294                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
12295                        == PackageManager.SIGNATURE_MATCH)
12296                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
12297                        == PackageManager.SIGNATURE_MATCH);
12298        if (!allowed && privilegedPermission) {
12299            if (isSystemApp(pkg)) {
12300                // For updated system applications, a system permission
12301                // is granted only if it had been defined by the original application.
12302                if (pkg.isUpdatedSystemApp()) {
12303                    final PackageSetting sysPs = mSettings
12304                            .getDisabledSystemPkgLPr(pkg.packageName);
12305                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
12306                        // If the original was granted this permission, we take
12307                        // that grant decision as read and propagate it to the
12308                        // update.
12309                        if (sysPs.isPrivileged()) {
12310                            allowed = true;
12311                        }
12312                    } else {
12313                        // The system apk may have been updated with an older
12314                        // version of the one on the data partition, but which
12315                        // granted a new system permission that it didn't have
12316                        // before.  In this case we do want to allow the app to
12317                        // now get the new permission if the ancestral apk is
12318                        // privileged to get it.
12319                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
12320                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
12321                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
12322                                    allowed = true;
12323                                    break;
12324                                }
12325                            }
12326                        }
12327                        // Also if a privileged parent package on the system image or any of
12328                        // its children requested a privileged permission, the updated child
12329                        // packages can also get the permission.
12330                        if (pkg.parentPackage != null) {
12331                            final PackageSetting disabledSysParentPs = mSettings
12332                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
12333                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
12334                                    && disabledSysParentPs.isPrivileged()) {
12335                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
12336                                    allowed = true;
12337                                } else if (disabledSysParentPs.pkg.childPackages != null) {
12338                                    final int count = disabledSysParentPs.pkg.childPackages.size();
12339                                    for (int i = 0; i < count; i++) {
12340                                        PackageParser.Package disabledSysChildPkg =
12341                                                disabledSysParentPs.pkg.childPackages.get(i);
12342                                        if (isPackageRequestingPermission(disabledSysChildPkg,
12343                                                perm)) {
12344                                            allowed = true;
12345                                            break;
12346                                        }
12347                                    }
12348                                }
12349                            }
12350                        }
12351                    }
12352                } else {
12353                    allowed = isPrivilegedApp(pkg);
12354                }
12355            }
12356        }
12357        if (!allowed) {
12358            if (!allowed && (bp.protectionLevel
12359                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
12360                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
12361                // If this was a previously normal/dangerous permission that got moved
12362                // to a system permission as part of the runtime permission redesign, then
12363                // we still want to blindly grant it to old apps.
12364                allowed = true;
12365            }
12366            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
12367                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
12368                // If this permission is to be granted to the system installer and
12369                // this app is an installer, then it gets the permission.
12370                allowed = true;
12371            }
12372            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
12373                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
12374                // If this permission is to be granted to the system verifier and
12375                // this app is a verifier, then it gets the permission.
12376                allowed = true;
12377            }
12378            if (!allowed && (bp.protectionLevel
12379                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
12380                    && isSystemApp(pkg)) {
12381                // Any pre-installed system app is allowed to get this permission.
12382                allowed = true;
12383            }
12384            if (!allowed && (bp.protectionLevel
12385                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
12386                // For development permissions, a development permission
12387                // is granted only if it was already granted.
12388                allowed = origPermissions.hasInstallPermission(perm);
12389            }
12390            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
12391                    && pkg.packageName.equals(mSetupWizardPackage)) {
12392                // If this permission is to be granted to the system setup wizard and
12393                // this app is a setup wizard, then it gets the permission.
12394                allowed = true;
12395            }
12396        }
12397        return allowed;
12398    }
12399
12400    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
12401        final int permCount = pkg.requestedPermissions.size();
12402        for (int j = 0; j < permCount; j++) {
12403            String requestedPermission = pkg.requestedPermissions.get(j);
12404            if (permission.equals(requestedPermission)) {
12405                return true;
12406            }
12407        }
12408        return false;
12409    }
12410
12411    final class ActivityIntentResolver
12412            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12413        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12414                boolean defaultOnly, int userId) {
12415            if (!sUserManager.exists(userId)) return null;
12416            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12417            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12418        }
12419
12420        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12421                int userId) {
12422            if (!sUserManager.exists(userId)) return null;
12423            mFlags = flags;
12424            return super.queryIntent(intent, resolvedType,
12425                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12426                    userId);
12427        }
12428
12429        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12430                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12431            if (!sUserManager.exists(userId)) return null;
12432            if (packageActivities == null) {
12433                return null;
12434            }
12435            mFlags = flags;
12436            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12437            final int N = packageActivities.size();
12438            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12439                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12440
12441            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12442            for (int i = 0; i < N; ++i) {
12443                intentFilters = packageActivities.get(i).intents;
12444                if (intentFilters != null && intentFilters.size() > 0) {
12445                    PackageParser.ActivityIntentInfo[] array =
12446                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12447                    intentFilters.toArray(array);
12448                    listCut.add(array);
12449                }
12450            }
12451            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12452        }
12453
12454        /**
12455         * Finds a privileged activity that matches the specified activity names.
12456         */
12457        private PackageParser.Activity findMatchingActivity(
12458                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12459            for (PackageParser.Activity sysActivity : activityList) {
12460                if (sysActivity.info.name.equals(activityInfo.name)) {
12461                    return sysActivity;
12462                }
12463                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12464                    return sysActivity;
12465                }
12466                if (sysActivity.info.targetActivity != null) {
12467                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12468                        return sysActivity;
12469                    }
12470                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12471                        return sysActivity;
12472                    }
12473                }
12474            }
12475            return null;
12476        }
12477
12478        public class IterGenerator<E> {
12479            public Iterator<E> generate(ActivityIntentInfo info) {
12480                return null;
12481            }
12482        }
12483
12484        public class ActionIterGenerator extends IterGenerator<String> {
12485            @Override
12486            public Iterator<String> generate(ActivityIntentInfo info) {
12487                return info.actionsIterator();
12488            }
12489        }
12490
12491        public class CategoriesIterGenerator extends IterGenerator<String> {
12492            @Override
12493            public Iterator<String> generate(ActivityIntentInfo info) {
12494                return info.categoriesIterator();
12495            }
12496        }
12497
12498        public class SchemesIterGenerator extends IterGenerator<String> {
12499            @Override
12500            public Iterator<String> generate(ActivityIntentInfo info) {
12501                return info.schemesIterator();
12502            }
12503        }
12504
12505        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12506            @Override
12507            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12508                return info.authoritiesIterator();
12509            }
12510        }
12511
12512        /**
12513         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12514         * MODIFIED. Do not pass in a list that should not be changed.
12515         */
12516        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12517                IterGenerator<T> generator, Iterator<T> searchIterator) {
12518            // loop through the set of actions; every one must be found in the intent filter
12519            while (searchIterator.hasNext()) {
12520                // we must have at least one filter in the list to consider a match
12521                if (intentList.size() == 0) {
12522                    break;
12523                }
12524
12525                final T searchAction = searchIterator.next();
12526
12527                // loop through the set of intent filters
12528                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12529                while (intentIter.hasNext()) {
12530                    final ActivityIntentInfo intentInfo = intentIter.next();
12531                    boolean selectionFound = false;
12532
12533                    // loop through the intent filter's selection criteria; at least one
12534                    // of them must match the searched criteria
12535                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12536                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12537                        final T intentSelection = intentSelectionIter.next();
12538                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12539                            selectionFound = true;
12540                            break;
12541                        }
12542                    }
12543
12544                    // the selection criteria wasn't found in this filter's set; this filter
12545                    // is not a potential match
12546                    if (!selectionFound) {
12547                        intentIter.remove();
12548                    }
12549                }
12550            }
12551        }
12552
12553        private boolean isProtectedAction(ActivityIntentInfo filter) {
12554            final Iterator<String> actionsIter = filter.actionsIterator();
12555            while (actionsIter != null && actionsIter.hasNext()) {
12556                final String filterAction = actionsIter.next();
12557                if (PROTECTED_ACTIONS.contains(filterAction)) {
12558                    return true;
12559                }
12560            }
12561            return false;
12562        }
12563
12564        /**
12565         * Adjusts the priority of the given intent filter according to policy.
12566         * <p>
12567         * <ul>
12568         * <li>The priority for non privileged applications is capped to '0'</li>
12569         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12570         * <li>The priority for unbundled updates to privileged applications is capped to the
12571         *      priority defined on the system partition</li>
12572         * </ul>
12573         * <p>
12574         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12575         * allowed to obtain any priority on any action.
12576         */
12577        private void adjustPriority(
12578                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12579            // nothing to do; priority is fine as-is
12580            if (intent.getPriority() <= 0) {
12581                return;
12582            }
12583
12584            final ActivityInfo activityInfo = intent.activity.info;
12585            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12586
12587            final boolean privilegedApp =
12588                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12589            if (!privilegedApp) {
12590                // non-privileged applications can never define a priority >0
12591                if (DEBUG_FILTERS) {
12592                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12593                            + " package: " + applicationInfo.packageName
12594                            + " activity: " + intent.activity.className
12595                            + " origPrio: " + intent.getPriority());
12596                }
12597                intent.setPriority(0);
12598                return;
12599            }
12600
12601            if (systemActivities == null) {
12602                // the system package is not disabled; we're parsing the system partition
12603                if (isProtectedAction(intent)) {
12604                    if (mDeferProtectedFilters) {
12605                        // We can't deal with these just yet. No component should ever obtain a
12606                        // >0 priority for a protected actions, with ONE exception -- the setup
12607                        // wizard. The setup wizard, however, cannot be known until we're able to
12608                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12609                        // until all intent filters have been processed. Chicken, meet egg.
12610                        // Let the filter temporarily have a high priority and rectify the
12611                        // priorities after all system packages have been scanned.
12612                        mProtectedFilters.add(intent);
12613                        if (DEBUG_FILTERS) {
12614                            Slog.i(TAG, "Protected action; save for later;"
12615                                    + " package: " + applicationInfo.packageName
12616                                    + " activity: " + intent.activity.className
12617                                    + " origPrio: " + intent.getPriority());
12618                        }
12619                        return;
12620                    } else {
12621                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12622                            Slog.i(TAG, "No setup wizard;"
12623                                + " All protected intents capped to priority 0");
12624                        }
12625                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12626                            if (DEBUG_FILTERS) {
12627                                Slog.i(TAG, "Found setup wizard;"
12628                                    + " allow priority " + intent.getPriority() + ";"
12629                                    + " package: " + intent.activity.info.packageName
12630                                    + " activity: " + intent.activity.className
12631                                    + " priority: " + intent.getPriority());
12632                            }
12633                            // setup wizard gets whatever it wants
12634                            return;
12635                        }
12636                        if (DEBUG_FILTERS) {
12637                            Slog.i(TAG, "Protected action; cap priority to 0;"
12638                                    + " package: " + intent.activity.info.packageName
12639                                    + " activity: " + intent.activity.className
12640                                    + " origPrio: " + intent.getPriority());
12641                        }
12642                        intent.setPriority(0);
12643                        return;
12644                    }
12645                }
12646                // privileged apps on the system image get whatever priority they request
12647                return;
12648            }
12649
12650            // privileged app unbundled update ... try to find the same activity
12651            final PackageParser.Activity foundActivity =
12652                    findMatchingActivity(systemActivities, activityInfo);
12653            if (foundActivity == null) {
12654                // this is a new activity; it cannot obtain >0 priority
12655                if (DEBUG_FILTERS) {
12656                    Slog.i(TAG, "New activity; cap priority to 0;"
12657                            + " package: " + applicationInfo.packageName
12658                            + " activity: " + intent.activity.className
12659                            + " origPrio: " + intent.getPriority());
12660                }
12661                intent.setPriority(0);
12662                return;
12663            }
12664
12665            // found activity, now check for filter equivalence
12666
12667            // a shallow copy is enough; we modify the list, not its contents
12668            final List<ActivityIntentInfo> intentListCopy =
12669                    new ArrayList<>(foundActivity.intents);
12670            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12671
12672            // find matching action subsets
12673            final Iterator<String> actionsIterator = intent.actionsIterator();
12674            if (actionsIterator != null) {
12675                getIntentListSubset(
12676                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12677                if (intentListCopy.size() == 0) {
12678                    // no more intents to match; we're not equivalent
12679                    if (DEBUG_FILTERS) {
12680                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12681                                + " package: " + applicationInfo.packageName
12682                                + " activity: " + intent.activity.className
12683                                + " origPrio: " + intent.getPriority());
12684                    }
12685                    intent.setPriority(0);
12686                    return;
12687                }
12688            }
12689
12690            // find matching category subsets
12691            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12692            if (categoriesIterator != null) {
12693                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12694                        categoriesIterator);
12695                if (intentListCopy.size() == 0) {
12696                    // no more intents to match; we're not equivalent
12697                    if (DEBUG_FILTERS) {
12698                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12699                                + " package: " + applicationInfo.packageName
12700                                + " activity: " + intent.activity.className
12701                                + " origPrio: " + intent.getPriority());
12702                    }
12703                    intent.setPriority(0);
12704                    return;
12705                }
12706            }
12707
12708            // find matching schemes subsets
12709            final Iterator<String> schemesIterator = intent.schemesIterator();
12710            if (schemesIterator != null) {
12711                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12712                        schemesIterator);
12713                if (intentListCopy.size() == 0) {
12714                    // no more intents to match; we're not equivalent
12715                    if (DEBUG_FILTERS) {
12716                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12717                                + " package: " + applicationInfo.packageName
12718                                + " activity: " + intent.activity.className
12719                                + " origPrio: " + intent.getPriority());
12720                    }
12721                    intent.setPriority(0);
12722                    return;
12723                }
12724            }
12725
12726            // find matching authorities subsets
12727            final Iterator<IntentFilter.AuthorityEntry>
12728                    authoritiesIterator = intent.authoritiesIterator();
12729            if (authoritiesIterator != null) {
12730                getIntentListSubset(intentListCopy,
12731                        new AuthoritiesIterGenerator(),
12732                        authoritiesIterator);
12733                if (intentListCopy.size() == 0) {
12734                    // no more intents to match; we're not equivalent
12735                    if (DEBUG_FILTERS) {
12736                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12737                                + " package: " + applicationInfo.packageName
12738                                + " activity: " + intent.activity.className
12739                                + " origPrio: " + intent.getPriority());
12740                    }
12741                    intent.setPriority(0);
12742                    return;
12743                }
12744            }
12745
12746            // we found matching filter(s); app gets the max priority of all intents
12747            int cappedPriority = 0;
12748            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12749                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12750            }
12751            if (intent.getPriority() > cappedPriority) {
12752                if (DEBUG_FILTERS) {
12753                    Slog.i(TAG, "Found matching filter(s);"
12754                            + " cap priority to " + cappedPriority + ";"
12755                            + " package: " + applicationInfo.packageName
12756                            + " activity: " + intent.activity.className
12757                            + " origPrio: " + intent.getPriority());
12758                }
12759                intent.setPriority(cappedPriority);
12760                return;
12761            }
12762            // all this for nothing; the requested priority was <= what was on the system
12763        }
12764
12765        public final void addActivity(PackageParser.Activity a, String type) {
12766            mActivities.put(a.getComponentName(), a);
12767            if (DEBUG_SHOW_INFO)
12768                Log.v(
12769                TAG, "  " + type + " " +
12770                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12771            if (DEBUG_SHOW_INFO)
12772                Log.v(TAG, "    Class=" + a.info.name);
12773            final int NI = a.intents.size();
12774            for (int j=0; j<NI; j++) {
12775                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12776                if ("activity".equals(type)) {
12777                    final PackageSetting ps =
12778                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12779                    final List<PackageParser.Activity> systemActivities =
12780                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12781                    adjustPriority(systemActivities, intent);
12782                }
12783                if (DEBUG_SHOW_INFO) {
12784                    Log.v(TAG, "    IntentFilter:");
12785                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12786                }
12787                if (!intent.debugCheck()) {
12788                    Log.w(TAG, "==> For Activity " + a.info.name);
12789                }
12790                addFilter(intent);
12791            }
12792        }
12793
12794        public final void removeActivity(PackageParser.Activity a, String type) {
12795            mActivities.remove(a.getComponentName());
12796            if (DEBUG_SHOW_INFO) {
12797                Log.v(TAG, "  " + type + " "
12798                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12799                                : a.info.name) + ":");
12800                Log.v(TAG, "    Class=" + a.info.name);
12801            }
12802            final int NI = a.intents.size();
12803            for (int j=0; j<NI; j++) {
12804                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12805                if (DEBUG_SHOW_INFO) {
12806                    Log.v(TAG, "    IntentFilter:");
12807                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12808                }
12809                removeFilter(intent);
12810            }
12811        }
12812
12813        @Override
12814        protected boolean allowFilterResult(
12815                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12816            ActivityInfo filterAi = filter.activity.info;
12817            for (int i=dest.size()-1; i>=0; i--) {
12818                ActivityInfo destAi = dest.get(i).activityInfo;
12819                if (destAi.name == filterAi.name
12820                        && destAi.packageName == filterAi.packageName) {
12821                    return false;
12822                }
12823            }
12824            return true;
12825        }
12826
12827        @Override
12828        protected ActivityIntentInfo[] newArray(int size) {
12829            return new ActivityIntentInfo[size];
12830        }
12831
12832        @Override
12833        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12834            if (!sUserManager.exists(userId)) return true;
12835            PackageParser.Package p = filter.activity.owner;
12836            if (p != null) {
12837                PackageSetting ps = (PackageSetting)p.mExtras;
12838                if (ps != null) {
12839                    // System apps are never considered stopped for purposes of
12840                    // filtering, because there may be no way for the user to
12841                    // actually re-launch them.
12842                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12843                            && ps.getStopped(userId);
12844                }
12845            }
12846            return false;
12847        }
12848
12849        @Override
12850        protected boolean isPackageForFilter(String packageName,
12851                PackageParser.ActivityIntentInfo info) {
12852            return packageName.equals(info.activity.owner.packageName);
12853        }
12854
12855        @Override
12856        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12857                int match, int userId) {
12858            if (!sUserManager.exists(userId)) return null;
12859            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12860                return null;
12861            }
12862            final PackageParser.Activity activity = info.activity;
12863            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12864            if (ps == null) {
12865                return null;
12866            }
12867            final PackageUserState userState = ps.readUserState(userId);
12868            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12869            if (ai == null) {
12870                return null;
12871            }
12872            final boolean matchExplicitlyVisibleOnly =
12873                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12874            final boolean matchVisibleToInstantApp =
12875                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12876            final boolean componentVisible =
12877                    matchVisibleToInstantApp
12878                    && info.isVisibleToInstantApp()
12879                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12880            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12881            // throw out filters that aren't visible to ephemeral apps
12882            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12883                return null;
12884            }
12885            // throw out instant app filters if we're not explicitly requesting them
12886            if (!matchInstantApp && userState.instantApp) {
12887                return null;
12888            }
12889            // throw out instant app filters if updates are available; will trigger
12890            // instant app resolution
12891            if (userState.instantApp && ps.isUpdateAvailable()) {
12892                return null;
12893            }
12894            final ResolveInfo res = new ResolveInfo();
12895            res.activityInfo = ai;
12896            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12897                res.filter = info;
12898            }
12899            if (info != null) {
12900                res.handleAllWebDataURI = info.handleAllWebDataURI();
12901            }
12902            res.priority = info.getPriority();
12903            res.preferredOrder = activity.owner.mPreferredOrder;
12904            //System.out.println("Result: " + res.activityInfo.className +
12905            //                   " = " + res.priority);
12906            res.match = match;
12907            res.isDefault = info.hasDefault;
12908            res.labelRes = info.labelRes;
12909            res.nonLocalizedLabel = info.nonLocalizedLabel;
12910            if (userNeedsBadging(userId)) {
12911                res.noResourceId = true;
12912            } else {
12913                res.icon = info.icon;
12914            }
12915            res.iconResourceId = info.icon;
12916            res.system = res.activityInfo.applicationInfo.isSystemApp();
12917            res.isInstantAppAvailable = userState.instantApp;
12918            return res;
12919        }
12920
12921        @Override
12922        protected void sortResults(List<ResolveInfo> results) {
12923            Collections.sort(results, mResolvePrioritySorter);
12924        }
12925
12926        @Override
12927        protected void dumpFilter(PrintWriter out, String prefix,
12928                PackageParser.ActivityIntentInfo filter) {
12929            out.print(prefix); out.print(
12930                    Integer.toHexString(System.identityHashCode(filter.activity)));
12931                    out.print(' ');
12932                    filter.activity.printComponentShortName(out);
12933                    out.print(" filter ");
12934                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12935        }
12936
12937        @Override
12938        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12939            return filter.activity;
12940        }
12941
12942        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12943            PackageParser.Activity activity = (PackageParser.Activity)label;
12944            out.print(prefix); out.print(
12945                    Integer.toHexString(System.identityHashCode(activity)));
12946                    out.print(' ');
12947                    activity.printComponentShortName(out);
12948            if (count > 1) {
12949                out.print(" ("); out.print(count); out.print(" filters)");
12950            }
12951            out.println();
12952        }
12953
12954        // Keys are String (activity class name), values are Activity.
12955        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12956                = new ArrayMap<ComponentName, PackageParser.Activity>();
12957        private int mFlags;
12958    }
12959
12960    private final class ServiceIntentResolver
12961            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12962        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12963                boolean defaultOnly, int userId) {
12964            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12965            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12966        }
12967
12968        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12969                int userId) {
12970            if (!sUserManager.exists(userId)) return null;
12971            mFlags = flags;
12972            return super.queryIntent(intent, resolvedType,
12973                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12974                    userId);
12975        }
12976
12977        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12978                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12979            if (!sUserManager.exists(userId)) return null;
12980            if (packageServices == null) {
12981                return null;
12982            }
12983            mFlags = flags;
12984            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12985            final int N = packageServices.size();
12986            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12987                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12988
12989            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12990            for (int i = 0; i < N; ++i) {
12991                intentFilters = packageServices.get(i).intents;
12992                if (intentFilters != null && intentFilters.size() > 0) {
12993                    PackageParser.ServiceIntentInfo[] array =
12994                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12995                    intentFilters.toArray(array);
12996                    listCut.add(array);
12997                }
12998            }
12999            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13000        }
13001
13002        public final void addService(PackageParser.Service s) {
13003            mServices.put(s.getComponentName(), s);
13004            if (DEBUG_SHOW_INFO) {
13005                Log.v(TAG, "  "
13006                        + (s.info.nonLocalizedLabel != null
13007                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13008                Log.v(TAG, "    Class=" + s.info.name);
13009            }
13010            final int NI = s.intents.size();
13011            int j;
13012            for (j=0; j<NI; j++) {
13013                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13014                if (DEBUG_SHOW_INFO) {
13015                    Log.v(TAG, "    IntentFilter:");
13016                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13017                }
13018                if (!intent.debugCheck()) {
13019                    Log.w(TAG, "==> For Service " + s.info.name);
13020                }
13021                addFilter(intent);
13022            }
13023        }
13024
13025        public final void removeService(PackageParser.Service s) {
13026            mServices.remove(s.getComponentName());
13027            if (DEBUG_SHOW_INFO) {
13028                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13029                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13030                Log.v(TAG, "    Class=" + s.info.name);
13031            }
13032            final int NI = s.intents.size();
13033            int j;
13034            for (j=0; j<NI; j++) {
13035                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13036                if (DEBUG_SHOW_INFO) {
13037                    Log.v(TAG, "    IntentFilter:");
13038                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13039                }
13040                removeFilter(intent);
13041            }
13042        }
13043
13044        @Override
13045        protected boolean allowFilterResult(
13046                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13047            ServiceInfo filterSi = filter.service.info;
13048            for (int i=dest.size()-1; i>=0; i--) {
13049                ServiceInfo destAi = dest.get(i).serviceInfo;
13050                if (destAi.name == filterSi.name
13051                        && destAi.packageName == filterSi.packageName) {
13052                    return false;
13053                }
13054            }
13055            return true;
13056        }
13057
13058        @Override
13059        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13060            return new PackageParser.ServiceIntentInfo[size];
13061        }
13062
13063        @Override
13064        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13065            if (!sUserManager.exists(userId)) return true;
13066            PackageParser.Package p = filter.service.owner;
13067            if (p != null) {
13068                PackageSetting ps = (PackageSetting)p.mExtras;
13069                if (ps != null) {
13070                    // System apps are never considered stopped for purposes of
13071                    // filtering, because there may be no way for the user to
13072                    // actually re-launch them.
13073                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13074                            && ps.getStopped(userId);
13075                }
13076            }
13077            return false;
13078        }
13079
13080        @Override
13081        protected boolean isPackageForFilter(String packageName,
13082                PackageParser.ServiceIntentInfo info) {
13083            return packageName.equals(info.service.owner.packageName);
13084        }
13085
13086        @Override
13087        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13088                int match, int userId) {
13089            if (!sUserManager.exists(userId)) return null;
13090            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13091            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13092                return null;
13093            }
13094            final PackageParser.Service service = info.service;
13095            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13096            if (ps == null) {
13097                return null;
13098            }
13099            final PackageUserState userState = ps.readUserState(userId);
13100            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13101                    userState, userId);
13102            if (si == null) {
13103                return null;
13104            }
13105            final boolean matchVisibleToInstantApp =
13106                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13107            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13108            // throw out filters that aren't visible to ephemeral apps
13109            if (matchVisibleToInstantApp
13110                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13111                return null;
13112            }
13113            // throw out ephemeral filters if we're not explicitly requesting them
13114            if (!isInstantApp && userState.instantApp) {
13115                return null;
13116            }
13117            // throw out instant app filters if updates are available; will trigger
13118            // instant app resolution
13119            if (userState.instantApp && ps.isUpdateAvailable()) {
13120                return null;
13121            }
13122            final ResolveInfo res = new ResolveInfo();
13123            res.serviceInfo = si;
13124            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13125                res.filter = filter;
13126            }
13127            res.priority = info.getPriority();
13128            res.preferredOrder = service.owner.mPreferredOrder;
13129            res.match = match;
13130            res.isDefault = info.hasDefault;
13131            res.labelRes = info.labelRes;
13132            res.nonLocalizedLabel = info.nonLocalizedLabel;
13133            res.icon = info.icon;
13134            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13135            return res;
13136        }
13137
13138        @Override
13139        protected void sortResults(List<ResolveInfo> results) {
13140            Collections.sort(results, mResolvePrioritySorter);
13141        }
13142
13143        @Override
13144        protected void dumpFilter(PrintWriter out, String prefix,
13145                PackageParser.ServiceIntentInfo filter) {
13146            out.print(prefix); out.print(
13147                    Integer.toHexString(System.identityHashCode(filter.service)));
13148                    out.print(' ');
13149                    filter.service.printComponentShortName(out);
13150                    out.print(" filter ");
13151                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13152        }
13153
13154        @Override
13155        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13156            return filter.service;
13157        }
13158
13159        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13160            PackageParser.Service service = (PackageParser.Service)label;
13161            out.print(prefix); out.print(
13162                    Integer.toHexString(System.identityHashCode(service)));
13163                    out.print(' ');
13164                    service.printComponentShortName(out);
13165            if (count > 1) {
13166                out.print(" ("); out.print(count); out.print(" filters)");
13167            }
13168            out.println();
13169        }
13170
13171//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13172//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13173//            final List<ResolveInfo> retList = Lists.newArrayList();
13174//            while (i.hasNext()) {
13175//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13176//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13177//                    retList.add(resolveInfo);
13178//                }
13179//            }
13180//            return retList;
13181//        }
13182
13183        // Keys are String (activity class name), values are Activity.
13184        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13185                = new ArrayMap<ComponentName, PackageParser.Service>();
13186        private int mFlags;
13187    }
13188
13189    private final class ProviderIntentResolver
13190            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13191        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13192                boolean defaultOnly, int userId) {
13193            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13194            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13195        }
13196
13197        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13198                int userId) {
13199            if (!sUserManager.exists(userId))
13200                return null;
13201            mFlags = flags;
13202            return super.queryIntent(intent, resolvedType,
13203                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13204                    userId);
13205        }
13206
13207        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13208                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13209            if (!sUserManager.exists(userId))
13210                return null;
13211            if (packageProviders == null) {
13212                return null;
13213            }
13214            mFlags = flags;
13215            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13216            final int N = packageProviders.size();
13217            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13218                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13219
13220            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13221            for (int i = 0; i < N; ++i) {
13222                intentFilters = packageProviders.get(i).intents;
13223                if (intentFilters != null && intentFilters.size() > 0) {
13224                    PackageParser.ProviderIntentInfo[] array =
13225                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13226                    intentFilters.toArray(array);
13227                    listCut.add(array);
13228                }
13229            }
13230            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13231        }
13232
13233        public final void addProvider(PackageParser.Provider p) {
13234            if (mProviders.containsKey(p.getComponentName())) {
13235                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13236                return;
13237            }
13238
13239            mProviders.put(p.getComponentName(), p);
13240            if (DEBUG_SHOW_INFO) {
13241                Log.v(TAG, "  "
13242                        + (p.info.nonLocalizedLabel != null
13243                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13244                Log.v(TAG, "    Class=" + p.info.name);
13245            }
13246            final int NI = p.intents.size();
13247            int j;
13248            for (j = 0; j < NI; j++) {
13249                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13250                if (DEBUG_SHOW_INFO) {
13251                    Log.v(TAG, "    IntentFilter:");
13252                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13253                }
13254                if (!intent.debugCheck()) {
13255                    Log.w(TAG, "==> For Provider " + p.info.name);
13256                }
13257                addFilter(intent);
13258            }
13259        }
13260
13261        public final void removeProvider(PackageParser.Provider p) {
13262            mProviders.remove(p.getComponentName());
13263            if (DEBUG_SHOW_INFO) {
13264                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13265                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13266                Log.v(TAG, "    Class=" + p.info.name);
13267            }
13268            final int NI = p.intents.size();
13269            int j;
13270            for (j = 0; j < NI; j++) {
13271                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13272                if (DEBUG_SHOW_INFO) {
13273                    Log.v(TAG, "    IntentFilter:");
13274                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13275                }
13276                removeFilter(intent);
13277            }
13278        }
13279
13280        @Override
13281        protected boolean allowFilterResult(
13282                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13283            ProviderInfo filterPi = filter.provider.info;
13284            for (int i = dest.size() - 1; i >= 0; i--) {
13285                ProviderInfo destPi = dest.get(i).providerInfo;
13286                if (destPi.name == filterPi.name
13287                        && destPi.packageName == filterPi.packageName) {
13288                    return false;
13289                }
13290            }
13291            return true;
13292        }
13293
13294        @Override
13295        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13296            return new PackageParser.ProviderIntentInfo[size];
13297        }
13298
13299        @Override
13300        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13301            if (!sUserManager.exists(userId))
13302                return true;
13303            PackageParser.Package p = filter.provider.owner;
13304            if (p != null) {
13305                PackageSetting ps = (PackageSetting) p.mExtras;
13306                if (ps != null) {
13307                    // System apps are never considered stopped for purposes of
13308                    // filtering, because there may be no way for the user to
13309                    // actually re-launch them.
13310                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13311                            && ps.getStopped(userId);
13312                }
13313            }
13314            return false;
13315        }
13316
13317        @Override
13318        protected boolean isPackageForFilter(String packageName,
13319                PackageParser.ProviderIntentInfo info) {
13320            return packageName.equals(info.provider.owner.packageName);
13321        }
13322
13323        @Override
13324        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13325                int match, int userId) {
13326            if (!sUserManager.exists(userId))
13327                return null;
13328            final PackageParser.ProviderIntentInfo info = filter;
13329            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13330                return null;
13331            }
13332            final PackageParser.Provider provider = info.provider;
13333            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13334            if (ps == null) {
13335                return null;
13336            }
13337            final PackageUserState userState = ps.readUserState(userId);
13338            final boolean matchVisibleToInstantApp =
13339                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13340            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13341            // throw out filters that aren't visible to instant applications
13342            if (matchVisibleToInstantApp
13343                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13344                return null;
13345            }
13346            // throw out instant application filters if we're not explicitly requesting them
13347            if (!isInstantApp && userState.instantApp) {
13348                return null;
13349            }
13350            // throw out instant application filters if updates are available; will trigger
13351            // instant application resolution
13352            if (userState.instantApp && ps.isUpdateAvailable()) {
13353                return null;
13354            }
13355            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13356                    userState, userId);
13357            if (pi == null) {
13358                return null;
13359            }
13360            final ResolveInfo res = new ResolveInfo();
13361            res.providerInfo = pi;
13362            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13363                res.filter = filter;
13364            }
13365            res.priority = info.getPriority();
13366            res.preferredOrder = provider.owner.mPreferredOrder;
13367            res.match = match;
13368            res.isDefault = info.hasDefault;
13369            res.labelRes = info.labelRes;
13370            res.nonLocalizedLabel = info.nonLocalizedLabel;
13371            res.icon = info.icon;
13372            res.system = res.providerInfo.applicationInfo.isSystemApp();
13373            return res;
13374        }
13375
13376        @Override
13377        protected void sortResults(List<ResolveInfo> results) {
13378            Collections.sort(results, mResolvePrioritySorter);
13379        }
13380
13381        @Override
13382        protected void dumpFilter(PrintWriter out, String prefix,
13383                PackageParser.ProviderIntentInfo filter) {
13384            out.print(prefix);
13385            out.print(
13386                    Integer.toHexString(System.identityHashCode(filter.provider)));
13387            out.print(' ');
13388            filter.provider.printComponentShortName(out);
13389            out.print(" filter ");
13390            out.println(Integer.toHexString(System.identityHashCode(filter)));
13391        }
13392
13393        @Override
13394        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13395            return filter.provider;
13396        }
13397
13398        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13399            PackageParser.Provider provider = (PackageParser.Provider)label;
13400            out.print(prefix); out.print(
13401                    Integer.toHexString(System.identityHashCode(provider)));
13402                    out.print(' ');
13403                    provider.printComponentShortName(out);
13404            if (count > 1) {
13405                out.print(" ("); out.print(count); out.print(" filters)");
13406            }
13407            out.println();
13408        }
13409
13410        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13411                = new ArrayMap<ComponentName, PackageParser.Provider>();
13412        private int mFlags;
13413    }
13414
13415    static final class EphemeralIntentResolver
13416            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
13417        /**
13418         * The result that has the highest defined order. Ordering applies on a
13419         * per-package basis. Mapping is from package name to Pair of order and
13420         * EphemeralResolveInfo.
13421         * <p>
13422         * NOTE: This is implemented as a field variable for convenience and efficiency.
13423         * By having a field variable, we're able to track filter ordering as soon as
13424         * a non-zero order is defined. Otherwise, multiple loops across the result set
13425         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13426         * this needs to be contained entirely within {@link #filterResults}.
13427         */
13428        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13429
13430        @Override
13431        protected AuxiliaryResolveInfo[] newArray(int size) {
13432            return new AuxiliaryResolveInfo[size];
13433        }
13434
13435        @Override
13436        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
13437            return true;
13438        }
13439
13440        @Override
13441        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
13442                int userId) {
13443            if (!sUserManager.exists(userId)) {
13444                return null;
13445            }
13446            final String packageName = responseObj.resolveInfo.getPackageName();
13447            final Integer order = responseObj.getOrder();
13448            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13449                    mOrderResult.get(packageName);
13450            // ordering is enabled and this item's order isn't high enough
13451            if (lastOrderResult != null && lastOrderResult.first >= order) {
13452                return null;
13453            }
13454            final InstantAppResolveInfo res = responseObj.resolveInfo;
13455            if (order > 0) {
13456                // non-zero order, enable ordering
13457                mOrderResult.put(packageName, new Pair<>(order, res));
13458            }
13459            return responseObj;
13460        }
13461
13462        @Override
13463        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13464            // only do work if ordering is enabled [most of the time it won't be]
13465            if (mOrderResult.size() == 0) {
13466                return;
13467            }
13468            int resultSize = results.size();
13469            for (int i = 0; i < resultSize; i++) {
13470                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13471                final String packageName = info.getPackageName();
13472                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13473                if (savedInfo == null) {
13474                    // package doesn't having ordering
13475                    continue;
13476                }
13477                if (savedInfo.second == info) {
13478                    // circled back to the highest ordered item; remove from order list
13479                    mOrderResult.remove(savedInfo);
13480                    if (mOrderResult.size() == 0) {
13481                        // no more ordered items
13482                        break;
13483                    }
13484                    continue;
13485                }
13486                // item has a worse order, remove it from the result list
13487                results.remove(i);
13488                resultSize--;
13489                i--;
13490            }
13491        }
13492    }
13493
13494    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13495            new Comparator<ResolveInfo>() {
13496        public int compare(ResolveInfo r1, ResolveInfo r2) {
13497            int v1 = r1.priority;
13498            int v2 = r2.priority;
13499            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13500            if (v1 != v2) {
13501                return (v1 > v2) ? -1 : 1;
13502            }
13503            v1 = r1.preferredOrder;
13504            v2 = r2.preferredOrder;
13505            if (v1 != v2) {
13506                return (v1 > v2) ? -1 : 1;
13507            }
13508            if (r1.isDefault != r2.isDefault) {
13509                return r1.isDefault ? -1 : 1;
13510            }
13511            v1 = r1.match;
13512            v2 = r2.match;
13513            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13514            if (v1 != v2) {
13515                return (v1 > v2) ? -1 : 1;
13516            }
13517            if (r1.system != r2.system) {
13518                return r1.system ? -1 : 1;
13519            }
13520            if (r1.activityInfo != null) {
13521                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13522            }
13523            if (r1.serviceInfo != null) {
13524                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13525            }
13526            if (r1.providerInfo != null) {
13527                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13528            }
13529            return 0;
13530        }
13531    };
13532
13533    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13534            new Comparator<ProviderInfo>() {
13535        public int compare(ProviderInfo p1, ProviderInfo p2) {
13536            final int v1 = p1.initOrder;
13537            final int v2 = p2.initOrder;
13538            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13539        }
13540    };
13541
13542    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13543            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13544            final int[] userIds) {
13545        mHandler.post(new Runnable() {
13546            @Override
13547            public void run() {
13548                try {
13549                    final IActivityManager am = ActivityManager.getService();
13550                    if (am == null) return;
13551                    final int[] resolvedUserIds;
13552                    if (userIds == null) {
13553                        resolvedUserIds = am.getRunningUserIds();
13554                    } else {
13555                        resolvedUserIds = userIds;
13556                    }
13557                    for (int id : resolvedUserIds) {
13558                        final Intent intent = new Intent(action,
13559                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13560                        if (extras != null) {
13561                            intent.putExtras(extras);
13562                        }
13563                        if (targetPkg != null) {
13564                            intent.setPackage(targetPkg);
13565                        }
13566                        // Modify the UID when posting to other users
13567                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13568                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13569                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13570                            intent.putExtra(Intent.EXTRA_UID, uid);
13571                        }
13572                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13573                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13574                        if (DEBUG_BROADCASTS) {
13575                            RuntimeException here = new RuntimeException("here");
13576                            here.fillInStackTrace();
13577                            Slog.d(TAG, "Sending to user " + id + ": "
13578                                    + intent.toShortString(false, true, false, false)
13579                                    + " " + intent.getExtras(), here);
13580                        }
13581                        am.broadcastIntent(null, intent, null, finishedReceiver,
13582                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13583                                null, finishedReceiver != null, false, id);
13584                    }
13585                } catch (RemoteException ex) {
13586                }
13587            }
13588        });
13589    }
13590
13591    /**
13592     * Check if the external storage media is available. This is true if there
13593     * is a mounted external storage medium or if the external storage is
13594     * emulated.
13595     */
13596    private boolean isExternalMediaAvailable() {
13597        return mMediaMounted || Environment.isExternalStorageEmulated();
13598    }
13599
13600    @Override
13601    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13602        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13603            return null;
13604        }
13605        // writer
13606        synchronized (mPackages) {
13607            if (!isExternalMediaAvailable()) {
13608                // If the external storage is no longer mounted at this point,
13609                // the caller may not have been able to delete all of this
13610                // packages files and can not delete any more.  Bail.
13611                return null;
13612            }
13613            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13614            if (lastPackage != null) {
13615                pkgs.remove(lastPackage);
13616            }
13617            if (pkgs.size() > 0) {
13618                return pkgs.get(0);
13619            }
13620        }
13621        return null;
13622    }
13623
13624    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13625        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13626                userId, andCode ? 1 : 0, packageName);
13627        if (mSystemReady) {
13628            msg.sendToTarget();
13629        } else {
13630            if (mPostSystemReadyMessages == null) {
13631                mPostSystemReadyMessages = new ArrayList<>();
13632            }
13633            mPostSystemReadyMessages.add(msg);
13634        }
13635    }
13636
13637    void startCleaningPackages() {
13638        // reader
13639        if (!isExternalMediaAvailable()) {
13640            return;
13641        }
13642        synchronized (mPackages) {
13643            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13644                return;
13645            }
13646        }
13647        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13648        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13649        IActivityManager am = ActivityManager.getService();
13650        if (am != null) {
13651            int dcsUid = -1;
13652            synchronized (mPackages) {
13653                if (!mDefaultContainerWhitelisted) {
13654                    mDefaultContainerWhitelisted = true;
13655                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13656                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13657                }
13658            }
13659            try {
13660                if (dcsUid > 0) {
13661                    am.backgroundWhitelistUid(dcsUid);
13662                }
13663                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13664                        UserHandle.USER_SYSTEM);
13665            } catch (RemoteException e) {
13666            }
13667        }
13668    }
13669
13670    @Override
13671    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13672            int installFlags, String installerPackageName, int userId) {
13673        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13674
13675        final int callingUid = Binder.getCallingUid();
13676        enforceCrossUserPermission(callingUid, userId,
13677                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13678
13679        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13680            try {
13681                if (observer != null) {
13682                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13683                }
13684            } catch (RemoteException re) {
13685            }
13686            return;
13687        }
13688
13689        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13690            installFlags |= PackageManager.INSTALL_FROM_ADB;
13691
13692        } else {
13693            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13694            // about installerPackageName.
13695
13696            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13697            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13698        }
13699
13700        UserHandle user;
13701        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13702            user = UserHandle.ALL;
13703        } else {
13704            user = new UserHandle(userId);
13705        }
13706
13707        // Only system components can circumvent runtime permissions when installing.
13708        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13709                && mContext.checkCallingOrSelfPermission(Manifest.permission
13710                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13711            throw new SecurityException("You need the "
13712                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13713                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13714        }
13715
13716        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13717                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13718            throw new IllegalArgumentException(
13719                    "New installs into ASEC containers no longer supported");
13720        }
13721
13722        final File originFile = new File(originPath);
13723        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13724
13725        final Message msg = mHandler.obtainMessage(INIT_COPY);
13726        final VerificationInfo verificationInfo = new VerificationInfo(
13727                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13728        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13729                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13730                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13731                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13732        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13733        msg.obj = params;
13734
13735        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13736                System.identityHashCode(msg.obj));
13737        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13738                System.identityHashCode(msg.obj));
13739
13740        mHandler.sendMessage(msg);
13741    }
13742
13743
13744    /**
13745     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13746     * it is acting on behalf on an enterprise or the user).
13747     *
13748     * Note that the ordering of the conditionals in this method is important. The checks we perform
13749     * are as follows, in this order:
13750     *
13751     * 1) If the install is being performed by a system app, we can trust the app to have set the
13752     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13753     *    what it is.
13754     * 2) If the install is being performed by a device or profile owner app, the install reason
13755     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13756     *    set the install reason correctly. If the app targets an older SDK version where install
13757     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13758     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13759     * 3) In all other cases, the install is being performed by a regular app that is neither part
13760     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13761     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13762     *    set to enterprise policy and if so, change it to unknown instead.
13763     */
13764    private int fixUpInstallReason(String installerPackageName, int installerUid,
13765            int installReason) {
13766        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13767                == PERMISSION_GRANTED) {
13768            // If the install is being performed by a system app, we trust that app to have set the
13769            // install reason correctly.
13770            return installReason;
13771        }
13772
13773        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13774            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13775        if (dpm != null) {
13776            ComponentName owner = null;
13777            try {
13778                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13779                if (owner == null) {
13780                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13781                }
13782            } catch (RemoteException e) {
13783            }
13784            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13785                // If the install is being performed by a device or profile owner, the install
13786                // reason should be enterprise policy.
13787                return PackageManager.INSTALL_REASON_POLICY;
13788            }
13789        }
13790
13791        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13792            // If the install is being performed by a regular app (i.e. neither system app nor
13793            // device or profile owner), we have no reason to believe that the app is acting on
13794            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13795            // change it to unknown instead.
13796            return PackageManager.INSTALL_REASON_UNKNOWN;
13797        }
13798
13799        // If the install is being performed by a regular app and the install reason was set to any
13800        // value but enterprise policy, leave the install reason unchanged.
13801        return installReason;
13802    }
13803
13804    void installStage(String packageName, File stagedDir, String stagedCid,
13805            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13806            String installerPackageName, int installerUid, UserHandle user,
13807            Certificate[][] certificates) {
13808        if (DEBUG_EPHEMERAL) {
13809            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13810                Slog.d(TAG, "Ephemeral install of " + packageName);
13811            }
13812        }
13813        final VerificationInfo verificationInfo = new VerificationInfo(
13814                sessionParams.originatingUri, sessionParams.referrerUri,
13815                sessionParams.originatingUid, installerUid);
13816
13817        final OriginInfo origin;
13818        if (stagedDir != null) {
13819            origin = OriginInfo.fromStagedFile(stagedDir);
13820        } else {
13821            origin = OriginInfo.fromStagedContainer(stagedCid);
13822        }
13823
13824        final Message msg = mHandler.obtainMessage(INIT_COPY);
13825        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13826                sessionParams.installReason);
13827        final InstallParams params = new InstallParams(origin, null, observer,
13828                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13829                verificationInfo, user, sessionParams.abiOverride,
13830                sessionParams.grantedRuntimePermissions, certificates, installReason);
13831        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13832        msg.obj = params;
13833
13834        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13835                System.identityHashCode(msg.obj));
13836        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13837                System.identityHashCode(msg.obj));
13838
13839        mHandler.sendMessage(msg);
13840    }
13841
13842    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13843            int userId) {
13844        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13845        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13846
13847        // Send a session commit broadcast
13848        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13849        info.installReason = pkgSetting.getInstallReason(userId);
13850        info.appPackageName = packageName;
13851        sendSessionCommitBroadcast(info, userId);
13852    }
13853
13854    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13855        if (ArrayUtils.isEmpty(userIds)) {
13856            return;
13857        }
13858        Bundle extras = new Bundle(1);
13859        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13860        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13861
13862        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13863                packageName, extras, 0, null, null, userIds);
13864        if (isSystem) {
13865            mHandler.post(() -> {
13866                        for (int userId : userIds) {
13867                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13868                        }
13869                    }
13870            );
13871        }
13872    }
13873
13874    /**
13875     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13876     * automatically without needing an explicit launch.
13877     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13878     */
13879    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13880        // If user is not running, the app didn't miss any broadcast
13881        if (!mUserManagerInternal.isUserRunning(userId)) {
13882            return;
13883        }
13884        final IActivityManager am = ActivityManager.getService();
13885        try {
13886            // Deliver LOCKED_BOOT_COMPLETED first
13887            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13888                    .setPackage(packageName);
13889            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13890            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13891                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13892
13893            // Deliver BOOT_COMPLETED only if user is unlocked
13894            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13895                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13896                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13897                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13898            }
13899        } catch (RemoteException e) {
13900            throw e.rethrowFromSystemServer();
13901        }
13902    }
13903
13904    @Override
13905    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13906            int userId) {
13907        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13908        PackageSetting pkgSetting;
13909        final int uid = Binder.getCallingUid();
13910        enforceCrossUserPermission(uid, userId,
13911                true /* requireFullPermission */, true /* checkShell */,
13912                "setApplicationHiddenSetting for user " + userId);
13913
13914        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13915            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13916            return false;
13917        }
13918
13919        long callingId = Binder.clearCallingIdentity();
13920        try {
13921            boolean sendAdded = false;
13922            boolean sendRemoved = false;
13923            // writer
13924            synchronized (mPackages) {
13925                pkgSetting = mSettings.mPackages.get(packageName);
13926                if (pkgSetting == null) {
13927                    return false;
13928                }
13929                // Do not allow "android" is being disabled
13930                if ("android".equals(packageName)) {
13931                    Slog.w(TAG, "Cannot hide package: android");
13932                    return false;
13933                }
13934                // Cannot hide static shared libs as they are considered
13935                // a part of the using app (emulating static linking). Also
13936                // static libs are installed always on internal storage.
13937                PackageParser.Package pkg = mPackages.get(packageName);
13938                if (pkg != null && pkg.staticSharedLibName != null) {
13939                    Slog.w(TAG, "Cannot hide package: " + packageName
13940                            + " providing static shared library: "
13941                            + pkg.staticSharedLibName);
13942                    return false;
13943                }
13944                // Only allow protected packages to hide themselves.
13945                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13946                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13947                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13948                    return false;
13949                }
13950
13951                if (pkgSetting.getHidden(userId) != hidden) {
13952                    pkgSetting.setHidden(hidden, userId);
13953                    mSettings.writePackageRestrictionsLPr(userId);
13954                    if (hidden) {
13955                        sendRemoved = true;
13956                    } else {
13957                        sendAdded = true;
13958                    }
13959                }
13960            }
13961            if (sendAdded) {
13962                sendPackageAddedForUser(packageName, pkgSetting, userId);
13963                return true;
13964            }
13965            if (sendRemoved) {
13966                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13967                        "hiding pkg");
13968                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13969                return true;
13970            }
13971        } finally {
13972            Binder.restoreCallingIdentity(callingId);
13973        }
13974        return false;
13975    }
13976
13977    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13978            int userId) {
13979        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13980        info.removedPackage = packageName;
13981        info.installerPackageName = pkgSetting.installerPackageName;
13982        info.removedUsers = new int[] {userId};
13983        info.broadcastUsers = new int[] {userId};
13984        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13985        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13986    }
13987
13988    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13989        if (pkgList.length > 0) {
13990            Bundle extras = new Bundle(1);
13991            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13992
13993            sendPackageBroadcast(
13994                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13995                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13996                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13997                    new int[] {userId});
13998        }
13999    }
14000
14001    /**
14002     * Returns true if application is not found or there was an error. Otherwise it returns
14003     * the hidden state of the package for the given user.
14004     */
14005    @Override
14006    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14007        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14008        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14009                true /* requireFullPermission */, false /* checkShell */,
14010                "getApplicationHidden for user " + userId);
14011        PackageSetting pkgSetting;
14012        long callingId = Binder.clearCallingIdentity();
14013        try {
14014            // writer
14015            synchronized (mPackages) {
14016                pkgSetting = mSettings.mPackages.get(packageName);
14017                if (pkgSetting == null) {
14018                    return true;
14019                }
14020                return pkgSetting.getHidden(userId);
14021            }
14022        } finally {
14023            Binder.restoreCallingIdentity(callingId);
14024        }
14025    }
14026
14027    /**
14028     * @hide
14029     */
14030    @Override
14031    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14032            int installReason) {
14033        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14034                null);
14035        PackageSetting pkgSetting;
14036        final int uid = Binder.getCallingUid();
14037        enforceCrossUserPermission(uid, userId,
14038                true /* requireFullPermission */, true /* checkShell */,
14039                "installExistingPackage for user " + userId);
14040        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14041            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14042        }
14043
14044        long callingId = Binder.clearCallingIdentity();
14045        try {
14046            boolean installed = false;
14047            final boolean instantApp =
14048                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14049            final boolean fullApp =
14050                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14051
14052            // writer
14053            synchronized (mPackages) {
14054                pkgSetting = mSettings.mPackages.get(packageName);
14055                if (pkgSetting == null) {
14056                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14057                }
14058                if (!pkgSetting.getInstalled(userId)) {
14059                    pkgSetting.setInstalled(true, userId);
14060                    pkgSetting.setHidden(false, userId);
14061                    pkgSetting.setInstallReason(installReason, userId);
14062                    mSettings.writePackageRestrictionsLPr(userId);
14063                    mSettings.writeKernelMappingLPr(pkgSetting);
14064                    installed = true;
14065                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14066                    // upgrade app from instant to full; we don't allow app downgrade
14067                    installed = true;
14068                }
14069                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14070            }
14071
14072            if (installed) {
14073                if (pkgSetting.pkg != null) {
14074                    synchronized (mInstallLock) {
14075                        // We don't need to freeze for a brand new install
14076                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14077                    }
14078                }
14079                sendPackageAddedForUser(packageName, pkgSetting, userId);
14080                synchronized (mPackages) {
14081                    updateSequenceNumberLP(packageName, new int[]{ userId });
14082                }
14083            }
14084        } finally {
14085            Binder.restoreCallingIdentity(callingId);
14086        }
14087
14088        return PackageManager.INSTALL_SUCCEEDED;
14089    }
14090
14091    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14092            boolean instantApp, boolean fullApp) {
14093        // no state specified; do nothing
14094        if (!instantApp && !fullApp) {
14095            return;
14096        }
14097        if (userId != UserHandle.USER_ALL) {
14098            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14099                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14100            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14101                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14102            }
14103        } else {
14104            for (int currentUserId : sUserManager.getUserIds()) {
14105                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14106                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14107                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14108                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14109                }
14110            }
14111        }
14112    }
14113
14114    boolean isUserRestricted(int userId, String restrictionKey) {
14115        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14116        if (restrictions.getBoolean(restrictionKey, false)) {
14117            Log.w(TAG, "User is restricted: " + restrictionKey);
14118            return true;
14119        }
14120        return false;
14121    }
14122
14123    @Override
14124    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14125            int userId) {
14126        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14127        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14128                true /* requireFullPermission */, true /* checkShell */,
14129                "setPackagesSuspended for user " + userId);
14130
14131        if (ArrayUtils.isEmpty(packageNames)) {
14132            return packageNames;
14133        }
14134
14135        // List of package names for whom the suspended state has changed.
14136        List<String> changedPackages = new ArrayList<>(packageNames.length);
14137        // List of package names for whom the suspended state is not set as requested in this
14138        // method.
14139        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14140        long callingId = Binder.clearCallingIdentity();
14141        try {
14142            for (int i = 0; i < packageNames.length; i++) {
14143                String packageName = packageNames[i];
14144                boolean changed = false;
14145                final int appId;
14146                synchronized (mPackages) {
14147                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14148                    if (pkgSetting == null) {
14149                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14150                                + "\". Skipping suspending/un-suspending.");
14151                        unactionedPackages.add(packageName);
14152                        continue;
14153                    }
14154                    appId = pkgSetting.appId;
14155                    if (pkgSetting.getSuspended(userId) != suspended) {
14156                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14157                            unactionedPackages.add(packageName);
14158                            continue;
14159                        }
14160                        pkgSetting.setSuspended(suspended, userId);
14161                        mSettings.writePackageRestrictionsLPr(userId);
14162                        changed = true;
14163                        changedPackages.add(packageName);
14164                    }
14165                }
14166
14167                if (changed && suspended) {
14168                    killApplication(packageName, UserHandle.getUid(userId, appId),
14169                            "suspending package");
14170                }
14171            }
14172        } finally {
14173            Binder.restoreCallingIdentity(callingId);
14174        }
14175
14176        if (!changedPackages.isEmpty()) {
14177            sendPackagesSuspendedForUser(changedPackages.toArray(
14178                    new String[changedPackages.size()]), userId, suspended);
14179        }
14180
14181        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14182    }
14183
14184    @Override
14185    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14186        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14187                true /* requireFullPermission */, false /* checkShell */,
14188                "isPackageSuspendedForUser for user " + userId);
14189        synchronized (mPackages) {
14190            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14191            if (pkgSetting == null) {
14192                throw new IllegalArgumentException("Unknown target package: " + packageName);
14193            }
14194            return pkgSetting.getSuspended(userId);
14195        }
14196    }
14197
14198    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14199        if (isPackageDeviceAdmin(packageName, userId)) {
14200            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14201                    + "\": has an active device admin");
14202            return false;
14203        }
14204
14205        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14206        if (packageName.equals(activeLauncherPackageName)) {
14207            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14208                    + "\": contains the active launcher");
14209            return false;
14210        }
14211
14212        if (packageName.equals(mRequiredInstallerPackage)) {
14213            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14214                    + "\": required for package installation");
14215            return false;
14216        }
14217
14218        if (packageName.equals(mRequiredUninstallerPackage)) {
14219            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14220                    + "\": required for package uninstallation");
14221            return false;
14222        }
14223
14224        if (packageName.equals(mRequiredVerifierPackage)) {
14225            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14226                    + "\": required for package verification");
14227            return false;
14228        }
14229
14230        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14231            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14232                    + "\": is the default dialer");
14233            return false;
14234        }
14235
14236        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14237            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14238                    + "\": protected package");
14239            return false;
14240        }
14241
14242        // Cannot suspend static shared libs as they are considered
14243        // a part of the using app (emulating static linking). Also
14244        // static libs are installed always on internal storage.
14245        PackageParser.Package pkg = mPackages.get(packageName);
14246        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14247            Slog.w(TAG, "Cannot suspend package: " + packageName
14248                    + " providing static shared library: "
14249                    + pkg.staticSharedLibName);
14250            return false;
14251        }
14252
14253        return true;
14254    }
14255
14256    private String getActiveLauncherPackageName(int userId) {
14257        Intent intent = new Intent(Intent.ACTION_MAIN);
14258        intent.addCategory(Intent.CATEGORY_HOME);
14259        ResolveInfo resolveInfo = resolveIntent(
14260                intent,
14261                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14262                PackageManager.MATCH_DEFAULT_ONLY,
14263                userId);
14264
14265        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14266    }
14267
14268    private String getDefaultDialerPackageName(int userId) {
14269        synchronized (mPackages) {
14270            return mSettings.getDefaultDialerPackageNameLPw(userId);
14271        }
14272    }
14273
14274    @Override
14275    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14276        mContext.enforceCallingOrSelfPermission(
14277                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14278                "Only package verification agents can verify applications");
14279
14280        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14281        final PackageVerificationResponse response = new PackageVerificationResponse(
14282                verificationCode, Binder.getCallingUid());
14283        msg.arg1 = id;
14284        msg.obj = response;
14285        mHandler.sendMessage(msg);
14286    }
14287
14288    @Override
14289    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14290            long millisecondsToDelay) {
14291        mContext.enforceCallingOrSelfPermission(
14292                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14293                "Only package verification agents can extend verification timeouts");
14294
14295        final PackageVerificationState state = mPendingVerification.get(id);
14296        final PackageVerificationResponse response = new PackageVerificationResponse(
14297                verificationCodeAtTimeout, Binder.getCallingUid());
14298
14299        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14300            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14301        }
14302        if (millisecondsToDelay < 0) {
14303            millisecondsToDelay = 0;
14304        }
14305        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14306                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14307            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14308        }
14309
14310        if ((state != null) && !state.timeoutExtended()) {
14311            state.extendTimeout();
14312
14313            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14314            msg.arg1 = id;
14315            msg.obj = response;
14316            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14317        }
14318    }
14319
14320    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14321            int verificationCode, UserHandle user) {
14322        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14323        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14324        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14325        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14326        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14327
14328        mContext.sendBroadcastAsUser(intent, user,
14329                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14330    }
14331
14332    private ComponentName matchComponentForVerifier(String packageName,
14333            List<ResolveInfo> receivers) {
14334        ActivityInfo targetReceiver = null;
14335
14336        final int NR = receivers.size();
14337        for (int i = 0; i < NR; i++) {
14338            final ResolveInfo info = receivers.get(i);
14339            if (info.activityInfo == null) {
14340                continue;
14341            }
14342
14343            if (packageName.equals(info.activityInfo.packageName)) {
14344                targetReceiver = info.activityInfo;
14345                break;
14346            }
14347        }
14348
14349        if (targetReceiver == null) {
14350            return null;
14351        }
14352
14353        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14354    }
14355
14356    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14357            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14358        if (pkgInfo.verifiers.length == 0) {
14359            return null;
14360        }
14361
14362        final int N = pkgInfo.verifiers.length;
14363        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14364        for (int i = 0; i < N; i++) {
14365            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14366
14367            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14368                    receivers);
14369            if (comp == null) {
14370                continue;
14371            }
14372
14373            final int verifierUid = getUidForVerifier(verifierInfo);
14374            if (verifierUid == -1) {
14375                continue;
14376            }
14377
14378            if (DEBUG_VERIFY) {
14379                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14380                        + " with the correct signature");
14381            }
14382            sufficientVerifiers.add(comp);
14383            verificationState.addSufficientVerifier(verifierUid);
14384        }
14385
14386        return sufficientVerifiers;
14387    }
14388
14389    private int getUidForVerifier(VerifierInfo verifierInfo) {
14390        synchronized (mPackages) {
14391            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14392            if (pkg == null) {
14393                return -1;
14394            } else if (pkg.mSignatures.length != 1) {
14395                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14396                        + " has more than one signature; ignoring");
14397                return -1;
14398            }
14399
14400            /*
14401             * If the public key of the package's signature does not match
14402             * our expected public key, then this is a different package and
14403             * we should skip.
14404             */
14405
14406            final byte[] expectedPublicKey;
14407            try {
14408                final Signature verifierSig = pkg.mSignatures[0];
14409                final PublicKey publicKey = verifierSig.getPublicKey();
14410                expectedPublicKey = publicKey.getEncoded();
14411            } catch (CertificateException e) {
14412                return -1;
14413            }
14414
14415            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14416
14417            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14418                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14419                        + " does not have the expected public key; ignoring");
14420                return -1;
14421            }
14422
14423            return pkg.applicationInfo.uid;
14424        }
14425    }
14426
14427    @Override
14428    public void finishPackageInstall(int token, boolean didLaunch) {
14429        enforceSystemOrRoot("Only the system is allowed to finish installs");
14430
14431        if (DEBUG_INSTALL) {
14432            Slog.v(TAG, "BM finishing package install for " + token);
14433        }
14434        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14435
14436        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14437        mHandler.sendMessage(msg);
14438    }
14439
14440    /**
14441     * Get the verification agent timeout.  Used for both the APK verifier and the
14442     * intent filter verifier.
14443     *
14444     * @return verification timeout in milliseconds
14445     */
14446    private long getVerificationTimeout() {
14447        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14448                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14449                DEFAULT_VERIFICATION_TIMEOUT);
14450    }
14451
14452    /**
14453     * Get the default verification agent response code.
14454     *
14455     * @return default verification response code
14456     */
14457    private int getDefaultVerificationResponse(UserHandle user) {
14458        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14459            return PackageManager.VERIFICATION_REJECT;
14460        }
14461        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14462                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14463                DEFAULT_VERIFICATION_RESPONSE);
14464    }
14465
14466    /**
14467     * Check whether or not package verification has been enabled.
14468     *
14469     * @return true if verification should be performed
14470     */
14471    private boolean isVerificationEnabled(int userId, int installFlags) {
14472        if (!DEFAULT_VERIFY_ENABLE) {
14473            return false;
14474        }
14475
14476        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14477
14478        // Check if installing from ADB
14479        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14480            // Do not run verification in a test harness environment
14481            if (ActivityManager.isRunningInTestHarness()) {
14482                return false;
14483            }
14484            if (ensureVerifyAppsEnabled) {
14485                return true;
14486            }
14487            // Check if the developer does not want package verification for ADB installs
14488            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14489                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14490                return false;
14491            }
14492        }
14493
14494        if (ensureVerifyAppsEnabled) {
14495            return true;
14496        }
14497
14498        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14499                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14500    }
14501
14502    @Override
14503    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14504            throws RemoteException {
14505        mContext.enforceCallingOrSelfPermission(
14506                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14507                "Only intentfilter verification agents can verify applications");
14508
14509        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14510        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14511                Binder.getCallingUid(), verificationCode, failedDomains);
14512        msg.arg1 = id;
14513        msg.obj = response;
14514        mHandler.sendMessage(msg);
14515    }
14516
14517    @Override
14518    public int getIntentVerificationStatus(String packageName, int userId) {
14519        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14520            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14521        }
14522        synchronized (mPackages) {
14523            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14524        }
14525    }
14526
14527    @Override
14528    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14529        mContext.enforceCallingOrSelfPermission(
14530                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14531
14532        boolean result = false;
14533        synchronized (mPackages) {
14534            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14535        }
14536        if (result) {
14537            scheduleWritePackageRestrictionsLocked(userId);
14538        }
14539        return result;
14540    }
14541
14542    @Override
14543    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14544            String packageName) {
14545        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14546            return ParceledListSlice.emptyList();
14547        }
14548        synchronized (mPackages) {
14549            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14550        }
14551    }
14552
14553    @Override
14554    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14555        if (TextUtils.isEmpty(packageName)) {
14556            return ParceledListSlice.emptyList();
14557        }
14558        synchronized (mPackages) {
14559            PackageParser.Package pkg = mPackages.get(packageName);
14560            if (pkg == null || pkg.activities == null) {
14561                return ParceledListSlice.emptyList();
14562            }
14563            final int count = pkg.activities.size();
14564            ArrayList<IntentFilter> result = new ArrayList<>();
14565            for (int n=0; n<count; n++) {
14566                PackageParser.Activity activity = pkg.activities.get(n);
14567                if (activity.intents != null && activity.intents.size() > 0) {
14568                    result.addAll(activity.intents);
14569                }
14570            }
14571            return new ParceledListSlice<>(result);
14572        }
14573    }
14574
14575    @Override
14576    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14577        mContext.enforceCallingOrSelfPermission(
14578                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14579
14580        synchronized (mPackages) {
14581            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14582            if (packageName != null) {
14583                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14584                        packageName, userId);
14585            }
14586            return result;
14587        }
14588    }
14589
14590    @Override
14591    public String getDefaultBrowserPackageName(int userId) {
14592        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14593            return null;
14594        }
14595        synchronized (mPackages) {
14596            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14597        }
14598    }
14599
14600    /**
14601     * Get the "allow unknown sources" setting.
14602     *
14603     * @return the current "allow unknown sources" setting
14604     */
14605    private int getUnknownSourcesSettings() {
14606        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14607                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14608                -1);
14609    }
14610
14611    @Override
14612    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14613        final int callingUid = Binder.getCallingUid();
14614        if (getInstantAppPackageName(callingUid) != null) {
14615            return;
14616        }
14617        // writer
14618        synchronized (mPackages) {
14619            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14620            if (targetPackageSetting == null) {
14621                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14622            }
14623
14624            PackageSetting installerPackageSetting;
14625            if (installerPackageName != null) {
14626                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14627                if (installerPackageSetting == null) {
14628                    throw new IllegalArgumentException("Unknown installer package: "
14629                            + installerPackageName);
14630                }
14631            } else {
14632                installerPackageSetting = null;
14633            }
14634
14635            Signature[] callerSignature;
14636            Object obj = mSettings.getUserIdLPr(callingUid);
14637            if (obj != null) {
14638                if (obj instanceof SharedUserSetting) {
14639                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14640                } else if (obj instanceof PackageSetting) {
14641                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14642                } else {
14643                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14644                }
14645            } else {
14646                throw new SecurityException("Unknown calling UID: " + callingUid);
14647            }
14648
14649            // Verify: can't set installerPackageName to a package that is
14650            // not signed with the same cert as the caller.
14651            if (installerPackageSetting != null) {
14652                if (compareSignatures(callerSignature,
14653                        installerPackageSetting.signatures.mSignatures)
14654                        != PackageManager.SIGNATURE_MATCH) {
14655                    throw new SecurityException(
14656                            "Caller does not have same cert as new installer package "
14657                            + installerPackageName);
14658                }
14659            }
14660
14661            // Verify: if target already has an installer package, it must
14662            // be signed with the same cert as the caller.
14663            if (targetPackageSetting.installerPackageName != null) {
14664                PackageSetting setting = mSettings.mPackages.get(
14665                        targetPackageSetting.installerPackageName);
14666                // If the currently set package isn't valid, then it's always
14667                // okay to change it.
14668                if (setting != null) {
14669                    if (compareSignatures(callerSignature,
14670                            setting.signatures.mSignatures)
14671                            != PackageManager.SIGNATURE_MATCH) {
14672                        throw new SecurityException(
14673                                "Caller does not have same cert as old installer package "
14674                                + targetPackageSetting.installerPackageName);
14675                    }
14676                }
14677            }
14678
14679            // Okay!
14680            targetPackageSetting.installerPackageName = installerPackageName;
14681            if (installerPackageName != null) {
14682                mSettings.mInstallerPackages.add(installerPackageName);
14683            }
14684            scheduleWriteSettingsLocked();
14685        }
14686    }
14687
14688    @Override
14689    public void setApplicationCategoryHint(String packageName, int categoryHint,
14690            String callerPackageName) {
14691        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14692            throw new SecurityException("Instant applications don't have access to this method");
14693        }
14694        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14695                callerPackageName);
14696        synchronized (mPackages) {
14697            PackageSetting ps = mSettings.mPackages.get(packageName);
14698            if (ps == null) {
14699                throw new IllegalArgumentException("Unknown target package " + packageName);
14700            }
14701
14702            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14703                throw new IllegalArgumentException("Calling package " + callerPackageName
14704                        + " is not installer for " + packageName);
14705            }
14706
14707            if (ps.categoryHint != categoryHint) {
14708                ps.categoryHint = categoryHint;
14709                scheduleWriteSettingsLocked();
14710            }
14711        }
14712    }
14713
14714    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14715        // Queue up an async operation since the package installation may take a little while.
14716        mHandler.post(new Runnable() {
14717            public void run() {
14718                mHandler.removeCallbacks(this);
14719                 // Result object to be returned
14720                PackageInstalledInfo res = new PackageInstalledInfo();
14721                res.setReturnCode(currentStatus);
14722                res.uid = -1;
14723                res.pkg = null;
14724                res.removedInfo = null;
14725                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14726                    args.doPreInstall(res.returnCode);
14727                    synchronized (mInstallLock) {
14728                        installPackageTracedLI(args, res);
14729                    }
14730                    args.doPostInstall(res.returnCode, res.uid);
14731                }
14732
14733                // A restore should be performed at this point if (a) the install
14734                // succeeded, (b) the operation is not an update, and (c) the new
14735                // package has not opted out of backup participation.
14736                final boolean update = res.removedInfo != null
14737                        && res.removedInfo.removedPackage != null;
14738                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14739                boolean doRestore = !update
14740                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14741
14742                // Set up the post-install work request bookkeeping.  This will be used
14743                // and cleaned up by the post-install event handling regardless of whether
14744                // there's a restore pass performed.  Token values are >= 1.
14745                int token;
14746                if (mNextInstallToken < 0) mNextInstallToken = 1;
14747                token = mNextInstallToken++;
14748
14749                PostInstallData data = new PostInstallData(args, res);
14750                mRunningInstalls.put(token, data);
14751                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14752
14753                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14754                    // Pass responsibility to the Backup Manager.  It will perform a
14755                    // restore if appropriate, then pass responsibility back to the
14756                    // Package Manager to run the post-install observer callbacks
14757                    // and broadcasts.
14758                    IBackupManager bm = IBackupManager.Stub.asInterface(
14759                            ServiceManager.getService(Context.BACKUP_SERVICE));
14760                    if (bm != null) {
14761                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14762                                + " to BM for possible restore");
14763                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14764                        try {
14765                            // TODO: http://b/22388012
14766                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14767                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14768                            } else {
14769                                doRestore = false;
14770                            }
14771                        } catch (RemoteException e) {
14772                            // can't happen; the backup manager is local
14773                        } catch (Exception e) {
14774                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14775                            doRestore = false;
14776                        }
14777                    } else {
14778                        Slog.e(TAG, "Backup Manager not found!");
14779                        doRestore = false;
14780                    }
14781                }
14782
14783                if (!doRestore) {
14784                    // No restore possible, or the Backup Manager was mysteriously not
14785                    // available -- just fire the post-install work request directly.
14786                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14787
14788                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14789
14790                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14791                    mHandler.sendMessage(msg);
14792                }
14793            }
14794        });
14795    }
14796
14797    /**
14798     * Callback from PackageSettings whenever an app is first transitioned out of the
14799     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14800     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14801     * here whether the app is the target of an ongoing install, and only send the
14802     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14803     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14804     * handling.
14805     */
14806    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14807        // Serialize this with the rest of the install-process message chain.  In the
14808        // restore-at-install case, this Runnable will necessarily run before the
14809        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14810        // are coherent.  In the non-restore case, the app has already completed install
14811        // and been launched through some other means, so it is not in a problematic
14812        // state for observers to see the FIRST_LAUNCH signal.
14813        mHandler.post(new Runnable() {
14814            @Override
14815            public void run() {
14816                for (int i = 0; i < mRunningInstalls.size(); i++) {
14817                    final PostInstallData data = mRunningInstalls.valueAt(i);
14818                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14819                        continue;
14820                    }
14821                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14822                        // right package; but is it for the right user?
14823                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14824                            if (userId == data.res.newUsers[uIndex]) {
14825                                if (DEBUG_BACKUP) {
14826                                    Slog.i(TAG, "Package " + pkgName
14827                                            + " being restored so deferring FIRST_LAUNCH");
14828                                }
14829                                return;
14830                            }
14831                        }
14832                    }
14833                }
14834                // didn't find it, so not being restored
14835                if (DEBUG_BACKUP) {
14836                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14837                }
14838                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14839            }
14840        });
14841    }
14842
14843    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14844        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14845                installerPkg, null, userIds);
14846    }
14847
14848    private abstract class HandlerParams {
14849        private static final int MAX_RETRIES = 4;
14850
14851        /**
14852         * Number of times startCopy() has been attempted and had a non-fatal
14853         * error.
14854         */
14855        private int mRetries = 0;
14856
14857        /** User handle for the user requesting the information or installation. */
14858        private final UserHandle mUser;
14859        String traceMethod;
14860        int traceCookie;
14861
14862        HandlerParams(UserHandle user) {
14863            mUser = user;
14864        }
14865
14866        UserHandle getUser() {
14867            return mUser;
14868        }
14869
14870        HandlerParams setTraceMethod(String traceMethod) {
14871            this.traceMethod = traceMethod;
14872            return this;
14873        }
14874
14875        HandlerParams setTraceCookie(int traceCookie) {
14876            this.traceCookie = traceCookie;
14877            return this;
14878        }
14879
14880        final boolean startCopy() {
14881            boolean res;
14882            try {
14883                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14884
14885                if (++mRetries > MAX_RETRIES) {
14886                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14887                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14888                    handleServiceError();
14889                    return false;
14890                } else {
14891                    handleStartCopy();
14892                    res = true;
14893                }
14894            } catch (RemoteException e) {
14895                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14896                mHandler.sendEmptyMessage(MCS_RECONNECT);
14897                res = false;
14898            }
14899            handleReturnCode();
14900            return res;
14901        }
14902
14903        final void serviceError() {
14904            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14905            handleServiceError();
14906            handleReturnCode();
14907        }
14908
14909        abstract void handleStartCopy() throws RemoteException;
14910        abstract void handleServiceError();
14911        abstract void handleReturnCode();
14912    }
14913
14914    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14915        for (File path : paths) {
14916            try {
14917                mcs.clearDirectory(path.getAbsolutePath());
14918            } catch (RemoteException e) {
14919            }
14920        }
14921    }
14922
14923    static class OriginInfo {
14924        /**
14925         * Location where install is coming from, before it has been
14926         * copied/renamed into place. This could be a single monolithic APK
14927         * file, or a cluster directory. This location may be untrusted.
14928         */
14929        final File file;
14930        final String cid;
14931
14932        /**
14933         * Flag indicating that {@link #file} or {@link #cid} has already been
14934         * staged, meaning downstream users don't need to defensively copy the
14935         * contents.
14936         */
14937        final boolean staged;
14938
14939        /**
14940         * Flag indicating that {@link #file} or {@link #cid} is an already
14941         * installed app that is being moved.
14942         */
14943        final boolean existing;
14944
14945        final String resolvedPath;
14946        final File resolvedFile;
14947
14948        static OriginInfo fromNothing() {
14949            return new OriginInfo(null, null, false, false);
14950        }
14951
14952        static OriginInfo fromUntrustedFile(File file) {
14953            return new OriginInfo(file, null, false, false);
14954        }
14955
14956        static OriginInfo fromExistingFile(File file) {
14957            return new OriginInfo(file, null, false, true);
14958        }
14959
14960        static OriginInfo fromStagedFile(File file) {
14961            return new OriginInfo(file, null, true, false);
14962        }
14963
14964        static OriginInfo fromStagedContainer(String cid) {
14965            return new OriginInfo(null, cid, true, false);
14966        }
14967
14968        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14969            this.file = file;
14970            this.cid = cid;
14971            this.staged = staged;
14972            this.existing = existing;
14973
14974            if (cid != null) {
14975                resolvedPath = PackageHelper.getSdDir(cid);
14976                resolvedFile = new File(resolvedPath);
14977            } else if (file != null) {
14978                resolvedPath = file.getAbsolutePath();
14979                resolvedFile = file;
14980            } else {
14981                resolvedPath = null;
14982                resolvedFile = null;
14983            }
14984        }
14985    }
14986
14987    static class MoveInfo {
14988        final int moveId;
14989        final String fromUuid;
14990        final String toUuid;
14991        final String packageName;
14992        final String dataAppName;
14993        final int appId;
14994        final String seinfo;
14995        final int targetSdkVersion;
14996
14997        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14998                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14999            this.moveId = moveId;
15000            this.fromUuid = fromUuid;
15001            this.toUuid = toUuid;
15002            this.packageName = packageName;
15003            this.dataAppName = dataAppName;
15004            this.appId = appId;
15005            this.seinfo = seinfo;
15006            this.targetSdkVersion = targetSdkVersion;
15007        }
15008    }
15009
15010    static class VerificationInfo {
15011        /** A constant used to indicate that a uid value is not present. */
15012        public static final int NO_UID = -1;
15013
15014        /** URI referencing where the package was downloaded from. */
15015        final Uri originatingUri;
15016
15017        /** HTTP referrer URI associated with the originatingURI. */
15018        final Uri referrer;
15019
15020        /** UID of the application that the install request originated from. */
15021        final int originatingUid;
15022
15023        /** UID of application requesting the install */
15024        final int installerUid;
15025
15026        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15027            this.originatingUri = originatingUri;
15028            this.referrer = referrer;
15029            this.originatingUid = originatingUid;
15030            this.installerUid = installerUid;
15031        }
15032    }
15033
15034    class InstallParams extends HandlerParams {
15035        final OriginInfo origin;
15036        final MoveInfo move;
15037        final IPackageInstallObserver2 observer;
15038        int installFlags;
15039        final String installerPackageName;
15040        final String volumeUuid;
15041        private InstallArgs mArgs;
15042        private int mRet;
15043        final String packageAbiOverride;
15044        final String[] grantedRuntimePermissions;
15045        final VerificationInfo verificationInfo;
15046        final Certificate[][] certificates;
15047        final int installReason;
15048
15049        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15050                int installFlags, String installerPackageName, String volumeUuid,
15051                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15052                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15053            super(user);
15054            this.origin = origin;
15055            this.move = move;
15056            this.observer = observer;
15057            this.installFlags = installFlags;
15058            this.installerPackageName = installerPackageName;
15059            this.volumeUuid = volumeUuid;
15060            this.verificationInfo = verificationInfo;
15061            this.packageAbiOverride = packageAbiOverride;
15062            this.grantedRuntimePermissions = grantedPermissions;
15063            this.certificates = certificates;
15064            this.installReason = installReason;
15065        }
15066
15067        @Override
15068        public String toString() {
15069            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15070                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15071        }
15072
15073        private int installLocationPolicy(PackageInfoLite pkgLite) {
15074            String packageName = pkgLite.packageName;
15075            int installLocation = pkgLite.installLocation;
15076            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15077            // reader
15078            synchronized (mPackages) {
15079                // Currently installed package which the new package is attempting to replace or
15080                // null if no such package is installed.
15081                PackageParser.Package installedPkg = mPackages.get(packageName);
15082                // Package which currently owns the data which the new package will own if installed.
15083                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15084                // will be null whereas dataOwnerPkg will contain information about the package
15085                // which was uninstalled while keeping its data.
15086                PackageParser.Package dataOwnerPkg = installedPkg;
15087                if (dataOwnerPkg  == null) {
15088                    PackageSetting ps = mSettings.mPackages.get(packageName);
15089                    if (ps != null) {
15090                        dataOwnerPkg = ps.pkg;
15091                    }
15092                }
15093
15094                if (dataOwnerPkg != null) {
15095                    // If installed, the package will get access to data left on the device by its
15096                    // predecessor. As a security measure, this is permited only if this is not a
15097                    // version downgrade or if the predecessor package is marked as debuggable and
15098                    // a downgrade is explicitly requested.
15099                    //
15100                    // On debuggable platform builds, downgrades are permitted even for
15101                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15102                    // not offer security guarantees and thus it's OK to disable some security
15103                    // mechanisms to make debugging/testing easier on those builds. However, even on
15104                    // debuggable builds downgrades of packages are permitted only if requested via
15105                    // installFlags. This is because we aim to keep the behavior of debuggable
15106                    // platform builds as close as possible to the behavior of non-debuggable
15107                    // platform builds.
15108                    final boolean downgradeRequested =
15109                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15110                    final boolean packageDebuggable =
15111                                (dataOwnerPkg.applicationInfo.flags
15112                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15113                    final boolean downgradePermitted =
15114                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15115                    if (!downgradePermitted) {
15116                        try {
15117                            checkDowngrade(dataOwnerPkg, pkgLite);
15118                        } catch (PackageManagerException e) {
15119                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15120                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15121                        }
15122                    }
15123                }
15124
15125                if (installedPkg != null) {
15126                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15127                        // Check for updated system application.
15128                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15129                            if (onSd) {
15130                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15131                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15132                            }
15133                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15134                        } else {
15135                            if (onSd) {
15136                                // Install flag overrides everything.
15137                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15138                            }
15139                            // If current upgrade specifies particular preference
15140                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15141                                // Application explicitly specified internal.
15142                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15143                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15144                                // App explictly prefers external. Let policy decide
15145                            } else {
15146                                // Prefer previous location
15147                                if (isExternal(installedPkg)) {
15148                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15149                                }
15150                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15151                            }
15152                        }
15153                    } else {
15154                        // Invalid install. Return error code
15155                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15156                    }
15157                }
15158            }
15159            // All the special cases have been taken care of.
15160            // Return result based on recommended install location.
15161            if (onSd) {
15162                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15163            }
15164            return pkgLite.recommendedInstallLocation;
15165        }
15166
15167        /*
15168         * Invoke remote method to get package information and install
15169         * location values. Override install location based on default
15170         * policy if needed and then create install arguments based
15171         * on the install location.
15172         */
15173        public void handleStartCopy() throws RemoteException {
15174            int ret = PackageManager.INSTALL_SUCCEEDED;
15175
15176            // If we're already staged, we've firmly committed to an install location
15177            if (origin.staged) {
15178                if (origin.file != null) {
15179                    installFlags |= PackageManager.INSTALL_INTERNAL;
15180                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15181                } else if (origin.cid != null) {
15182                    installFlags |= PackageManager.INSTALL_EXTERNAL;
15183                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
15184                } else {
15185                    throw new IllegalStateException("Invalid stage location");
15186                }
15187            }
15188
15189            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15190            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15191            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15192            PackageInfoLite pkgLite = null;
15193
15194            if (onInt && onSd) {
15195                // Check if both bits are set.
15196                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15197                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15198            } else if (onSd && ephemeral) {
15199                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15200                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15201            } else {
15202                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15203                        packageAbiOverride);
15204
15205                if (DEBUG_EPHEMERAL && ephemeral) {
15206                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15207                }
15208
15209                /*
15210                 * If we have too little free space, try to free cache
15211                 * before giving up.
15212                 */
15213                if (!origin.staged && pkgLite.recommendedInstallLocation
15214                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15215                    // TODO: focus freeing disk space on the target device
15216                    final StorageManager storage = StorageManager.from(mContext);
15217                    final long lowThreshold = storage.getStorageLowBytes(
15218                            Environment.getDataDirectory());
15219
15220                    final long sizeBytes = mContainerService.calculateInstalledSize(
15221                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
15222
15223                    try {
15224                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
15225                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15226                                installFlags, packageAbiOverride);
15227                    } catch (InstallerException e) {
15228                        Slog.w(TAG, "Failed to free cache", e);
15229                    }
15230
15231                    /*
15232                     * The cache free must have deleted the file we
15233                     * downloaded to install.
15234                     *
15235                     * TODO: fix the "freeCache" call to not delete
15236                     *       the file we care about.
15237                     */
15238                    if (pkgLite.recommendedInstallLocation
15239                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15240                        pkgLite.recommendedInstallLocation
15241                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15242                    }
15243                }
15244            }
15245
15246            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15247                int loc = pkgLite.recommendedInstallLocation;
15248                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15249                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15250                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15251                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15252                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15253                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15254                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15255                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15256                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15257                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15258                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15259                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15260                } else {
15261                    // Override with defaults if needed.
15262                    loc = installLocationPolicy(pkgLite);
15263                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15264                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15265                    } else if (!onSd && !onInt) {
15266                        // Override install location with flags
15267                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15268                            // Set the flag to install on external media.
15269                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15270                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15271                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15272                            if (DEBUG_EPHEMERAL) {
15273                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15274                            }
15275                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15276                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15277                                    |PackageManager.INSTALL_INTERNAL);
15278                        } else {
15279                            // Make sure the flag for installing on external
15280                            // media is unset
15281                            installFlags |= PackageManager.INSTALL_INTERNAL;
15282                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15283                        }
15284                    }
15285                }
15286            }
15287
15288            final InstallArgs args = createInstallArgs(this);
15289            mArgs = args;
15290
15291            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15292                // TODO: http://b/22976637
15293                // Apps installed for "all" users use the device owner to verify the app
15294                UserHandle verifierUser = getUser();
15295                if (verifierUser == UserHandle.ALL) {
15296                    verifierUser = UserHandle.SYSTEM;
15297                }
15298
15299                /*
15300                 * Determine if we have any installed package verifiers. If we
15301                 * do, then we'll defer to them to verify the packages.
15302                 */
15303                final int requiredUid = mRequiredVerifierPackage == null ? -1
15304                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15305                                verifierUser.getIdentifier());
15306                if (!origin.existing && requiredUid != -1
15307                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
15308                    final Intent verification = new Intent(
15309                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15310                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15311                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15312                            PACKAGE_MIME_TYPE);
15313                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15314
15315                    // Query all live verifiers based on current user state
15316                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15317                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
15318
15319                    if (DEBUG_VERIFY) {
15320                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15321                                + verification.toString() + " with " + pkgLite.verifiers.length
15322                                + " optional verifiers");
15323                    }
15324
15325                    final int verificationId = mPendingVerificationToken++;
15326
15327                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15328
15329                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15330                            installerPackageName);
15331
15332                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15333                            installFlags);
15334
15335                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15336                            pkgLite.packageName);
15337
15338                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15339                            pkgLite.versionCode);
15340
15341                    if (verificationInfo != null) {
15342                        if (verificationInfo.originatingUri != null) {
15343                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15344                                    verificationInfo.originatingUri);
15345                        }
15346                        if (verificationInfo.referrer != null) {
15347                            verification.putExtra(Intent.EXTRA_REFERRER,
15348                                    verificationInfo.referrer);
15349                        }
15350                        if (verificationInfo.originatingUid >= 0) {
15351                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15352                                    verificationInfo.originatingUid);
15353                        }
15354                        if (verificationInfo.installerUid >= 0) {
15355                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15356                                    verificationInfo.installerUid);
15357                        }
15358                    }
15359
15360                    final PackageVerificationState verificationState = new PackageVerificationState(
15361                            requiredUid, args);
15362
15363                    mPendingVerification.append(verificationId, verificationState);
15364
15365                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15366                            receivers, verificationState);
15367
15368                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15369                    final long idleDuration = getVerificationTimeout();
15370
15371                    /*
15372                     * If any sufficient verifiers were listed in the package
15373                     * manifest, attempt to ask them.
15374                     */
15375                    if (sufficientVerifiers != null) {
15376                        final int N = sufficientVerifiers.size();
15377                        if (N == 0) {
15378                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15379                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15380                        } else {
15381                            for (int i = 0; i < N; i++) {
15382                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15383                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15384                                        verifierComponent.getPackageName(), idleDuration,
15385                                        verifierUser.getIdentifier(), false, "package verifier");
15386
15387                                final Intent sufficientIntent = new Intent(verification);
15388                                sufficientIntent.setComponent(verifierComponent);
15389                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15390                            }
15391                        }
15392                    }
15393
15394                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15395                            mRequiredVerifierPackage, receivers);
15396                    if (ret == PackageManager.INSTALL_SUCCEEDED
15397                            && mRequiredVerifierPackage != null) {
15398                        Trace.asyncTraceBegin(
15399                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15400                        /*
15401                         * Send the intent to the required verification agent,
15402                         * but only start the verification timeout after the
15403                         * target BroadcastReceivers have run.
15404                         */
15405                        verification.setComponent(requiredVerifierComponent);
15406                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15407                                mRequiredVerifierPackage, idleDuration,
15408                                verifierUser.getIdentifier(), false, "package verifier");
15409                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15410                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15411                                new BroadcastReceiver() {
15412                                    @Override
15413                                    public void onReceive(Context context, Intent intent) {
15414                                        final Message msg = mHandler
15415                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15416                                        msg.arg1 = verificationId;
15417                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15418                                    }
15419                                }, null, 0, null, null);
15420
15421                        /*
15422                         * We don't want the copy to proceed until verification
15423                         * succeeds, so null out this field.
15424                         */
15425                        mArgs = null;
15426                    }
15427                } else {
15428                    /*
15429                     * No package verification is enabled, so immediately start
15430                     * the remote call to initiate copy using temporary file.
15431                     */
15432                    ret = args.copyApk(mContainerService, true);
15433                }
15434            }
15435
15436            mRet = ret;
15437        }
15438
15439        @Override
15440        void handleReturnCode() {
15441            // If mArgs is null, then MCS couldn't be reached. When it
15442            // reconnects, it will try again to install. At that point, this
15443            // will succeed.
15444            if (mArgs != null) {
15445                processPendingInstall(mArgs, mRet);
15446            }
15447        }
15448
15449        @Override
15450        void handleServiceError() {
15451            mArgs = createInstallArgs(this);
15452            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15453        }
15454
15455        public boolean isForwardLocked() {
15456            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15457        }
15458    }
15459
15460    /**
15461     * Used during creation of InstallArgs
15462     *
15463     * @param installFlags package installation flags
15464     * @return true if should be installed on external storage
15465     */
15466    private static boolean installOnExternalAsec(int installFlags) {
15467        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
15468            return false;
15469        }
15470        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15471            return true;
15472        }
15473        return false;
15474    }
15475
15476    /**
15477     * Used during creation of InstallArgs
15478     *
15479     * @param installFlags package installation flags
15480     * @return true if should be installed as forward locked
15481     */
15482    private static boolean installForwardLocked(int installFlags) {
15483        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15484    }
15485
15486    private InstallArgs createInstallArgs(InstallParams params) {
15487        if (params.move != null) {
15488            return new MoveInstallArgs(params);
15489        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15490            return new AsecInstallArgs(params);
15491        } else {
15492            return new FileInstallArgs(params);
15493        }
15494    }
15495
15496    /**
15497     * Create args that describe an existing installed package. Typically used
15498     * when cleaning up old installs, or used as a move source.
15499     */
15500    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15501            String resourcePath, String[] instructionSets) {
15502        final boolean isInAsec;
15503        if (installOnExternalAsec(installFlags)) {
15504            /* Apps on SD card are always in ASEC containers. */
15505            isInAsec = true;
15506        } else if (installForwardLocked(installFlags)
15507                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15508            /*
15509             * Forward-locked apps are only in ASEC containers if they're the
15510             * new style
15511             */
15512            isInAsec = true;
15513        } else {
15514            isInAsec = false;
15515        }
15516
15517        if (isInAsec) {
15518            return new AsecInstallArgs(codePath, instructionSets,
15519                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15520        } else {
15521            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15522        }
15523    }
15524
15525    static abstract class InstallArgs {
15526        /** @see InstallParams#origin */
15527        final OriginInfo origin;
15528        /** @see InstallParams#move */
15529        final MoveInfo move;
15530
15531        final IPackageInstallObserver2 observer;
15532        // Always refers to PackageManager flags only
15533        final int installFlags;
15534        final String installerPackageName;
15535        final String volumeUuid;
15536        final UserHandle user;
15537        final String abiOverride;
15538        final String[] installGrantPermissions;
15539        /** If non-null, drop an async trace when the install completes */
15540        final String traceMethod;
15541        final int traceCookie;
15542        final Certificate[][] certificates;
15543        final int installReason;
15544
15545        // The list of instruction sets supported by this app. This is currently
15546        // only used during the rmdex() phase to clean up resources. We can get rid of this
15547        // if we move dex files under the common app path.
15548        /* nullable */ String[] instructionSets;
15549
15550        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15551                int installFlags, String installerPackageName, String volumeUuid,
15552                UserHandle user, String[] instructionSets,
15553                String abiOverride, String[] installGrantPermissions,
15554                String traceMethod, int traceCookie, Certificate[][] certificates,
15555                int installReason) {
15556            this.origin = origin;
15557            this.move = move;
15558            this.installFlags = installFlags;
15559            this.observer = observer;
15560            this.installerPackageName = installerPackageName;
15561            this.volumeUuid = volumeUuid;
15562            this.user = user;
15563            this.instructionSets = instructionSets;
15564            this.abiOverride = abiOverride;
15565            this.installGrantPermissions = installGrantPermissions;
15566            this.traceMethod = traceMethod;
15567            this.traceCookie = traceCookie;
15568            this.certificates = certificates;
15569            this.installReason = installReason;
15570        }
15571
15572        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15573        abstract int doPreInstall(int status);
15574
15575        /**
15576         * Rename package into final resting place. All paths on the given
15577         * scanned package should be updated to reflect the rename.
15578         */
15579        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15580        abstract int doPostInstall(int status, int uid);
15581
15582        /** @see PackageSettingBase#codePathString */
15583        abstract String getCodePath();
15584        /** @see PackageSettingBase#resourcePathString */
15585        abstract String getResourcePath();
15586
15587        // Need installer lock especially for dex file removal.
15588        abstract void cleanUpResourcesLI();
15589        abstract boolean doPostDeleteLI(boolean delete);
15590
15591        /**
15592         * Called before the source arguments are copied. This is used mostly
15593         * for MoveParams when it needs to read the source file to put it in the
15594         * destination.
15595         */
15596        int doPreCopy() {
15597            return PackageManager.INSTALL_SUCCEEDED;
15598        }
15599
15600        /**
15601         * Called after the source arguments are copied. This is used mostly for
15602         * MoveParams when it needs to read the source file to put it in the
15603         * destination.
15604         */
15605        int doPostCopy(int uid) {
15606            return PackageManager.INSTALL_SUCCEEDED;
15607        }
15608
15609        protected boolean isFwdLocked() {
15610            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15611        }
15612
15613        protected boolean isExternalAsec() {
15614            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15615        }
15616
15617        protected boolean isEphemeral() {
15618            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15619        }
15620
15621        UserHandle getUser() {
15622            return user;
15623        }
15624    }
15625
15626    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15627        if (!allCodePaths.isEmpty()) {
15628            if (instructionSets == null) {
15629                throw new IllegalStateException("instructionSet == null");
15630            }
15631            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15632            for (String codePath : allCodePaths) {
15633                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15634                    try {
15635                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15636                    } catch (InstallerException ignored) {
15637                    }
15638                }
15639            }
15640        }
15641    }
15642
15643    /**
15644     * Logic to handle installation of non-ASEC applications, including copying
15645     * and renaming logic.
15646     */
15647    class FileInstallArgs extends InstallArgs {
15648        private File codeFile;
15649        private File resourceFile;
15650
15651        // Example topology:
15652        // /data/app/com.example/base.apk
15653        // /data/app/com.example/split_foo.apk
15654        // /data/app/com.example/lib/arm/libfoo.so
15655        // /data/app/com.example/lib/arm64/libfoo.so
15656        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15657
15658        /** New install */
15659        FileInstallArgs(InstallParams params) {
15660            super(params.origin, params.move, params.observer, params.installFlags,
15661                    params.installerPackageName, params.volumeUuid,
15662                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15663                    params.grantedRuntimePermissions,
15664                    params.traceMethod, params.traceCookie, params.certificates,
15665                    params.installReason);
15666            if (isFwdLocked()) {
15667                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15668            }
15669        }
15670
15671        /** Existing install */
15672        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15673            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15674                    null, null, null, 0, null /*certificates*/,
15675                    PackageManager.INSTALL_REASON_UNKNOWN);
15676            this.codeFile = (codePath != null) ? new File(codePath) : null;
15677            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15678        }
15679
15680        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15681            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15682            try {
15683                return doCopyApk(imcs, temp);
15684            } finally {
15685                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15686            }
15687        }
15688
15689        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15690            if (origin.staged) {
15691                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15692                codeFile = origin.file;
15693                resourceFile = origin.file;
15694                return PackageManager.INSTALL_SUCCEEDED;
15695            }
15696
15697            try {
15698                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15699                final File tempDir =
15700                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15701                codeFile = tempDir;
15702                resourceFile = tempDir;
15703            } catch (IOException e) {
15704                Slog.w(TAG, "Failed to create copy file: " + e);
15705                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15706            }
15707
15708            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15709                @Override
15710                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15711                    if (!FileUtils.isValidExtFilename(name)) {
15712                        throw new IllegalArgumentException("Invalid filename: " + name);
15713                    }
15714                    try {
15715                        final File file = new File(codeFile, name);
15716                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15717                                O_RDWR | O_CREAT, 0644);
15718                        Os.chmod(file.getAbsolutePath(), 0644);
15719                        return new ParcelFileDescriptor(fd);
15720                    } catch (ErrnoException e) {
15721                        throw new RemoteException("Failed to open: " + e.getMessage());
15722                    }
15723                }
15724            };
15725
15726            int ret = PackageManager.INSTALL_SUCCEEDED;
15727            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15728            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15729                Slog.e(TAG, "Failed to copy package");
15730                return ret;
15731            }
15732
15733            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15734            NativeLibraryHelper.Handle handle = null;
15735            try {
15736                handle = NativeLibraryHelper.Handle.create(codeFile);
15737                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15738                        abiOverride);
15739            } catch (IOException e) {
15740                Slog.e(TAG, "Copying native libraries failed", e);
15741                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15742            } finally {
15743                IoUtils.closeQuietly(handle);
15744            }
15745
15746            return ret;
15747        }
15748
15749        int doPreInstall(int status) {
15750            if (status != PackageManager.INSTALL_SUCCEEDED) {
15751                cleanUp();
15752            }
15753            return status;
15754        }
15755
15756        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15757            if (status != PackageManager.INSTALL_SUCCEEDED) {
15758                cleanUp();
15759                return false;
15760            }
15761
15762            final File targetDir = codeFile.getParentFile();
15763            final File beforeCodeFile = codeFile;
15764            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15765
15766            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15767            try {
15768                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15769            } catch (ErrnoException e) {
15770                Slog.w(TAG, "Failed to rename", e);
15771                return false;
15772            }
15773
15774            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15775                Slog.w(TAG, "Failed to restorecon");
15776                return false;
15777            }
15778
15779            // Reflect the rename internally
15780            codeFile = afterCodeFile;
15781            resourceFile = afterCodeFile;
15782
15783            // Reflect the rename in scanned details
15784            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15785            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15786                    afterCodeFile, pkg.baseCodePath));
15787            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15788                    afterCodeFile, pkg.splitCodePaths));
15789
15790            // Reflect the rename in app info
15791            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15792            pkg.setApplicationInfoCodePath(pkg.codePath);
15793            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15794            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15795            pkg.setApplicationInfoResourcePath(pkg.codePath);
15796            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15797            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15798
15799            return true;
15800        }
15801
15802        int doPostInstall(int status, int uid) {
15803            if (status != PackageManager.INSTALL_SUCCEEDED) {
15804                cleanUp();
15805            }
15806            return status;
15807        }
15808
15809        @Override
15810        String getCodePath() {
15811            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15812        }
15813
15814        @Override
15815        String getResourcePath() {
15816            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15817        }
15818
15819        private boolean cleanUp() {
15820            if (codeFile == null || !codeFile.exists()) {
15821                return false;
15822            }
15823
15824            removeCodePathLI(codeFile);
15825
15826            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15827                resourceFile.delete();
15828            }
15829
15830            return true;
15831        }
15832
15833        void cleanUpResourcesLI() {
15834            // Try enumerating all code paths before deleting
15835            List<String> allCodePaths = Collections.EMPTY_LIST;
15836            if (codeFile != null && codeFile.exists()) {
15837                try {
15838                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15839                    allCodePaths = pkg.getAllCodePaths();
15840                } catch (PackageParserException e) {
15841                    // Ignored; we tried our best
15842                }
15843            }
15844
15845            cleanUp();
15846            removeDexFiles(allCodePaths, instructionSets);
15847        }
15848
15849        boolean doPostDeleteLI(boolean delete) {
15850            // XXX err, shouldn't we respect the delete flag?
15851            cleanUpResourcesLI();
15852            return true;
15853        }
15854    }
15855
15856    private boolean isAsecExternal(String cid) {
15857        final String asecPath = PackageHelper.getSdFilesystem(cid);
15858        return !asecPath.startsWith(mAsecInternalPath);
15859    }
15860
15861    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15862            PackageManagerException {
15863        if (copyRet < 0) {
15864            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15865                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15866                throw new PackageManagerException(copyRet, message);
15867            }
15868        }
15869    }
15870
15871    /**
15872     * Extract the StorageManagerService "container ID" from the full code path of an
15873     * .apk.
15874     */
15875    static String cidFromCodePath(String fullCodePath) {
15876        int eidx = fullCodePath.lastIndexOf("/");
15877        String subStr1 = fullCodePath.substring(0, eidx);
15878        int sidx = subStr1.lastIndexOf("/");
15879        return subStr1.substring(sidx+1, eidx);
15880    }
15881
15882    /**
15883     * Logic to handle installation of ASEC applications, including copying and
15884     * renaming logic.
15885     */
15886    class AsecInstallArgs extends InstallArgs {
15887        static final String RES_FILE_NAME = "pkg.apk";
15888        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15889
15890        String cid;
15891        String packagePath;
15892        String resourcePath;
15893
15894        /** New install */
15895        AsecInstallArgs(InstallParams params) {
15896            super(params.origin, params.move, params.observer, params.installFlags,
15897                    params.installerPackageName, params.volumeUuid,
15898                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15899                    params.grantedRuntimePermissions,
15900                    params.traceMethod, params.traceCookie, params.certificates,
15901                    params.installReason);
15902        }
15903
15904        /** Existing install */
15905        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15906                        boolean isExternal, boolean isForwardLocked) {
15907            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15908                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15909                    instructionSets, null, null, null, 0, null /*certificates*/,
15910                    PackageManager.INSTALL_REASON_UNKNOWN);
15911            // Hackily pretend we're still looking at a full code path
15912            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15913                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15914            }
15915
15916            // Extract cid from fullCodePath
15917            int eidx = fullCodePath.lastIndexOf("/");
15918            String subStr1 = fullCodePath.substring(0, eidx);
15919            int sidx = subStr1.lastIndexOf("/");
15920            cid = subStr1.substring(sidx+1, eidx);
15921            setMountPath(subStr1);
15922        }
15923
15924        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15925            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15926                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15927                    instructionSets, null, null, null, 0, null /*certificates*/,
15928                    PackageManager.INSTALL_REASON_UNKNOWN);
15929            this.cid = cid;
15930            setMountPath(PackageHelper.getSdDir(cid));
15931        }
15932
15933        void createCopyFile() {
15934            cid = mInstallerService.allocateExternalStageCidLegacy();
15935        }
15936
15937        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15938            if (origin.staged && origin.cid != null) {
15939                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15940                cid = origin.cid;
15941                setMountPath(PackageHelper.getSdDir(cid));
15942                return PackageManager.INSTALL_SUCCEEDED;
15943            }
15944
15945            if (temp) {
15946                createCopyFile();
15947            } else {
15948                /*
15949                 * Pre-emptively destroy the container since it's destroyed if
15950                 * copying fails due to it existing anyway.
15951                 */
15952                PackageHelper.destroySdDir(cid);
15953            }
15954
15955            final String newMountPath = imcs.copyPackageToContainer(
15956                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15957                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15958
15959            if (newMountPath != null) {
15960                setMountPath(newMountPath);
15961                return PackageManager.INSTALL_SUCCEEDED;
15962            } else {
15963                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15964            }
15965        }
15966
15967        @Override
15968        String getCodePath() {
15969            return packagePath;
15970        }
15971
15972        @Override
15973        String getResourcePath() {
15974            return resourcePath;
15975        }
15976
15977        int doPreInstall(int status) {
15978            if (status != PackageManager.INSTALL_SUCCEEDED) {
15979                // Destroy container
15980                PackageHelper.destroySdDir(cid);
15981            } else {
15982                boolean mounted = PackageHelper.isContainerMounted(cid);
15983                if (!mounted) {
15984                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15985                            Process.SYSTEM_UID);
15986                    if (newMountPath != null) {
15987                        setMountPath(newMountPath);
15988                    } else {
15989                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15990                    }
15991                }
15992            }
15993            return status;
15994        }
15995
15996        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15997            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15998            String newMountPath = null;
15999            if (PackageHelper.isContainerMounted(cid)) {
16000                // Unmount the container
16001                if (!PackageHelper.unMountSdDir(cid)) {
16002                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
16003                    return false;
16004                }
16005            }
16006            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16007                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
16008                        " which might be stale. Will try to clean up.");
16009                // Clean up the stale container and proceed to recreate.
16010                if (!PackageHelper.destroySdDir(newCacheId)) {
16011                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
16012                    return false;
16013                }
16014                // Successfully cleaned up stale container. Try to rename again.
16015                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16016                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
16017                            + " inspite of cleaning it up.");
16018                    return false;
16019                }
16020            }
16021            if (!PackageHelper.isContainerMounted(newCacheId)) {
16022                Slog.w(TAG, "Mounting container " + newCacheId);
16023                newMountPath = PackageHelper.mountSdDir(newCacheId,
16024                        getEncryptKey(), Process.SYSTEM_UID);
16025            } else {
16026                newMountPath = PackageHelper.getSdDir(newCacheId);
16027            }
16028            if (newMountPath == null) {
16029                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
16030                return false;
16031            }
16032            Log.i(TAG, "Succesfully renamed " + cid +
16033                    " to " + newCacheId +
16034                    " at new path: " + newMountPath);
16035            cid = newCacheId;
16036
16037            final File beforeCodeFile = new File(packagePath);
16038            setMountPath(newMountPath);
16039            final File afterCodeFile = new File(packagePath);
16040
16041            // Reflect the rename in scanned details
16042            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16043            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16044                    afterCodeFile, pkg.baseCodePath));
16045            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16046                    afterCodeFile, pkg.splitCodePaths));
16047
16048            // Reflect the rename in app info
16049            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16050            pkg.setApplicationInfoCodePath(pkg.codePath);
16051            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16052            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16053            pkg.setApplicationInfoResourcePath(pkg.codePath);
16054            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16055            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16056
16057            return true;
16058        }
16059
16060        private void setMountPath(String mountPath) {
16061            final File mountFile = new File(mountPath);
16062
16063            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16064            if (monolithicFile.exists()) {
16065                packagePath = monolithicFile.getAbsolutePath();
16066                if (isFwdLocked()) {
16067                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16068                } else {
16069                    resourcePath = packagePath;
16070                }
16071            } else {
16072                packagePath = mountFile.getAbsolutePath();
16073                resourcePath = packagePath;
16074            }
16075        }
16076
16077        int doPostInstall(int status, int uid) {
16078            if (status != PackageManager.INSTALL_SUCCEEDED) {
16079                cleanUp();
16080            } else {
16081                final int groupOwner;
16082                final String protectedFile;
16083                if (isFwdLocked()) {
16084                    groupOwner = UserHandle.getSharedAppGid(uid);
16085                    protectedFile = RES_FILE_NAME;
16086                } else {
16087                    groupOwner = -1;
16088                    protectedFile = null;
16089                }
16090
16091                if (uid < Process.FIRST_APPLICATION_UID
16092                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16093                    Slog.e(TAG, "Failed to finalize " + cid);
16094                    PackageHelper.destroySdDir(cid);
16095                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16096                }
16097
16098                boolean mounted = PackageHelper.isContainerMounted(cid);
16099                if (!mounted) {
16100                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16101                }
16102            }
16103            return status;
16104        }
16105
16106        private void cleanUp() {
16107            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16108
16109            // Destroy secure container
16110            PackageHelper.destroySdDir(cid);
16111        }
16112
16113        private List<String> getAllCodePaths() {
16114            final File codeFile = new File(getCodePath());
16115            if (codeFile != null && codeFile.exists()) {
16116                try {
16117                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16118                    return pkg.getAllCodePaths();
16119                } catch (PackageParserException e) {
16120                    // Ignored; we tried our best
16121                }
16122            }
16123            return Collections.EMPTY_LIST;
16124        }
16125
16126        void cleanUpResourcesLI() {
16127            // Enumerate all code paths before deleting
16128            cleanUpResourcesLI(getAllCodePaths());
16129        }
16130
16131        private void cleanUpResourcesLI(List<String> allCodePaths) {
16132            cleanUp();
16133            removeDexFiles(allCodePaths, instructionSets);
16134        }
16135
16136        String getPackageName() {
16137            return getAsecPackageName(cid);
16138        }
16139
16140        boolean doPostDeleteLI(boolean delete) {
16141            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
16142            final List<String> allCodePaths = getAllCodePaths();
16143            boolean mounted = PackageHelper.isContainerMounted(cid);
16144            if (mounted) {
16145                // Unmount first
16146                if (PackageHelper.unMountSdDir(cid)) {
16147                    mounted = false;
16148                }
16149            }
16150            if (!mounted && delete) {
16151                cleanUpResourcesLI(allCodePaths);
16152            }
16153            return !mounted;
16154        }
16155
16156        @Override
16157        int doPreCopy() {
16158            if (isFwdLocked()) {
16159                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
16160                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
16161                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16162                }
16163            }
16164
16165            return PackageManager.INSTALL_SUCCEEDED;
16166        }
16167
16168        @Override
16169        int doPostCopy(int uid) {
16170            if (isFwdLocked()) {
16171                if (uid < Process.FIRST_APPLICATION_UID
16172                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
16173                                RES_FILE_NAME)) {
16174                    Slog.e(TAG, "Failed to finalize " + cid);
16175                    PackageHelper.destroySdDir(cid);
16176                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16177                }
16178            }
16179
16180            return PackageManager.INSTALL_SUCCEEDED;
16181        }
16182    }
16183
16184    /**
16185     * Logic to handle movement of existing installed applications.
16186     */
16187    class MoveInstallArgs extends InstallArgs {
16188        private File codeFile;
16189        private File resourceFile;
16190
16191        /** New install */
16192        MoveInstallArgs(InstallParams params) {
16193            super(params.origin, params.move, params.observer, params.installFlags,
16194                    params.installerPackageName, params.volumeUuid,
16195                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16196                    params.grantedRuntimePermissions,
16197                    params.traceMethod, params.traceCookie, params.certificates,
16198                    params.installReason);
16199        }
16200
16201        int copyApk(IMediaContainerService imcs, boolean temp) {
16202            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16203                    + move.fromUuid + " to " + move.toUuid);
16204            synchronized (mInstaller) {
16205                try {
16206                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16207                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16208                } catch (InstallerException e) {
16209                    Slog.w(TAG, "Failed to move app", e);
16210                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16211                }
16212            }
16213
16214            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16215            resourceFile = codeFile;
16216            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16217
16218            return PackageManager.INSTALL_SUCCEEDED;
16219        }
16220
16221        int doPreInstall(int status) {
16222            if (status != PackageManager.INSTALL_SUCCEEDED) {
16223                cleanUp(move.toUuid);
16224            }
16225            return status;
16226        }
16227
16228        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16229            if (status != PackageManager.INSTALL_SUCCEEDED) {
16230                cleanUp(move.toUuid);
16231                return false;
16232            }
16233
16234            // Reflect the move in app info
16235            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16236            pkg.setApplicationInfoCodePath(pkg.codePath);
16237            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16238            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16239            pkg.setApplicationInfoResourcePath(pkg.codePath);
16240            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16241            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16242
16243            return true;
16244        }
16245
16246        int doPostInstall(int status, int uid) {
16247            if (status == PackageManager.INSTALL_SUCCEEDED) {
16248                cleanUp(move.fromUuid);
16249            } else {
16250                cleanUp(move.toUuid);
16251            }
16252            return status;
16253        }
16254
16255        @Override
16256        String getCodePath() {
16257            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16258        }
16259
16260        @Override
16261        String getResourcePath() {
16262            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16263        }
16264
16265        private boolean cleanUp(String volumeUuid) {
16266            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16267                    move.dataAppName);
16268            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16269            final int[] userIds = sUserManager.getUserIds();
16270            synchronized (mInstallLock) {
16271                // Clean up both app data and code
16272                // All package moves are frozen until finished
16273                for (int userId : userIds) {
16274                    try {
16275                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16276                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16277                    } catch (InstallerException e) {
16278                        Slog.w(TAG, String.valueOf(e));
16279                    }
16280                }
16281                removeCodePathLI(codeFile);
16282            }
16283            return true;
16284        }
16285
16286        void cleanUpResourcesLI() {
16287            throw new UnsupportedOperationException();
16288        }
16289
16290        boolean doPostDeleteLI(boolean delete) {
16291            throw new UnsupportedOperationException();
16292        }
16293    }
16294
16295    static String getAsecPackageName(String packageCid) {
16296        int idx = packageCid.lastIndexOf("-");
16297        if (idx == -1) {
16298            return packageCid;
16299        }
16300        return packageCid.substring(0, idx);
16301    }
16302
16303    // Utility method used to create code paths based on package name and available index.
16304    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16305        String idxStr = "";
16306        int idx = 1;
16307        // Fall back to default value of idx=1 if prefix is not
16308        // part of oldCodePath
16309        if (oldCodePath != null) {
16310            String subStr = oldCodePath;
16311            // Drop the suffix right away
16312            if (suffix != null && subStr.endsWith(suffix)) {
16313                subStr = subStr.substring(0, subStr.length() - suffix.length());
16314            }
16315            // If oldCodePath already contains prefix find out the
16316            // ending index to either increment or decrement.
16317            int sidx = subStr.lastIndexOf(prefix);
16318            if (sidx != -1) {
16319                subStr = subStr.substring(sidx + prefix.length());
16320                if (subStr != null) {
16321                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16322                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16323                    }
16324                    try {
16325                        idx = Integer.parseInt(subStr);
16326                        if (idx <= 1) {
16327                            idx++;
16328                        } else {
16329                            idx--;
16330                        }
16331                    } catch(NumberFormatException e) {
16332                    }
16333                }
16334            }
16335        }
16336        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16337        return prefix + idxStr;
16338    }
16339
16340    private File getNextCodePath(File targetDir, String packageName) {
16341        File result;
16342        SecureRandom random = new SecureRandom();
16343        byte[] bytes = new byte[16];
16344        do {
16345            random.nextBytes(bytes);
16346            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16347            result = new File(targetDir, packageName + "-" + suffix);
16348        } while (result.exists());
16349        return result;
16350    }
16351
16352    // Utility method that returns the relative package path with respect
16353    // to the installation directory. Like say for /data/data/com.test-1.apk
16354    // string com.test-1 is returned.
16355    static String deriveCodePathName(String codePath) {
16356        if (codePath == null) {
16357            return null;
16358        }
16359        final File codeFile = new File(codePath);
16360        final String name = codeFile.getName();
16361        if (codeFile.isDirectory()) {
16362            return name;
16363        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16364            final int lastDot = name.lastIndexOf('.');
16365            return name.substring(0, lastDot);
16366        } else {
16367            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16368            return null;
16369        }
16370    }
16371
16372    static class PackageInstalledInfo {
16373        String name;
16374        int uid;
16375        // The set of users that originally had this package installed.
16376        int[] origUsers;
16377        // The set of users that now have this package installed.
16378        int[] newUsers;
16379        PackageParser.Package pkg;
16380        int returnCode;
16381        String returnMsg;
16382        PackageRemovedInfo removedInfo;
16383        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16384
16385        public void setError(int code, String msg) {
16386            setReturnCode(code);
16387            setReturnMessage(msg);
16388            Slog.w(TAG, msg);
16389        }
16390
16391        public void setError(String msg, PackageParserException e) {
16392            setReturnCode(e.error);
16393            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16394            Slog.w(TAG, msg, e);
16395        }
16396
16397        public void setError(String msg, PackageManagerException e) {
16398            returnCode = e.error;
16399            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16400            Slog.w(TAG, msg, e);
16401        }
16402
16403        public void setReturnCode(int returnCode) {
16404            this.returnCode = returnCode;
16405            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16406            for (int i = 0; i < childCount; i++) {
16407                addedChildPackages.valueAt(i).returnCode = returnCode;
16408            }
16409        }
16410
16411        private void setReturnMessage(String returnMsg) {
16412            this.returnMsg = returnMsg;
16413            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16414            for (int i = 0; i < childCount; i++) {
16415                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16416            }
16417        }
16418
16419        // In some error cases we want to convey more info back to the observer
16420        String origPackage;
16421        String origPermission;
16422    }
16423
16424    /*
16425     * Install a non-existing package.
16426     */
16427    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16428            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16429            PackageInstalledInfo res, int installReason) {
16430        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16431
16432        // Remember this for later, in case we need to rollback this install
16433        String pkgName = pkg.packageName;
16434
16435        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16436
16437        synchronized(mPackages) {
16438            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16439            if (renamedPackage != null) {
16440                // A package with the same name is already installed, though
16441                // it has been renamed to an older name.  The package we
16442                // are trying to install should be installed as an update to
16443                // the existing one, but that has not been requested, so bail.
16444                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16445                        + " without first uninstalling package running as "
16446                        + renamedPackage);
16447                return;
16448            }
16449            if (mPackages.containsKey(pkgName)) {
16450                // Don't allow installation over an existing package with the same name.
16451                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16452                        + " without first uninstalling.");
16453                return;
16454            }
16455        }
16456
16457        try {
16458            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
16459                    System.currentTimeMillis(), user);
16460
16461            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16462
16463            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16464                prepareAppDataAfterInstallLIF(newPackage);
16465
16466            } else {
16467                // Remove package from internal structures, but keep around any
16468                // data that might have already existed
16469                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16470                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16471            }
16472        } catch (PackageManagerException e) {
16473            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16474        }
16475
16476        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16477    }
16478
16479    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16480        // Can't rotate keys during boot or if sharedUser.
16481        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16482                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16483            return false;
16484        }
16485        // app is using upgradeKeySets; make sure all are valid
16486        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16487        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16488        for (int i = 0; i < upgradeKeySets.length; i++) {
16489            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16490                Slog.wtf(TAG, "Package "
16491                         + (oldPs.name != null ? oldPs.name : "<null>")
16492                         + " contains upgrade-key-set reference to unknown key-set: "
16493                         + upgradeKeySets[i]
16494                         + " reverting to signatures check.");
16495                return false;
16496            }
16497        }
16498        return true;
16499    }
16500
16501    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16502        // Upgrade keysets are being used.  Determine if new package has a superset of the
16503        // required keys.
16504        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16505        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16506        for (int i = 0; i < upgradeKeySets.length; i++) {
16507            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16508            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16509                return true;
16510            }
16511        }
16512        return false;
16513    }
16514
16515    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16516        try (DigestInputStream digestStream =
16517                new DigestInputStream(new FileInputStream(file), digest)) {
16518            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16519        }
16520    }
16521
16522    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16523            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16524            int installReason) {
16525        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16526
16527        final PackageParser.Package oldPackage;
16528        final PackageSetting ps;
16529        final String pkgName = pkg.packageName;
16530        final int[] allUsers;
16531        final int[] installedUsers;
16532
16533        synchronized(mPackages) {
16534            oldPackage = mPackages.get(pkgName);
16535            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16536
16537            // don't allow upgrade to target a release SDK from a pre-release SDK
16538            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16539                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16540            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16541                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16542            if (oldTargetsPreRelease
16543                    && !newTargetsPreRelease
16544                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16545                Slog.w(TAG, "Can't install package targeting released sdk");
16546                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16547                return;
16548            }
16549
16550            ps = mSettings.mPackages.get(pkgName);
16551
16552            // verify signatures are valid
16553            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16554                if (!checkUpgradeKeySetLP(ps, pkg)) {
16555                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16556                            "New package not signed by keys specified by upgrade-keysets: "
16557                                    + pkgName);
16558                    return;
16559                }
16560            } else {
16561                // default to original signature matching
16562                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16563                        != PackageManager.SIGNATURE_MATCH) {
16564                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16565                            "New package has a different signature: " + pkgName);
16566                    return;
16567                }
16568            }
16569
16570            // don't allow a system upgrade unless the upgrade hash matches
16571            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16572                byte[] digestBytes = null;
16573                try {
16574                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16575                    updateDigest(digest, new File(pkg.baseCodePath));
16576                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16577                        for (String path : pkg.splitCodePaths) {
16578                            updateDigest(digest, new File(path));
16579                        }
16580                    }
16581                    digestBytes = digest.digest();
16582                } catch (NoSuchAlgorithmException | IOException e) {
16583                    res.setError(INSTALL_FAILED_INVALID_APK,
16584                            "Could not compute hash: " + pkgName);
16585                    return;
16586                }
16587                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16588                    res.setError(INSTALL_FAILED_INVALID_APK,
16589                            "New package fails restrict-update check: " + pkgName);
16590                    return;
16591                }
16592                // retain upgrade restriction
16593                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16594            }
16595
16596            // Check for shared user id changes
16597            String invalidPackageName =
16598                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16599            if (invalidPackageName != null) {
16600                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16601                        "Package " + invalidPackageName + " tried to change user "
16602                                + oldPackage.mSharedUserId);
16603                return;
16604            }
16605
16606            // In case of rollback, remember per-user/profile install state
16607            allUsers = sUserManager.getUserIds();
16608            installedUsers = ps.queryInstalledUsers(allUsers, true);
16609
16610            // don't allow an upgrade from full to ephemeral
16611            if (isInstantApp) {
16612                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16613                    for (int currentUser : allUsers) {
16614                        if (!ps.getInstantApp(currentUser)) {
16615                            // can't downgrade from full to instant
16616                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16617                                    + " for user: " + currentUser);
16618                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16619                            return;
16620                        }
16621                    }
16622                } else if (!ps.getInstantApp(user.getIdentifier())) {
16623                    // can't downgrade from full to instant
16624                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16625                            + " for user: " + user.getIdentifier());
16626                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16627                    return;
16628                }
16629            }
16630        }
16631
16632        // Update what is removed
16633        res.removedInfo = new PackageRemovedInfo(this);
16634        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16635        res.removedInfo.removedPackage = oldPackage.packageName;
16636        res.removedInfo.installerPackageName = ps.installerPackageName;
16637        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16638        res.removedInfo.isUpdate = true;
16639        res.removedInfo.origUsers = installedUsers;
16640        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16641        for (int i = 0; i < installedUsers.length; i++) {
16642            final int userId = installedUsers[i];
16643            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16644        }
16645
16646        final int childCount = (oldPackage.childPackages != null)
16647                ? oldPackage.childPackages.size() : 0;
16648        for (int i = 0; i < childCount; i++) {
16649            boolean childPackageUpdated = false;
16650            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16651            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16652            if (res.addedChildPackages != null) {
16653                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16654                if (childRes != null) {
16655                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16656                    childRes.removedInfo.removedPackage = childPkg.packageName;
16657                    if (childPs != null) {
16658                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16659                    }
16660                    childRes.removedInfo.isUpdate = true;
16661                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16662                    childPackageUpdated = true;
16663                }
16664            }
16665            if (!childPackageUpdated) {
16666                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16667                childRemovedRes.removedPackage = childPkg.packageName;
16668                if (childPs != null) {
16669                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16670                }
16671                childRemovedRes.isUpdate = false;
16672                childRemovedRes.dataRemoved = true;
16673                synchronized (mPackages) {
16674                    if (childPs != null) {
16675                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16676                    }
16677                }
16678                if (res.removedInfo.removedChildPackages == null) {
16679                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16680                }
16681                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16682            }
16683        }
16684
16685        boolean sysPkg = (isSystemApp(oldPackage));
16686        if (sysPkg) {
16687            // Set the system/privileged flags as needed
16688            final boolean privileged =
16689                    (oldPackage.applicationInfo.privateFlags
16690                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16691            final int systemPolicyFlags = policyFlags
16692                    | PackageParser.PARSE_IS_SYSTEM
16693                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16694
16695            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16696                    user, allUsers, installerPackageName, res, installReason);
16697        } else {
16698            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16699                    user, allUsers, installerPackageName, res, installReason);
16700        }
16701    }
16702
16703    @Override
16704    public List<String> getPreviousCodePaths(String packageName) {
16705        final List<String> result = new ArrayList<>();
16706        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
16707            return result;
16708        }
16709        final PackageSetting ps = mSettings.mPackages.get(packageName);
16710        if (ps != null && ps.oldCodePaths != null) {
16711            result.addAll(ps.oldCodePaths);
16712        }
16713        return result;
16714    }
16715
16716    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16717            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16718            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16719            int installReason) {
16720        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16721                + deletedPackage);
16722
16723        String pkgName = deletedPackage.packageName;
16724        boolean deletedPkg = true;
16725        boolean addedPkg = false;
16726        boolean updatedSettings = false;
16727        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16728        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16729                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16730
16731        final long origUpdateTime = (pkg.mExtras != null)
16732                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16733
16734        // First delete the existing package while retaining the data directory
16735        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16736                res.removedInfo, true, pkg)) {
16737            // If the existing package wasn't successfully deleted
16738            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16739            deletedPkg = false;
16740        } else {
16741            // Successfully deleted the old package; proceed with replace.
16742
16743            // If deleted package lived in a container, give users a chance to
16744            // relinquish resources before killing.
16745            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16746                if (DEBUG_INSTALL) {
16747                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16748                }
16749                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16750                final ArrayList<String> pkgList = new ArrayList<String>(1);
16751                pkgList.add(deletedPackage.applicationInfo.packageName);
16752                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16753            }
16754
16755            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16756                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16757            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16758
16759            try {
16760                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16761                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16762                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16763                        installReason);
16764
16765                // Update the in-memory copy of the previous code paths.
16766                PackageSetting ps = mSettings.mPackages.get(pkgName);
16767                if (!killApp) {
16768                    if (ps.oldCodePaths == null) {
16769                        ps.oldCodePaths = new ArraySet<>();
16770                    }
16771                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16772                    if (deletedPackage.splitCodePaths != null) {
16773                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16774                    }
16775                } else {
16776                    ps.oldCodePaths = null;
16777                }
16778                if (ps.childPackageNames != null) {
16779                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16780                        final String childPkgName = ps.childPackageNames.get(i);
16781                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16782                        childPs.oldCodePaths = ps.oldCodePaths;
16783                    }
16784                }
16785                // set instant app status, but, only if it's explicitly specified
16786                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16787                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16788                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16789                prepareAppDataAfterInstallLIF(newPackage);
16790                addedPkg = true;
16791                mDexManager.notifyPackageUpdated(newPackage.packageName,
16792                        newPackage.baseCodePath, newPackage.splitCodePaths);
16793            } catch (PackageManagerException e) {
16794                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16795            }
16796        }
16797
16798        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16799            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16800
16801            // Revert all internal state mutations and added folders for the failed install
16802            if (addedPkg) {
16803                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16804                        res.removedInfo, true, null);
16805            }
16806
16807            // Restore the old package
16808            if (deletedPkg) {
16809                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16810                File restoreFile = new File(deletedPackage.codePath);
16811                // Parse old package
16812                boolean oldExternal = isExternal(deletedPackage);
16813                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16814                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16815                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16816                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16817                try {
16818                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16819                            null);
16820                } catch (PackageManagerException e) {
16821                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16822                            + e.getMessage());
16823                    return;
16824                }
16825
16826                synchronized (mPackages) {
16827                    // Ensure the installer package name up to date
16828                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16829
16830                    // Update permissions for restored package
16831                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16832
16833                    mSettings.writeLPr();
16834                }
16835
16836                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16837            }
16838        } else {
16839            synchronized (mPackages) {
16840                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16841                if (ps != null) {
16842                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16843                    if (res.removedInfo.removedChildPackages != null) {
16844                        final int childCount = res.removedInfo.removedChildPackages.size();
16845                        // Iterate in reverse as we may modify the collection
16846                        for (int i = childCount - 1; i >= 0; i--) {
16847                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16848                            if (res.addedChildPackages.containsKey(childPackageName)) {
16849                                res.removedInfo.removedChildPackages.removeAt(i);
16850                            } else {
16851                                PackageRemovedInfo childInfo = res.removedInfo
16852                                        .removedChildPackages.valueAt(i);
16853                                childInfo.removedForAllUsers = mPackages.get(
16854                                        childInfo.removedPackage) == null;
16855                            }
16856                        }
16857                    }
16858                }
16859            }
16860        }
16861    }
16862
16863    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16864            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16865            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16866            int installReason) {
16867        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16868                + ", old=" + deletedPackage);
16869
16870        final boolean disabledSystem;
16871
16872        // Remove existing system package
16873        removePackageLI(deletedPackage, true);
16874
16875        synchronized (mPackages) {
16876            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16877        }
16878        if (!disabledSystem) {
16879            // We didn't need to disable the .apk as a current system package,
16880            // which means we are replacing another update that is already
16881            // installed.  We need to make sure to delete the older one's .apk.
16882            res.removedInfo.args = createInstallArgsForExisting(0,
16883                    deletedPackage.applicationInfo.getCodePath(),
16884                    deletedPackage.applicationInfo.getResourcePath(),
16885                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16886        } else {
16887            res.removedInfo.args = null;
16888        }
16889
16890        // Successfully disabled the old package. Now proceed with re-installation
16891        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16892                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16893        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16894
16895        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16896        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16897                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16898
16899        PackageParser.Package newPackage = null;
16900        try {
16901            // Add the package to the internal data structures
16902            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16903
16904            // Set the update and install times
16905            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16906            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16907                    System.currentTimeMillis());
16908
16909            // Update the package dynamic state if succeeded
16910            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16911                // Now that the install succeeded make sure we remove data
16912                // directories for any child package the update removed.
16913                final int deletedChildCount = (deletedPackage.childPackages != null)
16914                        ? deletedPackage.childPackages.size() : 0;
16915                final int newChildCount = (newPackage.childPackages != null)
16916                        ? newPackage.childPackages.size() : 0;
16917                for (int i = 0; i < deletedChildCount; i++) {
16918                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16919                    boolean childPackageDeleted = true;
16920                    for (int j = 0; j < newChildCount; j++) {
16921                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16922                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16923                            childPackageDeleted = false;
16924                            break;
16925                        }
16926                    }
16927                    if (childPackageDeleted) {
16928                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16929                                deletedChildPkg.packageName);
16930                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16931                            PackageRemovedInfo removedChildRes = res.removedInfo
16932                                    .removedChildPackages.get(deletedChildPkg.packageName);
16933                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16934                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16935                        }
16936                    }
16937                }
16938
16939                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16940                        installReason);
16941                prepareAppDataAfterInstallLIF(newPackage);
16942
16943                mDexManager.notifyPackageUpdated(newPackage.packageName,
16944                            newPackage.baseCodePath, newPackage.splitCodePaths);
16945            }
16946        } catch (PackageManagerException e) {
16947            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16948            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16949        }
16950
16951        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16952            // Re installation failed. Restore old information
16953            // Remove new pkg information
16954            if (newPackage != null) {
16955                removeInstalledPackageLI(newPackage, true);
16956            }
16957            // Add back the old system package
16958            try {
16959                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16960            } catch (PackageManagerException e) {
16961                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16962            }
16963
16964            synchronized (mPackages) {
16965                if (disabledSystem) {
16966                    enableSystemPackageLPw(deletedPackage);
16967                }
16968
16969                // Ensure the installer package name up to date
16970                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16971
16972                // Update permissions for restored package
16973                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16974
16975                mSettings.writeLPr();
16976            }
16977
16978            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16979                    + " after failed upgrade");
16980        }
16981    }
16982
16983    /**
16984     * Checks whether the parent or any of the child packages have a change shared
16985     * user. For a package to be a valid update the shred users of the parent and
16986     * the children should match. We may later support changing child shared users.
16987     * @param oldPkg The updated package.
16988     * @param newPkg The update package.
16989     * @return The shared user that change between the versions.
16990     */
16991    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16992            PackageParser.Package newPkg) {
16993        // Check parent shared user
16994        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16995            return newPkg.packageName;
16996        }
16997        // Check child shared users
16998        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16999        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17000        for (int i = 0; i < newChildCount; i++) {
17001            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17002            // If this child was present, did it have the same shared user?
17003            for (int j = 0; j < oldChildCount; j++) {
17004                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17005                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17006                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17007                    return newChildPkg.packageName;
17008                }
17009            }
17010        }
17011        return null;
17012    }
17013
17014    private void removeNativeBinariesLI(PackageSetting ps) {
17015        // Remove the lib path for the parent package
17016        if (ps != null) {
17017            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17018            // Remove the lib path for the child packages
17019            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17020            for (int i = 0; i < childCount; i++) {
17021                PackageSetting childPs = null;
17022                synchronized (mPackages) {
17023                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17024                }
17025                if (childPs != null) {
17026                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17027                            .legacyNativeLibraryPathString);
17028                }
17029            }
17030        }
17031    }
17032
17033    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17034        // Enable the parent package
17035        mSettings.enableSystemPackageLPw(pkg.packageName);
17036        // Enable the child packages
17037        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17038        for (int i = 0; i < childCount; i++) {
17039            PackageParser.Package childPkg = pkg.childPackages.get(i);
17040            mSettings.enableSystemPackageLPw(childPkg.packageName);
17041        }
17042    }
17043
17044    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17045            PackageParser.Package newPkg) {
17046        // Disable the parent package (parent always replaced)
17047        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17048        // Disable the child packages
17049        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17050        for (int i = 0; i < childCount; i++) {
17051            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17052            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17053            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17054        }
17055        return disabled;
17056    }
17057
17058    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17059            String installerPackageName) {
17060        // Enable the parent package
17061        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17062        // Enable the child packages
17063        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17064        for (int i = 0; i < childCount; i++) {
17065            PackageParser.Package childPkg = pkg.childPackages.get(i);
17066            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17067        }
17068    }
17069
17070    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17071        // Collect all used permissions in the UID
17072        ArraySet<String> usedPermissions = new ArraySet<>();
17073        final int packageCount = su.packages.size();
17074        for (int i = 0; i < packageCount; i++) {
17075            PackageSetting ps = su.packages.valueAt(i);
17076            if (ps.pkg == null) {
17077                continue;
17078            }
17079            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17080            for (int j = 0; j < requestedPermCount; j++) {
17081                String permission = ps.pkg.requestedPermissions.get(j);
17082                BasePermission bp = mSettings.mPermissions.get(permission);
17083                if (bp != null) {
17084                    usedPermissions.add(permission);
17085                }
17086            }
17087        }
17088
17089        PermissionsState permissionsState = su.getPermissionsState();
17090        // Prune install permissions
17091        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17092        final int installPermCount = installPermStates.size();
17093        for (int i = installPermCount - 1; i >= 0;  i--) {
17094            PermissionState permissionState = installPermStates.get(i);
17095            if (!usedPermissions.contains(permissionState.getName())) {
17096                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17097                if (bp != null) {
17098                    permissionsState.revokeInstallPermission(bp);
17099                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17100                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17101                }
17102            }
17103        }
17104
17105        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17106
17107        // Prune runtime permissions
17108        for (int userId : allUserIds) {
17109            List<PermissionState> runtimePermStates = permissionsState
17110                    .getRuntimePermissionStates(userId);
17111            final int runtimePermCount = runtimePermStates.size();
17112            for (int i = runtimePermCount - 1; i >= 0; i--) {
17113                PermissionState permissionState = runtimePermStates.get(i);
17114                if (!usedPermissions.contains(permissionState.getName())) {
17115                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17116                    if (bp != null) {
17117                        permissionsState.revokeRuntimePermission(bp, userId);
17118                        permissionsState.updatePermissionFlags(bp, userId,
17119                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17120                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17121                                runtimePermissionChangedUserIds, userId);
17122                    }
17123                }
17124            }
17125        }
17126
17127        return runtimePermissionChangedUserIds;
17128    }
17129
17130    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17131            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17132        // Update the parent package setting
17133        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17134                res, user, installReason);
17135        // Update the child packages setting
17136        final int childCount = (newPackage.childPackages != null)
17137                ? newPackage.childPackages.size() : 0;
17138        for (int i = 0; i < childCount; i++) {
17139            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17140            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17141            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17142                    childRes.origUsers, childRes, user, installReason);
17143        }
17144    }
17145
17146    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17147            String installerPackageName, int[] allUsers, int[] installedForUsers,
17148            PackageInstalledInfo res, UserHandle user, int installReason) {
17149        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17150
17151        String pkgName = newPackage.packageName;
17152        synchronized (mPackages) {
17153            //write settings. the installStatus will be incomplete at this stage.
17154            //note that the new package setting would have already been
17155            //added to mPackages. It hasn't been persisted yet.
17156            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17157            // TODO: Remove this write? It's also written at the end of this method
17158            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17159            mSettings.writeLPr();
17160            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17161        }
17162
17163        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17164        synchronized (mPackages) {
17165            updatePermissionsLPw(newPackage.packageName, newPackage,
17166                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17167                            ? UPDATE_PERMISSIONS_ALL : 0));
17168            // For system-bundled packages, we assume that installing an upgraded version
17169            // of the package implies that the user actually wants to run that new code,
17170            // so we enable the package.
17171            PackageSetting ps = mSettings.mPackages.get(pkgName);
17172            final int userId = user.getIdentifier();
17173            if (ps != null) {
17174                if (isSystemApp(newPackage)) {
17175                    if (DEBUG_INSTALL) {
17176                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17177                    }
17178                    // Enable system package for requested users
17179                    if (res.origUsers != null) {
17180                        for (int origUserId : res.origUsers) {
17181                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17182                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17183                                        origUserId, installerPackageName);
17184                            }
17185                        }
17186                    }
17187                    // Also convey the prior install/uninstall state
17188                    if (allUsers != null && installedForUsers != null) {
17189                        for (int currentUserId : allUsers) {
17190                            final boolean installed = ArrayUtils.contains(
17191                                    installedForUsers, currentUserId);
17192                            if (DEBUG_INSTALL) {
17193                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17194                            }
17195                            ps.setInstalled(installed, currentUserId);
17196                        }
17197                        // these install state changes will be persisted in the
17198                        // upcoming call to mSettings.writeLPr().
17199                    }
17200                }
17201                // It's implied that when a user requests installation, they want the app to be
17202                // installed and enabled.
17203                if (userId != UserHandle.USER_ALL) {
17204                    ps.setInstalled(true, userId);
17205                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17206                }
17207
17208                // When replacing an existing package, preserve the original install reason for all
17209                // users that had the package installed before.
17210                final Set<Integer> previousUserIds = new ArraySet<>();
17211                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17212                    final int installReasonCount = res.removedInfo.installReasons.size();
17213                    for (int i = 0; i < installReasonCount; i++) {
17214                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17215                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17216                        ps.setInstallReason(previousInstallReason, previousUserId);
17217                        previousUserIds.add(previousUserId);
17218                    }
17219                }
17220
17221                // Set install reason for users that are having the package newly installed.
17222                if (userId == UserHandle.USER_ALL) {
17223                    for (int currentUserId : sUserManager.getUserIds()) {
17224                        if (!previousUserIds.contains(currentUserId)) {
17225                            ps.setInstallReason(installReason, currentUserId);
17226                        }
17227                    }
17228                } else if (!previousUserIds.contains(userId)) {
17229                    ps.setInstallReason(installReason, userId);
17230                }
17231                mSettings.writeKernelMappingLPr(ps);
17232            }
17233            res.name = pkgName;
17234            res.uid = newPackage.applicationInfo.uid;
17235            res.pkg = newPackage;
17236            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17237            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17238            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17239            //to update install status
17240            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17241            mSettings.writeLPr();
17242            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17243        }
17244
17245        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17246    }
17247
17248    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17249        try {
17250            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17251            installPackageLI(args, res);
17252        } finally {
17253            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17254        }
17255    }
17256
17257    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17258        final int installFlags = args.installFlags;
17259        final String installerPackageName = args.installerPackageName;
17260        final String volumeUuid = args.volumeUuid;
17261        final File tmpPackageFile = new File(args.getCodePath());
17262        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17263        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17264                || (args.volumeUuid != null));
17265        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17266        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17267        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17268        boolean replace = false;
17269        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17270        if (args.move != null) {
17271            // moving a complete application; perform an initial scan on the new install location
17272            scanFlags |= SCAN_INITIAL;
17273        }
17274        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17275            scanFlags |= SCAN_DONT_KILL_APP;
17276        }
17277        if (instantApp) {
17278            scanFlags |= SCAN_AS_INSTANT_APP;
17279        }
17280        if (fullApp) {
17281            scanFlags |= SCAN_AS_FULL_APP;
17282        }
17283
17284        // Result object to be returned
17285        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17286
17287        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17288
17289        // Sanity check
17290        if (instantApp && (forwardLocked || onExternal)) {
17291            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17292                    + " external=" + onExternal);
17293            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17294            return;
17295        }
17296
17297        // Retrieve PackageSettings and parse package
17298        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17299                | PackageParser.PARSE_ENFORCE_CODE
17300                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17301                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17302                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17303                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17304        PackageParser pp = new PackageParser();
17305        pp.setSeparateProcesses(mSeparateProcesses);
17306        pp.setDisplayMetrics(mMetrics);
17307        pp.setCallback(mPackageParserCallback);
17308
17309        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17310        final PackageParser.Package pkg;
17311        try {
17312            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17313        } catch (PackageParserException e) {
17314            res.setError("Failed parse during installPackageLI", e);
17315            return;
17316        } finally {
17317            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17318        }
17319
17320        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17321        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17322            Slog.w(TAG, "Instant app package " + pkg.packageName
17323                    + " does not target O, this will be a fatal error.");
17324            // STOPSHIP: Make this a fatal error
17325            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
17326        }
17327        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17328            Slog.w(TAG, "Instant app package " + pkg.packageName
17329                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
17330            // STOPSHIP: Make this a fatal error
17331            pkg.applicationInfo.targetSandboxVersion = 2;
17332        }
17333
17334        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17335            // Static shared libraries have synthetic package names
17336            renameStaticSharedLibraryPackage(pkg);
17337
17338            // No static shared libs on external storage
17339            if (onExternal) {
17340                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17341                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17342                        "Packages declaring static-shared libs cannot be updated");
17343                return;
17344            }
17345        }
17346
17347        // If we are installing a clustered package add results for the children
17348        if (pkg.childPackages != null) {
17349            synchronized (mPackages) {
17350                final int childCount = pkg.childPackages.size();
17351                for (int i = 0; i < childCount; i++) {
17352                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17353                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17354                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17355                    childRes.pkg = childPkg;
17356                    childRes.name = childPkg.packageName;
17357                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17358                    if (childPs != null) {
17359                        childRes.origUsers = childPs.queryInstalledUsers(
17360                                sUserManager.getUserIds(), true);
17361                    }
17362                    if ((mPackages.containsKey(childPkg.packageName))) {
17363                        childRes.removedInfo = new PackageRemovedInfo(this);
17364                        childRes.removedInfo.removedPackage = childPkg.packageName;
17365                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17366                    }
17367                    if (res.addedChildPackages == null) {
17368                        res.addedChildPackages = new ArrayMap<>();
17369                    }
17370                    res.addedChildPackages.put(childPkg.packageName, childRes);
17371                }
17372            }
17373        }
17374
17375        // If package doesn't declare API override, mark that we have an install
17376        // time CPU ABI override.
17377        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17378            pkg.cpuAbiOverride = args.abiOverride;
17379        }
17380
17381        String pkgName = res.name = pkg.packageName;
17382        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17383            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17384                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17385                return;
17386            }
17387        }
17388
17389        try {
17390            // either use what we've been given or parse directly from the APK
17391            if (args.certificates != null) {
17392                try {
17393                    PackageParser.populateCertificates(pkg, args.certificates);
17394                } catch (PackageParserException e) {
17395                    // there was something wrong with the certificates we were given;
17396                    // try to pull them from the APK
17397                    PackageParser.collectCertificates(pkg, parseFlags);
17398                }
17399            } else {
17400                PackageParser.collectCertificates(pkg, parseFlags);
17401            }
17402        } catch (PackageParserException e) {
17403            res.setError("Failed collect during installPackageLI", e);
17404            return;
17405        }
17406
17407        // Get rid of all references to package scan path via parser.
17408        pp = null;
17409        String oldCodePath = null;
17410        boolean systemApp = false;
17411        synchronized (mPackages) {
17412            // Check if installing already existing package
17413            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17414                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17415                if (pkg.mOriginalPackages != null
17416                        && pkg.mOriginalPackages.contains(oldName)
17417                        && mPackages.containsKey(oldName)) {
17418                    // This package is derived from an original package,
17419                    // and this device has been updating from that original
17420                    // name.  We must continue using the original name, so
17421                    // rename the new package here.
17422                    pkg.setPackageName(oldName);
17423                    pkgName = pkg.packageName;
17424                    replace = true;
17425                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17426                            + oldName + " pkgName=" + pkgName);
17427                } else if (mPackages.containsKey(pkgName)) {
17428                    // This package, under its official name, already exists
17429                    // on the device; we should replace it.
17430                    replace = true;
17431                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17432                }
17433
17434                // Child packages are installed through the parent package
17435                if (pkg.parentPackage != null) {
17436                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17437                            "Package " + pkg.packageName + " is child of package "
17438                                    + pkg.parentPackage.parentPackage + ". Child packages "
17439                                    + "can be updated only through the parent package.");
17440                    return;
17441                }
17442
17443                if (replace) {
17444                    // Prevent apps opting out from runtime permissions
17445                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17446                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17447                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17448                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17449                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17450                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17451                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17452                                        + " doesn't support runtime permissions but the old"
17453                                        + " target SDK " + oldTargetSdk + " does.");
17454                        return;
17455                    }
17456                    // Prevent apps from downgrading their targetSandbox.
17457                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
17458                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
17459                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
17460                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17461                                "Package " + pkg.packageName + " new target sandbox "
17462                                + newTargetSandbox + " is incompatible with the previous value of"
17463                                + oldTargetSandbox + ".");
17464                        return;
17465                    }
17466
17467                    // Prevent installing of child packages
17468                    if (oldPackage.parentPackage != null) {
17469                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17470                                "Package " + pkg.packageName + " is child of package "
17471                                        + oldPackage.parentPackage + ". Child packages "
17472                                        + "can be updated only through the parent package.");
17473                        return;
17474                    }
17475                }
17476            }
17477
17478            PackageSetting ps = mSettings.mPackages.get(pkgName);
17479            if (ps != null) {
17480                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17481
17482                // Static shared libs have same package with different versions where
17483                // we internally use a synthetic package name to allow multiple versions
17484                // of the same package, therefore we need to compare signatures against
17485                // the package setting for the latest library version.
17486                PackageSetting signatureCheckPs = ps;
17487                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17488                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17489                    if (libraryEntry != null) {
17490                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17491                    }
17492                }
17493
17494                // Quick sanity check that we're signed correctly if updating;
17495                // we'll check this again later when scanning, but we want to
17496                // bail early here before tripping over redefined permissions.
17497                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17498                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17499                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17500                                + pkg.packageName + " upgrade keys do not match the "
17501                                + "previously installed version");
17502                        return;
17503                    }
17504                } else {
17505                    try {
17506                        verifySignaturesLP(signatureCheckPs, pkg);
17507                    } catch (PackageManagerException e) {
17508                        res.setError(e.error, e.getMessage());
17509                        return;
17510                    }
17511                }
17512
17513                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17514                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17515                    systemApp = (ps.pkg.applicationInfo.flags &
17516                            ApplicationInfo.FLAG_SYSTEM) != 0;
17517                }
17518                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17519            }
17520
17521            int N = pkg.permissions.size();
17522            for (int i = N-1; i >= 0; i--) {
17523                PackageParser.Permission perm = pkg.permissions.get(i);
17524                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17525
17526                // Don't allow anyone but the system to define ephemeral permissions.
17527                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17528                        && !systemApp) {
17529                    Slog.w(TAG, "Non-System package " + pkg.packageName
17530                            + " attempting to delcare ephemeral permission "
17531                            + perm.info.name + "; Removing ephemeral.");
17532                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17533                }
17534                // Check whether the newly-scanned package wants to define an already-defined perm
17535                if (bp != null) {
17536                    // If the defining package is signed with our cert, it's okay.  This
17537                    // also includes the "updating the same package" case, of course.
17538                    // "updating same package" could also involve key-rotation.
17539                    final boolean sigsOk;
17540                    if (bp.sourcePackage.equals(pkg.packageName)
17541                            && (bp.packageSetting instanceof PackageSetting)
17542                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17543                                    scanFlags))) {
17544                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17545                    } else {
17546                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17547                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17548                    }
17549                    if (!sigsOk) {
17550                        // If the owning package is the system itself, we log but allow
17551                        // install to proceed; we fail the install on all other permission
17552                        // redefinitions.
17553                        if (!bp.sourcePackage.equals("android")) {
17554                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17555                                    + pkg.packageName + " attempting to redeclare permission "
17556                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17557                            res.origPermission = perm.info.name;
17558                            res.origPackage = bp.sourcePackage;
17559                            return;
17560                        } else {
17561                            Slog.w(TAG, "Package " + pkg.packageName
17562                                    + " attempting to redeclare system permission "
17563                                    + perm.info.name + "; ignoring new declaration");
17564                            pkg.permissions.remove(i);
17565                        }
17566                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17567                        // Prevent apps to change protection level to dangerous from any other
17568                        // type as this would allow a privilege escalation where an app adds a
17569                        // normal/signature permission in other app's group and later redefines
17570                        // it as dangerous leading to the group auto-grant.
17571                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17572                                == PermissionInfo.PROTECTION_DANGEROUS) {
17573                            if (bp != null && !bp.isRuntime()) {
17574                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17575                                        + "non-runtime permission " + perm.info.name
17576                                        + " to runtime; keeping old protection level");
17577                                perm.info.protectionLevel = bp.protectionLevel;
17578                            }
17579                        }
17580                    }
17581                }
17582            }
17583        }
17584
17585        if (systemApp) {
17586            if (onExternal) {
17587                // Abort update; system app can't be replaced with app on sdcard
17588                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17589                        "Cannot install updates to system apps on sdcard");
17590                return;
17591            } else if (instantApp) {
17592                // Abort update; system app can't be replaced with an instant app
17593                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17594                        "Cannot update a system app with an instant app");
17595                return;
17596            }
17597        }
17598
17599        if (args.move != null) {
17600            // We did an in-place move, so dex is ready to roll
17601            scanFlags |= SCAN_NO_DEX;
17602            scanFlags |= SCAN_MOVE;
17603
17604            synchronized (mPackages) {
17605                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17606                if (ps == null) {
17607                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17608                            "Missing settings for moved package " + pkgName);
17609                }
17610
17611                // We moved the entire application as-is, so bring over the
17612                // previously derived ABI information.
17613                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17614                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17615            }
17616
17617        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17618            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17619            scanFlags |= SCAN_NO_DEX;
17620
17621            try {
17622                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17623                    args.abiOverride : pkg.cpuAbiOverride);
17624                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17625                        true /*extractLibs*/, mAppLib32InstallDir);
17626            } catch (PackageManagerException pme) {
17627                Slog.e(TAG, "Error deriving application ABI", pme);
17628                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17629                return;
17630            }
17631
17632            // Shared libraries for the package need to be updated.
17633            synchronized (mPackages) {
17634                try {
17635                    updateSharedLibrariesLPr(pkg, null);
17636                } catch (PackageManagerException e) {
17637                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17638                }
17639            }
17640
17641            // dexopt can take some time to complete, so, for instant apps, we skip this
17642            // step during installation. Instead, we'll take extra time the first time the
17643            // instant app starts. It's preferred to do it this way to provide continuous
17644            // progress to the user instead of mysteriously blocking somewhere in the
17645            // middle of running an instant app.
17646            if (!instantApp) {
17647                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17648                // Do not run PackageDexOptimizer through the local performDexOpt
17649                // method because `pkg` may not be in `mPackages` yet.
17650                //
17651                // Also, don't fail application installs if the dexopt step fails.
17652                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17653                        null /* instructionSets */, false /* checkProfiles */,
17654                        getCompilerFilterForReason(REASON_INSTALL),
17655                        getOrCreateCompilerPackageStats(pkg),
17656                        mDexManager.isUsedByOtherApps(pkg.packageName));
17657                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17658            }
17659
17660            // Notify BackgroundDexOptService that the package has been changed.
17661            // If this is an update of a package which used to fail to compile,
17662            // BDOS will remove it from its blacklist.
17663            // TODO: Layering violation
17664            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17665        }
17666
17667        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17668            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17669            return;
17670        }
17671
17672        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17673
17674        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17675                "installPackageLI")) {
17676            if (replace) {
17677                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17678                    // Static libs have a synthetic package name containing the version
17679                    // and cannot be updated as an update would get a new package name,
17680                    // unless this is the exact same version code which is useful for
17681                    // development.
17682                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17683                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17684                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17685                                + "static-shared libs cannot be updated");
17686                        return;
17687                    }
17688                }
17689                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17690                        installerPackageName, res, args.installReason);
17691            } else {
17692                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17693                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17694            }
17695        }
17696
17697        synchronized (mPackages) {
17698            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17699            if (ps != null) {
17700                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17701                ps.setUpdateAvailable(false /*updateAvailable*/);
17702            }
17703
17704            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17705            for (int i = 0; i < childCount; i++) {
17706                PackageParser.Package childPkg = pkg.childPackages.get(i);
17707                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17708                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17709                if (childPs != null) {
17710                    childRes.newUsers = childPs.queryInstalledUsers(
17711                            sUserManager.getUserIds(), true);
17712                }
17713            }
17714
17715            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17716                updateSequenceNumberLP(pkgName, res.newUsers);
17717                updateInstantAppInstallerLocked(pkgName);
17718            }
17719        }
17720    }
17721
17722    private void startIntentFilterVerifications(int userId, boolean replacing,
17723            PackageParser.Package pkg) {
17724        if (mIntentFilterVerifierComponent == null) {
17725            Slog.w(TAG, "No IntentFilter verification will not be done as "
17726                    + "there is no IntentFilterVerifier available!");
17727            return;
17728        }
17729
17730        final int verifierUid = getPackageUid(
17731                mIntentFilterVerifierComponent.getPackageName(),
17732                MATCH_DEBUG_TRIAGED_MISSING,
17733                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17734
17735        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17736        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17737        mHandler.sendMessage(msg);
17738
17739        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17740        for (int i = 0; i < childCount; i++) {
17741            PackageParser.Package childPkg = pkg.childPackages.get(i);
17742            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17743            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17744            mHandler.sendMessage(msg);
17745        }
17746    }
17747
17748    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17749            PackageParser.Package pkg) {
17750        int size = pkg.activities.size();
17751        if (size == 0) {
17752            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17753                    "No activity, so no need to verify any IntentFilter!");
17754            return;
17755        }
17756
17757        final boolean hasDomainURLs = hasDomainURLs(pkg);
17758        if (!hasDomainURLs) {
17759            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17760                    "No domain URLs, so no need to verify any IntentFilter!");
17761            return;
17762        }
17763
17764        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17765                + " if any IntentFilter from the " + size
17766                + " Activities needs verification ...");
17767
17768        int count = 0;
17769        final String packageName = pkg.packageName;
17770
17771        synchronized (mPackages) {
17772            // If this is a new install and we see that we've already run verification for this
17773            // package, we have nothing to do: it means the state was restored from backup.
17774            if (!replacing) {
17775                IntentFilterVerificationInfo ivi =
17776                        mSettings.getIntentFilterVerificationLPr(packageName);
17777                if (ivi != null) {
17778                    if (DEBUG_DOMAIN_VERIFICATION) {
17779                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17780                                + ivi.getStatusString());
17781                    }
17782                    return;
17783                }
17784            }
17785
17786            // If any filters need to be verified, then all need to be.
17787            boolean needToVerify = false;
17788            for (PackageParser.Activity a : pkg.activities) {
17789                for (ActivityIntentInfo filter : a.intents) {
17790                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17791                        if (DEBUG_DOMAIN_VERIFICATION) {
17792                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17793                        }
17794                        needToVerify = true;
17795                        break;
17796                    }
17797                }
17798            }
17799
17800            if (needToVerify) {
17801                final int verificationId = mIntentFilterVerificationToken++;
17802                for (PackageParser.Activity a : pkg.activities) {
17803                    for (ActivityIntentInfo filter : a.intents) {
17804                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17805                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17806                                    "Verification needed for IntentFilter:" + filter.toString());
17807                            mIntentFilterVerifier.addOneIntentFilterVerification(
17808                                    verifierUid, userId, verificationId, filter, packageName);
17809                            count++;
17810                        }
17811                    }
17812                }
17813            }
17814        }
17815
17816        if (count > 0) {
17817            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17818                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17819                    +  " for userId:" + userId);
17820            mIntentFilterVerifier.startVerifications(userId);
17821        } else {
17822            if (DEBUG_DOMAIN_VERIFICATION) {
17823                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17824            }
17825        }
17826    }
17827
17828    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17829        final ComponentName cn  = filter.activity.getComponentName();
17830        final String packageName = cn.getPackageName();
17831
17832        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17833                packageName);
17834        if (ivi == null) {
17835            return true;
17836        }
17837        int status = ivi.getStatus();
17838        switch (status) {
17839            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17840            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17841                return true;
17842
17843            default:
17844                // Nothing to do
17845                return false;
17846        }
17847    }
17848
17849    private static boolean isMultiArch(ApplicationInfo info) {
17850        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17851    }
17852
17853    private static boolean isExternal(PackageParser.Package pkg) {
17854        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17855    }
17856
17857    private static boolean isExternal(PackageSetting ps) {
17858        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17859    }
17860
17861    private static boolean isSystemApp(PackageParser.Package pkg) {
17862        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17863    }
17864
17865    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17866        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17867    }
17868
17869    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17870        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17871    }
17872
17873    private static boolean isSystemApp(PackageSetting ps) {
17874        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17875    }
17876
17877    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17878        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17879    }
17880
17881    private int packageFlagsToInstallFlags(PackageSetting ps) {
17882        int installFlags = 0;
17883        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17884            // This existing package was an external ASEC install when we have
17885            // the external flag without a UUID
17886            installFlags |= PackageManager.INSTALL_EXTERNAL;
17887        }
17888        if (ps.isForwardLocked()) {
17889            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17890        }
17891        return installFlags;
17892    }
17893
17894    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17895        if (isExternal(pkg)) {
17896            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17897                return StorageManager.UUID_PRIMARY_PHYSICAL;
17898            } else {
17899                return pkg.volumeUuid;
17900            }
17901        } else {
17902            return StorageManager.UUID_PRIVATE_INTERNAL;
17903        }
17904    }
17905
17906    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17907        if (isExternal(pkg)) {
17908            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17909                return mSettings.getExternalVersion();
17910            } else {
17911                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17912            }
17913        } else {
17914            return mSettings.getInternalVersion();
17915        }
17916    }
17917
17918    private void deleteTempPackageFiles() {
17919        final FilenameFilter filter = new FilenameFilter() {
17920            public boolean accept(File dir, String name) {
17921                return name.startsWith("vmdl") && name.endsWith(".tmp");
17922            }
17923        };
17924        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17925            file.delete();
17926        }
17927    }
17928
17929    @Override
17930    public void deletePackageAsUser(String packageName, int versionCode,
17931            IPackageDeleteObserver observer, int userId, int flags) {
17932        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17933                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17934    }
17935
17936    @Override
17937    public void deletePackageVersioned(VersionedPackage versionedPackage,
17938            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17939        mContext.enforceCallingOrSelfPermission(
17940                android.Manifest.permission.DELETE_PACKAGES, null);
17941        Preconditions.checkNotNull(versionedPackage);
17942        Preconditions.checkNotNull(observer);
17943        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17944                PackageManager.VERSION_CODE_HIGHEST,
17945                Integer.MAX_VALUE, "versionCode must be >= -1");
17946
17947        final String packageName = versionedPackage.getPackageName();
17948        final int versionCode = versionedPackage.getVersionCode();
17949        final String internalPackageName;
17950        synchronized (mPackages) {
17951            // Normalize package name to handle renamed packages and static libs
17952            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17953                    versionedPackage.getVersionCode());
17954        }
17955
17956        final int uid = Binder.getCallingUid();
17957        if (!isOrphaned(internalPackageName)
17958                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17959            try {
17960                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17961                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17962                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17963                observer.onUserActionRequired(intent);
17964            } catch (RemoteException re) {
17965            }
17966            return;
17967        }
17968        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17969        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17970        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17971            mContext.enforceCallingOrSelfPermission(
17972                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17973                    "deletePackage for user " + userId);
17974        }
17975
17976        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17977            try {
17978                observer.onPackageDeleted(packageName,
17979                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17980            } catch (RemoteException re) {
17981            }
17982            return;
17983        }
17984
17985        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17986            try {
17987                observer.onPackageDeleted(packageName,
17988                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17989            } catch (RemoteException re) {
17990            }
17991            return;
17992        }
17993
17994        if (DEBUG_REMOVE) {
17995            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17996                    + " deleteAllUsers: " + deleteAllUsers + " version="
17997                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17998                    ? "VERSION_CODE_HIGHEST" : versionCode));
17999        }
18000        // Queue up an async operation since the package deletion may take a little while.
18001        mHandler.post(new Runnable() {
18002            public void run() {
18003                mHandler.removeCallbacks(this);
18004                int returnCode;
18005                if (!deleteAllUsers) {
18006                    returnCode = deletePackageX(internalPackageName, versionCode,
18007                            userId, deleteFlags);
18008                } else {
18009                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
18010                            internalPackageName, users);
18011                    // If nobody is blocking uninstall, proceed with delete for all users
18012                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18013                        returnCode = deletePackageX(internalPackageName, versionCode,
18014                                userId, deleteFlags);
18015                    } else {
18016                        // Otherwise uninstall individually for users with blockUninstalls=false
18017                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18018                        for (int userId : users) {
18019                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18020                                returnCode = deletePackageX(internalPackageName, versionCode,
18021                                        userId, userFlags);
18022                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18023                                    Slog.w(TAG, "Package delete failed for user " + userId
18024                                            + ", returnCode " + returnCode);
18025                                }
18026                            }
18027                        }
18028                        // The app has only been marked uninstalled for certain users.
18029                        // We still need to report that delete was blocked
18030                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18031                    }
18032                }
18033                try {
18034                    observer.onPackageDeleted(packageName, returnCode, null);
18035                } catch (RemoteException e) {
18036                    Log.i(TAG, "Observer no longer exists.");
18037                } //end catch
18038            } //end run
18039        });
18040    }
18041
18042    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18043        if (pkg.staticSharedLibName != null) {
18044            return pkg.manifestPackageName;
18045        }
18046        return pkg.packageName;
18047    }
18048
18049    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18050        // Handle renamed packages
18051        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18052        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18053
18054        // Is this a static library?
18055        SparseArray<SharedLibraryEntry> versionedLib =
18056                mStaticLibsByDeclaringPackage.get(packageName);
18057        if (versionedLib == null || versionedLib.size() <= 0) {
18058            return packageName;
18059        }
18060
18061        // Figure out which lib versions the caller can see
18062        SparseIntArray versionsCallerCanSee = null;
18063        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18064        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18065                && callingAppId != Process.ROOT_UID) {
18066            versionsCallerCanSee = new SparseIntArray();
18067            String libName = versionedLib.valueAt(0).info.getName();
18068            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18069            if (uidPackages != null) {
18070                for (String uidPackage : uidPackages) {
18071                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18072                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18073                    if (libIdx >= 0) {
18074                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18075                        versionsCallerCanSee.append(libVersion, libVersion);
18076                    }
18077                }
18078            }
18079        }
18080
18081        // Caller can see nothing - done
18082        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18083            return packageName;
18084        }
18085
18086        // Find the version the caller can see and the app version code
18087        SharedLibraryEntry highestVersion = null;
18088        final int versionCount = versionedLib.size();
18089        for (int i = 0; i < versionCount; i++) {
18090            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18091            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18092                    libEntry.info.getVersion()) < 0) {
18093                continue;
18094            }
18095            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18096            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18097                if (libVersionCode == versionCode) {
18098                    return libEntry.apk;
18099                }
18100            } else if (highestVersion == null) {
18101                highestVersion = libEntry;
18102            } else if (libVersionCode  > highestVersion.info
18103                    .getDeclaringPackage().getVersionCode()) {
18104                highestVersion = libEntry;
18105            }
18106        }
18107
18108        if (highestVersion != null) {
18109            return highestVersion.apk;
18110        }
18111
18112        return packageName;
18113    }
18114
18115    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18116        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18117              || callingUid == Process.SYSTEM_UID) {
18118            return true;
18119        }
18120        final int callingUserId = UserHandle.getUserId(callingUid);
18121        // If the caller installed the pkgName, then allow it to silently uninstall.
18122        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18123            return true;
18124        }
18125
18126        // Allow package verifier to silently uninstall.
18127        if (mRequiredVerifierPackage != null &&
18128                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18129            return true;
18130        }
18131
18132        // Allow package uninstaller to silently uninstall.
18133        if (mRequiredUninstallerPackage != null &&
18134                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18135            return true;
18136        }
18137
18138        // Allow storage manager to silently uninstall.
18139        if (mStorageManagerPackage != null &&
18140                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18141            return true;
18142        }
18143        return false;
18144    }
18145
18146    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18147        int[] result = EMPTY_INT_ARRAY;
18148        for (int userId : userIds) {
18149            if (getBlockUninstallForUser(packageName, userId)) {
18150                result = ArrayUtils.appendInt(result, userId);
18151            }
18152        }
18153        return result;
18154    }
18155
18156    @Override
18157    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18158        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18159    }
18160
18161    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18162        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18163                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18164        try {
18165            if (dpm != null) {
18166                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18167                        /* callingUserOnly =*/ false);
18168                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18169                        : deviceOwnerComponentName.getPackageName();
18170                // Does the package contains the device owner?
18171                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18172                // this check is probably not needed, since DO should be registered as a device
18173                // admin on some user too. (Original bug for this: b/17657954)
18174                if (packageName.equals(deviceOwnerPackageName)) {
18175                    return true;
18176                }
18177                // Does it contain a device admin for any user?
18178                int[] users;
18179                if (userId == UserHandle.USER_ALL) {
18180                    users = sUserManager.getUserIds();
18181                } else {
18182                    users = new int[]{userId};
18183                }
18184                for (int i = 0; i < users.length; ++i) {
18185                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18186                        return true;
18187                    }
18188                }
18189            }
18190        } catch (RemoteException e) {
18191        }
18192        return false;
18193    }
18194
18195    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18196        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18197    }
18198
18199    /**
18200     *  This method is an internal method that could be get invoked either
18201     *  to delete an installed package or to clean up a failed installation.
18202     *  After deleting an installed package, a broadcast is sent to notify any
18203     *  listeners that the package has been removed. For cleaning up a failed
18204     *  installation, the broadcast is not necessary since the package's
18205     *  installation wouldn't have sent the initial broadcast either
18206     *  The key steps in deleting a package are
18207     *  deleting the package information in internal structures like mPackages,
18208     *  deleting the packages base directories through installd
18209     *  updating mSettings to reflect current status
18210     *  persisting settings for later use
18211     *  sending a broadcast if necessary
18212     */
18213    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18214        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18215        final boolean res;
18216
18217        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18218                ? UserHandle.USER_ALL : userId;
18219
18220        if (isPackageDeviceAdmin(packageName, removeUser)) {
18221            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18222            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18223        }
18224
18225        PackageSetting uninstalledPs = null;
18226        PackageParser.Package pkg = null;
18227
18228        // for the uninstall-updates case and restricted profiles, remember the per-
18229        // user handle installed state
18230        int[] allUsers;
18231        synchronized (mPackages) {
18232            uninstalledPs = mSettings.mPackages.get(packageName);
18233            if (uninstalledPs == null) {
18234                Slog.w(TAG, "Not removing non-existent package " + packageName);
18235                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18236            }
18237
18238            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18239                    && uninstalledPs.versionCode != versionCode) {
18240                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18241                        + uninstalledPs.versionCode + " != " + versionCode);
18242                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18243            }
18244
18245            // Static shared libs can be declared by any package, so let us not
18246            // allow removing a package if it provides a lib others depend on.
18247            pkg = mPackages.get(packageName);
18248
18249            allUsers = sUserManager.getUserIds();
18250
18251            if (pkg != null && pkg.staticSharedLibName != null) {
18252                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18253                        pkg.staticSharedLibVersion);
18254                if (libEntry != null) {
18255                    for (int currUserId : allUsers) {
18256                        if (userId != UserHandle.USER_ALL && userId != currUserId) {
18257                            continue;
18258                        }
18259                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18260                                libEntry.info, 0, currUserId);
18261                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18262                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18263                                    + " hosting lib " + libEntry.info.getName() + " version "
18264                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18265                                    + " for user " + currUserId);
18266                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18267                        }
18268                    }
18269                }
18270            }
18271
18272            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18273        }
18274
18275        final int freezeUser;
18276        if (isUpdatedSystemApp(uninstalledPs)
18277                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18278            // We're downgrading a system app, which will apply to all users, so
18279            // freeze them all during the downgrade
18280            freezeUser = UserHandle.USER_ALL;
18281        } else {
18282            freezeUser = removeUser;
18283        }
18284
18285        synchronized (mInstallLock) {
18286            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18287            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18288                    deleteFlags, "deletePackageX")) {
18289                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18290                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18291            }
18292            synchronized (mPackages) {
18293                if (res) {
18294                    if (pkg != null) {
18295                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18296                    }
18297                    updateSequenceNumberLP(packageName, info.removedUsers);
18298                    updateInstantAppInstallerLocked(packageName);
18299                }
18300            }
18301        }
18302
18303        if (res) {
18304            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18305            info.sendPackageRemovedBroadcasts(killApp);
18306            info.sendSystemPackageUpdatedBroadcasts();
18307            info.sendSystemPackageAppearedBroadcasts();
18308        }
18309        // Force a gc here.
18310        Runtime.getRuntime().gc();
18311        // Delete the resources here after sending the broadcast to let
18312        // other processes clean up before deleting resources.
18313        if (info.args != null) {
18314            synchronized (mInstallLock) {
18315                info.args.doPostDeleteLI(true);
18316            }
18317        }
18318
18319        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18320    }
18321
18322    static class PackageRemovedInfo {
18323        final PackageSender packageSender;
18324        String removedPackage;
18325        String installerPackageName;
18326        int uid = -1;
18327        int removedAppId = -1;
18328        int[] origUsers;
18329        int[] removedUsers = null;
18330        int[] broadcastUsers = null;
18331        SparseArray<Integer> installReasons;
18332        boolean isRemovedPackageSystemUpdate = false;
18333        boolean isUpdate;
18334        boolean dataRemoved;
18335        boolean removedForAllUsers;
18336        boolean isStaticSharedLib;
18337        // Clean up resources deleted packages.
18338        InstallArgs args = null;
18339        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18340        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18341
18342        PackageRemovedInfo(PackageSender packageSender) {
18343            this.packageSender = packageSender;
18344        }
18345
18346        void sendPackageRemovedBroadcasts(boolean killApp) {
18347            sendPackageRemovedBroadcastInternal(killApp);
18348            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18349            for (int i = 0; i < childCount; i++) {
18350                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18351                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18352            }
18353        }
18354
18355        void sendSystemPackageUpdatedBroadcasts() {
18356            if (isRemovedPackageSystemUpdate) {
18357                sendSystemPackageUpdatedBroadcastsInternal();
18358                final int childCount = (removedChildPackages != null)
18359                        ? removedChildPackages.size() : 0;
18360                for (int i = 0; i < childCount; i++) {
18361                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18362                    if (childInfo.isRemovedPackageSystemUpdate) {
18363                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18364                    }
18365                }
18366            }
18367        }
18368
18369        void sendSystemPackageAppearedBroadcasts() {
18370            final int packageCount = (appearedChildPackages != null)
18371                    ? appearedChildPackages.size() : 0;
18372            for (int i = 0; i < packageCount; i++) {
18373                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18374                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18375                    true, UserHandle.getAppId(installedInfo.uid),
18376                    installedInfo.newUsers);
18377            }
18378        }
18379
18380        private void sendSystemPackageUpdatedBroadcastsInternal() {
18381            Bundle extras = new Bundle(2);
18382            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18383            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18384            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18385                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18386            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18387                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18388            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18389                null, null, 0, removedPackage, null, null);
18390            if (installerPackageName != null) {
18391                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18392                        removedPackage, extras, 0 /*flags*/,
18393                        installerPackageName, null, null);
18394                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18395                        removedPackage, extras, 0 /*flags*/,
18396                        installerPackageName, null, null);
18397            }
18398        }
18399
18400        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18401            // Don't send static shared library removal broadcasts as these
18402            // libs are visible only the the apps that depend on them an one
18403            // cannot remove the library if it has a dependency.
18404            if (isStaticSharedLib) {
18405                return;
18406            }
18407            Bundle extras = new Bundle(2);
18408            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18409            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18410            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18411            if (isUpdate || isRemovedPackageSystemUpdate) {
18412                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18413            }
18414            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18415            if (removedPackage != null) {
18416                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18417                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
18418                if (installerPackageName != null) {
18419                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18420                            removedPackage, extras, 0 /*flags*/,
18421                            installerPackageName, null, broadcastUsers);
18422                }
18423                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18424                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18425                        removedPackage, extras,
18426                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18427                        null, null, broadcastUsers);
18428                }
18429            }
18430            if (removedAppId >= 0) {
18431                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
18432                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
18433            }
18434        }
18435
18436        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18437            removedUsers = userIds;
18438            if (removedUsers == null) {
18439                broadcastUsers = null;
18440                return;
18441            }
18442
18443            broadcastUsers = EMPTY_INT_ARRAY;
18444            for (int i = userIds.length - 1; i >= 0; --i) {
18445                final int userId = userIds[i];
18446                if (deletedPackageSetting.getInstantApp(userId)) {
18447                    continue;
18448                }
18449                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18450            }
18451        }
18452    }
18453
18454    /*
18455     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18456     * flag is not set, the data directory is removed as well.
18457     * make sure this flag is set for partially installed apps. If not its meaningless to
18458     * delete a partially installed application.
18459     */
18460    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18461            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18462        String packageName = ps.name;
18463        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18464        // Retrieve object to delete permissions for shared user later on
18465        final PackageParser.Package deletedPkg;
18466        final PackageSetting deletedPs;
18467        // reader
18468        synchronized (mPackages) {
18469            deletedPkg = mPackages.get(packageName);
18470            deletedPs = mSettings.mPackages.get(packageName);
18471            if (outInfo != null) {
18472                outInfo.removedPackage = packageName;
18473                outInfo.installerPackageName = ps.installerPackageName;
18474                outInfo.isStaticSharedLib = deletedPkg != null
18475                        && deletedPkg.staticSharedLibName != null;
18476                outInfo.populateUsers(deletedPs == null ? null
18477                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18478            }
18479        }
18480
18481        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
18482
18483        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18484            final PackageParser.Package resolvedPkg;
18485            if (deletedPkg != null) {
18486                resolvedPkg = deletedPkg;
18487            } else {
18488                // We don't have a parsed package when it lives on an ejected
18489                // adopted storage device, so fake something together
18490                resolvedPkg = new PackageParser.Package(ps.name);
18491                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18492            }
18493            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18494                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18495            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18496            if (outInfo != null) {
18497                outInfo.dataRemoved = true;
18498            }
18499            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18500        }
18501
18502        int removedAppId = -1;
18503
18504        // writer
18505        synchronized (mPackages) {
18506            boolean installedStateChanged = false;
18507            if (deletedPs != null) {
18508                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18509                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18510                    clearDefaultBrowserIfNeeded(packageName);
18511                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18512                    removedAppId = mSettings.removePackageLPw(packageName);
18513                    if (outInfo != null) {
18514                        outInfo.removedAppId = removedAppId;
18515                    }
18516                    updatePermissionsLPw(deletedPs.name, null, 0);
18517                    if (deletedPs.sharedUser != null) {
18518                        // Remove permissions associated with package. Since runtime
18519                        // permissions are per user we have to kill the removed package
18520                        // or packages running under the shared user of the removed
18521                        // package if revoking the permissions requested only by the removed
18522                        // package is successful and this causes a change in gids.
18523                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18524                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18525                                    userId);
18526                            if (userIdToKill == UserHandle.USER_ALL
18527                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18528                                // If gids changed for this user, kill all affected packages.
18529                                mHandler.post(new Runnable() {
18530                                    @Override
18531                                    public void run() {
18532                                        // This has to happen with no lock held.
18533                                        killApplication(deletedPs.name, deletedPs.appId,
18534                                                KILL_APP_REASON_GIDS_CHANGED);
18535                                    }
18536                                });
18537                                break;
18538                            }
18539                        }
18540                    }
18541                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18542                }
18543                // make sure to preserve per-user disabled state if this removal was just
18544                // a downgrade of a system app to the factory package
18545                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18546                    if (DEBUG_REMOVE) {
18547                        Slog.d(TAG, "Propagating install state across downgrade");
18548                    }
18549                    for (int userId : allUserHandles) {
18550                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18551                        if (DEBUG_REMOVE) {
18552                            Slog.d(TAG, "    user " + userId + " => " + installed);
18553                        }
18554                        if (installed != ps.getInstalled(userId)) {
18555                            installedStateChanged = true;
18556                        }
18557                        ps.setInstalled(installed, userId);
18558                    }
18559                }
18560            }
18561            // can downgrade to reader
18562            if (writeSettings) {
18563                // Save settings now
18564                mSettings.writeLPr();
18565            }
18566            if (installedStateChanged) {
18567                mSettings.writeKernelMappingLPr(ps);
18568            }
18569        }
18570        if (removedAppId != -1) {
18571            // A user ID was deleted here. Go through all users and remove it
18572            // from KeyStore.
18573            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18574        }
18575    }
18576
18577    static boolean locationIsPrivileged(File path) {
18578        try {
18579            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18580                    .getCanonicalPath();
18581            return path.getCanonicalPath().startsWith(privilegedAppDir);
18582        } catch (IOException e) {
18583            Slog.e(TAG, "Unable to access code path " + path);
18584        }
18585        return false;
18586    }
18587
18588    /*
18589     * Tries to delete system package.
18590     */
18591    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18592            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18593            boolean writeSettings) {
18594        if (deletedPs.parentPackageName != null) {
18595            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18596            return false;
18597        }
18598
18599        final boolean applyUserRestrictions
18600                = (allUserHandles != null) && (outInfo.origUsers != null);
18601        final PackageSetting disabledPs;
18602        // Confirm if the system package has been updated
18603        // An updated system app can be deleted. This will also have to restore
18604        // the system pkg from system partition
18605        // reader
18606        synchronized (mPackages) {
18607            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18608        }
18609
18610        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18611                + " disabledPs=" + disabledPs);
18612
18613        if (disabledPs == null) {
18614            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18615            return false;
18616        } else if (DEBUG_REMOVE) {
18617            Slog.d(TAG, "Deleting system pkg from data partition");
18618        }
18619
18620        if (DEBUG_REMOVE) {
18621            if (applyUserRestrictions) {
18622                Slog.d(TAG, "Remembering install states:");
18623                for (int userId : allUserHandles) {
18624                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18625                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18626                }
18627            }
18628        }
18629
18630        // Delete the updated package
18631        outInfo.isRemovedPackageSystemUpdate = true;
18632        if (outInfo.removedChildPackages != null) {
18633            final int childCount = (deletedPs.childPackageNames != null)
18634                    ? deletedPs.childPackageNames.size() : 0;
18635            for (int i = 0; i < childCount; i++) {
18636                String childPackageName = deletedPs.childPackageNames.get(i);
18637                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18638                        .contains(childPackageName)) {
18639                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18640                            childPackageName);
18641                    if (childInfo != null) {
18642                        childInfo.isRemovedPackageSystemUpdate = true;
18643                    }
18644                }
18645            }
18646        }
18647
18648        if (disabledPs.versionCode < deletedPs.versionCode) {
18649            // Delete data for downgrades
18650            flags &= ~PackageManager.DELETE_KEEP_DATA;
18651        } else {
18652            // Preserve data by setting flag
18653            flags |= PackageManager.DELETE_KEEP_DATA;
18654        }
18655
18656        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18657                outInfo, writeSettings, disabledPs.pkg);
18658        if (!ret) {
18659            return false;
18660        }
18661
18662        // writer
18663        synchronized (mPackages) {
18664            // Reinstate the old system package
18665            enableSystemPackageLPw(disabledPs.pkg);
18666            // Remove any native libraries from the upgraded package.
18667            removeNativeBinariesLI(deletedPs);
18668        }
18669
18670        // Install the system package
18671        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18672        int parseFlags = mDefParseFlags
18673                | PackageParser.PARSE_MUST_BE_APK
18674                | PackageParser.PARSE_IS_SYSTEM
18675                | PackageParser.PARSE_IS_SYSTEM_DIR;
18676        if (locationIsPrivileged(disabledPs.codePath)) {
18677            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18678        }
18679
18680        final PackageParser.Package newPkg;
18681        try {
18682            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18683                0 /* currentTime */, null);
18684        } catch (PackageManagerException e) {
18685            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18686                    + e.getMessage());
18687            return false;
18688        }
18689
18690        try {
18691            // update shared libraries for the newly re-installed system package
18692            updateSharedLibrariesLPr(newPkg, null);
18693        } catch (PackageManagerException e) {
18694            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18695        }
18696
18697        prepareAppDataAfterInstallLIF(newPkg);
18698
18699        // writer
18700        synchronized (mPackages) {
18701            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18702
18703            // Propagate the permissions state as we do not want to drop on the floor
18704            // runtime permissions. The update permissions method below will take
18705            // care of removing obsolete permissions and grant install permissions.
18706            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18707            updatePermissionsLPw(newPkg.packageName, newPkg,
18708                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18709
18710            if (applyUserRestrictions) {
18711                boolean installedStateChanged = false;
18712                if (DEBUG_REMOVE) {
18713                    Slog.d(TAG, "Propagating install state across reinstall");
18714                }
18715                for (int userId : allUserHandles) {
18716                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18717                    if (DEBUG_REMOVE) {
18718                        Slog.d(TAG, "    user " + userId + " => " + installed);
18719                    }
18720                    if (installed != ps.getInstalled(userId)) {
18721                        installedStateChanged = true;
18722                    }
18723                    ps.setInstalled(installed, userId);
18724
18725                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18726                }
18727                // Regardless of writeSettings we need to ensure that this restriction
18728                // state propagation is persisted
18729                mSettings.writeAllUsersPackageRestrictionsLPr();
18730                if (installedStateChanged) {
18731                    mSettings.writeKernelMappingLPr(ps);
18732                }
18733            }
18734            // can downgrade to reader here
18735            if (writeSettings) {
18736                mSettings.writeLPr();
18737            }
18738        }
18739        return true;
18740    }
18741
18742    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18743            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18744            PackageRemovedInfo outInfo, boolean writeSettings,
18745            PackageParser.Package replacingPackage) {
18746        synchronized (mPackages) {
18747            if (outInfo != null) {
18748                outInfo.uid = ps.appId;
18749            }
18750
18751            if (outInfo != null && outInfo.removedChildPackages != null) {
18752                final int childCount = (ps.childPackageNames != null)
18753                        ? ps.childPackageNames.size() : 0;
18754                for (int i = 0; i < childCount; i++) {
18755                    String childPackageName = ps.childPackageNames.get(i);
18756                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18757                    if (childPs == null) {
18758                        return false;
18759                    }
18760                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18761                            childPackageName);
18762                    if (childInfo != null) {
18763                        childInfo.uid = childPs.appId;
18764                    }
18765                }
18766            }
18767        }
18768
18769        // Delete package data from internal structures and also remove data if flag is set
18770        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18771
18772        // Delete the child packages data
18773        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18774        for (int i = 0; i < childCount; i++) {
18775            PackageSetting childPs;
18776            synchronized (mPackages) {
18777                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18778            }
18779            if (childPs != null) {
18780                PackageRemovedInfo childOutInfo = (outInfo != null
18781                        && outInfo.removedChildPackages != null)
18782                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18783                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18784                        && (replacingPackage != null
18785                        && !replacingPackage.hasChildPackage(childPs.name))
18786                        ? flags & ~DELETE_KEEP_DATA : flags;
18787                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18788                        deleteFlags, writeSettings);
18789            }
18790        }
18791
18792        // Delete application code and resources only for parent packages
18793        if (ps.parentPackageName == null) {
18794            if (deleteCodeAndResources && (outInfo != null)) {
18795                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18796                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18797                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18798            }
18799        }
18800
18801        return true;
18802    }
18803
18804    @Override
18805    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18806            int userId) {
18807        mContext.enforceCallingOrSelfPermission(
18808                android.Manifest.permission.DELETE_PACKAGES, null);
18809        synchronized (mPackages) {
18810            // Cannot block uninstall of static shared libs as they are
18811            // considered a part of the using app (emulating static linking).
18812            // Also static libs are installed always on internal storage.
18813            PackageParser.Package pkg = mPackages.get(packageName);
18814            if (pkg != null && pkg.staticSharedLibName != null) {
18815                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18816                        + " providing static shared library: " + pkg.staticSharedLibName);
18817                return false;
18818            }
18819            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18820            mSettings.writePackageRestrictionsLPr(userId);
18821        }
18822        return true;
18823    }
18824
18825    @Override
18826    public boolean getBlockUninstallForUser(String packageName, int userId) {
18827        synchronized (mPackages) {
18828            return mSettings.getBlockUninstallLPr(userId, packageName);
18829        }
18830    }
18831
18832    @Override
18833    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18834        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18835        synchronized (mPackages) {
18836            PackageSetting ps = mSettings.mPackages.get(packageName);
18837            if (ps == null) {
18838                Log.w(TAG, "Package doesn't exist: " + packageName);
18839                return false;
18840            }
18841            if (systemUserApp) {
18842                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18843            } else {
18844                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18845            }
18846            mSettings.writeLPr();
18847        }
18848        return true;
18849    }
18850
18851    /*
18852     * This method handles package deletion in general
18853     */
18854    private boolean deletePackageLIF(String packageName, UserHandle user,
18855            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18856            PackageRemovedInfo outInfo, boolean writeSettings,
18857            PackageParser.Package replacingPackage) {
18858        if (packageName == null) {
18859            Slog.w(TAG, "Attempt to delete null packageName.");
18860            return false;
18861        }
18862
18863        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18864
18865        PackageSetting ps;
18866        synchronized (mPackages) {
18867            ps = mSettings.mPackages.get(packageName);
18868            if (ps == null) {
18869                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18870                return false;
18871            }
18872
18873            if (ps.parentPackageName != null && (!isSystemApp(ps)
18874                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18875                if (DEBUG_REMOVE) {
18876                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18877                            + ((user == null) ? UserHandle.USER_ALL : user));
18878                }
18879                final int removedUserId = (user != null) ? user.getIdentifier()
18880                        : UserHandle.USER_ALL;
18881                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18882                    return false;
18883                }
18884                markPackageUninstalledForUserLPw(ps, user);
18885                scheduleWritePackageRestrictionsLocked(user);
18886                return true;
18887            }
18888        }
18889
18890        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18891                && user.getIdentifier() != UserHandle.USER_ALL)) {
18892            // The caller is asking that the package only be deleted for a single
18893            // user.  To do this, we just mark its uninstalled state and delete
18894            // its data. If this is a system app, we only allow this to happen if
18895            // they have set the special DELETE_SYSTEM_APP which requests different
18896            // semantics than normal for uninstalling system apps.
18897            markPackageUninstalledForUserLPw(ps, user);
18898
18899            if (!isSystemApp(ps)) {
18900                // Do not uninstall the APK if an app should be cached
18901                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18902                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18903                    // Other user still have this package installed, so all
18904                    // we need to do is clear this user's data and save that
18905                    // it is uninstalled.
18906                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18907                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18908                        return false;
18909                    }
18910                    scheduleWritePackageRestrictionsLocked(user);
18911                    return true;
18912                } else {
18913                    // We need to set it back to 'installed' so the uninstall
18914                    // broadcasts will be sent correctly.
18915                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18916                    ps.setInstalled(true, user.getIdentifier());
18917                    mSettings.writeKernelMappingLPr(ps);
18918                }
18919            } else {
18920                // This is a system app, so we assume that the
18921                // other users still have this package installed, so all
18922                // we need to do is clear this user's data and save that
18923                // it is uninstalled.
18924                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18925                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18926                    return false;
18927                }
18928                scheduleWritePackageRestrictionsLocked(user);
18929                return true;
18930            }
18931        }
18932
18933        // If we are deleting a composite package for all users, keep track
18934        // of result for each child.
18935        if (ps.childPackageNames != null && outInfo != null) {
18936            synchronized (mPackages) {
18937                final int childCount = ps.childPackageNames.size();
18938                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18939                for (int i = 0; i < childCount; i++) {
18940                    String childPackageName = ps.childPackageNames.get(i);
18941                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18942                    childInfo.removedPackage = childPackageName;
18943                    childInfo.installerPackageName = ps.installerPackageName;
18944                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18945                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18946                    if (childPs != null) {
18947                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18948                    }
18949                }
18950            }
18951        }
18952
18953        boolean ret = false;
18954        if (isSystemApp(ps)) {
18955            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18956            // When an updated system application is deleted we delete the existing resources
18957            // as well and fall back to existing code in system partition
18958            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18959        } else {
18960            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18961            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18962                    outInfo, writeSettings, replacingPackage);
18963        }
18964
18965        // Take a note whether we deleted the package for all users
18966        if (outInfo != null) {
18967            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18968            if (outInfo.removedChildPackages != null) {
18969                synchronized (mPackages) {
18970                    final int childCount = outInfo.removedChildPackages.size();
18971                    for (int i = 0; i < childCount; i++) {
18972                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18973                        if (childInfo != null) {
18974                            childInfo.removedForAllUsers = mPackages.get(
18975                                    childInfo.removedPackage) == null;
18976                        }
18977                    }
18978                }
18979            }
18980            // If we uninstalled an update to a system app there may be some
18981            // child packages that appeared as they are declared in the system
18982            // app but were not declared in the update.
18983            if (isSystemApp(ps)) {
18984                synchronized (mPackages) {
18985                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18986                    final int childCount = (updatedPs.childPackageNames != null)
18987                            ? updatedPs.childPackageNames.size() : 0;
18988                    for (int i = 0; i < childCount; i++) {
18989                        String childPackageName = updatedPs.childPackageNames.get(i);
18990                        if (outInfo.removedChildPackages == null
18991                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18992                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18993                            if (childPs == null) {
18994                                continue;
18995                            }
18996                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18997                            installRes.name = childPackageName;
18998                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18999                            installRes.pkg = mPackages.get(childPackageName);
19000                            installRes.uid = childPs.pkg.applicationInfo.uid;
19001                            if (outInfo.appearedChildPackages == null) {
19002                                outInfo.appearedChildPackages = new ArrayMap<>();
19003                            }
19004                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19005                        }
19006                    }
19007                }
19008            }
19009        }
19010
19011        return ret;
19012    }
19013
19014    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19015        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19016                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19017        for (int nextUserId : userIds) {
19018            if (DEBUG_REMOVE) {
19019                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19020            }
19021            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19022                    false /*installed*/,
19023                    true /*stopped*/,
19024                    true /*notLaunched*/,
19025                    false /*hidden*/,
19026                    false /*suspended*/,
19027                    false /*instantApp*/,
19028                    null /*lastDisableAppCaller*/,
19029                    null /*enabledComponents*/,
19030                    null /*disabledComponents*/,
19031                    ps.readUserState(nextUserId).domainVerificationStatus,
19032                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19033        }
19034        mSettings.writeKernelMappingLPr(ps);
19035    }
19036
19037    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19038            PackageRemovedInfo outInfo) {
19039        final PackageParser.Package pkg;
19040        synchronized (mPackages) {
19041            pkg = mPackages.get(ps.name);
19042        }
19043
19044        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19045                : new int[] {userId};
19046        for (int nextUserId : userIds) {
19047            if (DEBUG_REMOVE) {
19048                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19049                        + nextUserId);
19050            }
19051
19052            destroyAppDataLIF(pkg, userId,
19053                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19054            destroyAppProfilesLIF(pkg, userId);
19055            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19056            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19057            schedulePackageCleaning(ps.name, nextUserId, false);
19058            synchronized (mPackages) {
19059                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19060                    scheduleWritePackageRestrictionsLocked(nextUserId);
19061                }
19062                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19063            }
19064        }
19065
19066        if (outInfo != null) {
19067            outInfo.removedPackage = ps.name;
19068            outInfo.installerPackageName = ps.installerPackageName;
19069            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19070            outInfo.removedAppId = ps.appId;
19071            outInfo.removedUsers = userIds;
19072            outInfo.broadcastUsers = userIds;
19073        }
19074
19075        return true;
19076    }
19077
19078    private final class ClearStorageConnection implements ServiceConnection {
19079        IMediaContainerService mContainerService;
19080
19081        @Override
19082        public void onServiceConnected(ComponentName name, IBinder service) {
19083            synchronized (this) {
19084                mContainerService = IMediaContainerService.Stub
19085                        .asInterface(Binder.allowBlocking(service));
19086                notifyAll();
19087            }
19088        }
19089
19090        @Override
19091        public void onServiceDisconnected(ComponentName name) {
19092        }
19093    }
19094
19095    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19096        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19097
19098        final boolean mounted;
19099        if (Environment.isExternalStorageEmulated()) {
19100            mounted = true;
19101        } else {
19102            final String status = Environment.getExternalStorageState();
19103
19104            mounted = status.equals(Environment.MEDIA_MOUNTED)
19105                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19106        }
19107
19108        if (!mounted) {
19109            return;
19110        }
19111
19112        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19113        int[] users;
19114        if (userId == UserHandle.USER_ALL) {
19115            users = sUserManager.getUserIds();
19116        } else {
19117            users = new int[] { userId };
19118        }
19119        final ClearStorageConnection conn = new ClearStorageConnection();
19120        if (mContext.bindServiceAsUser(
19121                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19122            try {
19123                for (int curUser : users) {
19124                    long timeout = SystemClock.uptimeMillis() + 5000;
19125                    synchronized (conn) {
19126                        long now;
19127                        while (conn.mContainerService == null &&
19128                                (now = SystemClock.uptimeMillis()) < timeout) {
19129                            try {
19130                                conn.wait(timeout - now);
19131                            } catch (InterruptedException e) {
19132                            }
19133                        }
19134                    }
19135                    if (conn.mContainerService == null) {
19136                        return;
19137                    }
19138
19139                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19140                    clearDirectory(conn.mContainerService,
19141                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19142                    if (allData) {
19143                        clearDirectory(conn.mContainerService,
19144                                userEnv.buildExternalStorageAppDataDirs(packageName));
19145                        clearDirectory(conn.mContainerService,
19146                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19147                    }
19148                }
19149            } finally {
19150                mContext.unbindService(conn);
19151            }
19152        }
19153    }
19154
19155    @Override
19156    public void clearApplicationProfileData(String packageName) {
19157        enforceSystemOrRoot("Only the system can clear all profile data");
19158
19159        final PackageParser.Package pkg;
19160        synchronized (mPackages) {
19161            pkg = mPackages.get(packageName);
19162        }
19163
19164        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19165            synchronized (mInstallLock) {
19166                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19167            }
19168        }
19169    }
19170
19171    @Override
19172    public void clearApplicationUserData(final String packageName,
19173            final IPackageDataObserver observer, final int userId) {
19174        mContext.enforceCallingOrSelfPermission(
19175                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19176
19177        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19178                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19179
19180        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19181            throw new SecurityException("Cannot clear data for a protected package: "
19182                    + packageName);
19183        }
19184        // Queue up an async operation since the package deletion may take a little while.
19185        mHandler.post(new Runnable() {
19186            public void run() {
19187                mHandler.removeCallbacks(this);
19188                final boolean succeeded;
19189                try (PackageFreezer freezer = freezePackage(packageName,
19190                        "clearApplicationUserData")) {
19191                    synchronized (mInstallLock) {
19192                        succeeded = clearApplicationUserDataLIF(packageName, userId);
19193                    }
19194                    clearExternalStorageDataSync(packageName, userId, true);
19195                    synchronized (mPackages) {
19196                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19197                                packageName, userId);
19198                    }
19199                }
19200                if (succeeded) {
19201                    // invoke DeviceStorageMonitor's update method to clear any notifications
19202                    DeviceStorageMonitorInternal dsm = LocalServices
19203                            .getService(DeviceStorageMonitorInternal.class);
19204                    if (dsm != null) {
19205                        dsm.checkMemory();
19206                    }
19207                }
19208                if(observer != null) {
19209                    try {
19210                        observer.onRemoveCompleted(packageName, succeeded);
19211                    } catch (RemoteException e) {
19212                        Log.i(TAG, "Observer no longer exists.");
19213                    }
19214                } //end if observer
19215            } //end run
19216        });
19217    }
19218
19219    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19220        if (packageName == null) {
19221            Slog.w(TAG, "Attempt to delete null packageName.");
19222            return false;
19223        }
19224
19225        // Try finding details about the requested package
19226        PackageParser.Package pkg;
19227        synchronized (mPackages) {
19228            pkg = mPackages.get(packageName);
19229            if (pkg == null) {
19230                final PackageSetting ps = mSettings.mPackages.get(packageName);
19231                if (ps != null) {
19232                    pkg = ps.pkg;
19233                }
19234            }
19235
19236            if (pkg == null) {
19237                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19238                return false;
19239            }
19240
19241            PackageSetting ps = (PackageSetting) pkg.mExtras;
19242            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19243        }
19244
19245        clearAppDataLIF(pkg, userId,
19246                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19247
19248        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19249        removeKeystoreDataIfNeeded(userId, appId);
19250
19251        UserManagerInternal umInternal = getUserManagerInternal();
19252        final int flags;
19253        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19254            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19255        } else if (umInternal.isUserRunning(userId)) {
19256            flags = StorageManager.FLAG_STORAGE_DE;
19257        } else {
19258            flags = 0;
19259        }
19260        prepareAppDataContentsLIF(pkg, userId, flags);
19261
19262        return true;
19263    }
19264
19265    /**
19266     * Reverts user permission state changes (permissions and flags) in
19267     * all packages for a given user.
19268     *
19269     * @param userId The device user for which to do a reset.
19270     */
19271    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19272        final int packageCount = mPackages.size();
19273        for (int i = 0; i < packageCount; i++) {
19274            PackageParser.Package pkg = mPackages.valueAt(i);
19275            PackageSetting ps = (PackageSetting) pkg.mExtras;
19276            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19277        }
19278    }
19279
19280    private void resetNetworkPolicies(int userId) {
19281        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19282    }
19283
19284    /**
19285     * Reverts user permission state changes (permissions and flags).
19286     *
19287     * @param ps The package for which to reset.
19288     * @param userId The device user for which to do a reset.
19289     */
19290    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19291            final PackageSetting ps, final int userId) {
19292        if (ps.pkg == null) {
19293            return;
19294        }
19295
19296        // These are flags that can change base on user actions.
19297        final int userSettableMask = FLAG_PERMISSION_USER_SET
19298                | FLAG_PERMISSION_USER_FIXED
19299                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19300                | FLAG_PERMISSION_REVIEW_REQUIRED;
19301
19302        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19303                | FLAG_PERMISSION_POLICY_FIXED;
19304
19305        boolean writeInstallPermissions = false;
19306        boolean writeRuntimePermissions = false;
19307
19308        final int permissionCount = ps.pkg.requestedPermissions.size();
19309        for (int i = 0; i < permissionCount; i++) {
19310            String permission = ps.pkg.requestedPermissions.get(i);
19311
19312            BasePermission bp = mSettings.mPermissions.get(permission);
19313            if (bp == null) {
19314                continue;
19315            }
19316
19317            // If shared user we just reset the state to which only this app contributed.
19318            if (ps.sharedUser != null) {
19319                boolean used = false;
19320                final int packageCount = ps.sharedUser.packages.size();
19321                for (int j = 0; j < packageCount; j++) {
19322                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19323                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19324                            && pkg.pkg.requestedPermissions.contains(permission)) {
19325                        used = true;
19326                        break;
19327                    }
19328                }
19329                if (used) {
19330                    continue;
19331                }
19332            }
19333
19334            PermissionsState permissionsState = ps.getPermissionsState();
19335
19336            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
19337
19338            // Always clear the user settable flags.
19339            final boolean hasInstallState = permissionsState.getInstallPermissionState(
19340                    bp.name) != null;
19341            // If permission review is enabled and this is a legacy app, mark the
19342            // permission as requiring a review as this is the initial state.
19343            int flags = 0;
19344            if (mPermissionReviewRequired
19345                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19346                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19347            }
19348            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19349                if (hasInstallState) {
19350                    writeInstallPermissions = true;
19351                } else {
19352                    writeRuntimePermissions = true;
19353                }
19354            }
19355
19356            // Below is only runtime permission handling.
19357            if (!bp.isRuntime()) {
19358                continue;
19359            }
19360
19361            // Never clobber system or policy.
19362            if ((oldFlags & policyOrSystemFlags) != 0) {
19363                continue;
19364            }
19365
19366            // If this permission was granted by default, make sure it is.
19367            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19368                if (permissionsState.grantRuntimePermission(bp, userId)
19369                        != PERMISSION_OPERATION_FAILURE) {
19370                    writeRuntimePermissions = true;
19371                }
19372            // If permission review is enabled the permissions for a legacy apps
19373            // are represented as constantly granted runtime ones, so don't revoke.
19374            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19375                // Otherwise, reset the permission.
19376                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19377                switch (revokeResult) {
19378                    case PERMISSION_OPERATION_SUCCESS:
19379                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19380                        writeRuntimePermissions = true;
19381                        final int appId = ps.appId;
19382                        mHandler.post(new Runnable() {
19383                            @Override
19384                            public void run() {
19385                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19386                            }
19387                        });
19388                    } break;
19389                }
19390            }
19391        }
19392
19393        // Synchronously write as we are taking permissions away.
19394        if (writeRuntimePermissions) {
19395            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19396        }
19397
19398        // Synchronously write as we are taking permissions away.
19399        if (writeInstallPermissions) {
19400            mSettings.writeLPr();
19401        }
19402    }
19403
19404    /**
19405     * Remove entries from the keystore daemon. Will only remove it if the
19406     * {@code appId} is valid.
19407     */
19408    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19409        if (appId < 0) {
19410            return;
19411        }
19412
19413        final KeyStore keyStore = KeyStore.getInstance();
19414        if (keyStore != null) {
19415            if (userId == UserHandle.USER_ALL) {
19416                for (final int individual : sUserManager.getUserIds()) {
19417                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19418                }
19419            } else {
19420                keyStore.clearUid(UserHandle.getUid(userId, appId));
19421            }
19422        } else {
19423            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19424        }
19425    }
19426
19427    @Override
19428    public void deleteApplicationCacheFiles(final String packageName,
19429            final IPackageDataObserver observer) {
19430        final int userId = UserHandle.getCallingUserId();
19431        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19432    }
19433
19434    @Override
19435    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19436            final IPackageDataObserver observer) {
19437        mContext.enforceCallingOrSelfPermission(
19438                android.Manifest.permission.DELETE_CACHE_FILES, null);
19439        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19440                /* requireFullPermission= */ true, /* checkShell= */ false,
19441                "delete application cache files");
19442
19443        final PackageParser.Package pkg;
19444        synchronized (mPackages) {
19445            pkg = mPackages.get(packageName);
19446        }
19447
19448        // Queue up an async operation since the package deletion may take a little while.
19449        mHandler.post(new Runnable() {
19450            public void run() {
19451                synchronized (mInstallLock) {
19452                    final int flags = StorageManager.FLAG_STORAGE_DE
19453                            | StorageManager.FLAG_STORAGE_CE;
19454                    // We're only clearing cache files, so we don't care if the
19455                    // app is unfrozen and still able to run
19456                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19457                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19458                }
19459                clearExternalStorageDataSync(packageName, userId, false);
19460                if (observer != null) {
19461                    try {
19462                        observer.onRemoveCompleted(packageName, true);
19463                    } catch (RemoteException e) {
19464                        Log.i(TAG, "Observer no longer exists.");
19465                    }
19466                }
19467            }
19468        });
19469    }
19470
19471    @Override
19472    public void getPackageSizeInfo(final String packageName, int userHandle,
19473            final IPackageStatsObserver observer) {
19474        throw new UnsupportedOperationException(
19475                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19476    }
19477
19478    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19479        final PackageSetting ps;
19480        synchronized (mPackages) {
19481            ps = mSettings.mPackages.get(packageName);
19482            if (ps == null) {
19483                Slog.w(TAG, "Failed to find settings for " + packageName);
19484                return false;
19485            }
19486        }
19487
19488        final String[] packageNames = { packageName };
19489        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19490        final String[] codePaths = { ps.codePathString };
19491
19492        try {
19493            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19494                    ps.appId, ceDataInodes, codePaths, stats);
19495
19496            // For now, ignore code size of packages on system partition
19497            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19498                stats.codeSize = 0;
19499            }
19500
19501            // External clients expect these to be tracked separately
19502            stats.dataSize -= stats.cacheSize;
19503
19504        } catch (InstallerException e) {
19505            Slog.w(TAG, String.valueOf(e));
19506            return false;
19507        }
19508
19509        return true;
19510    }
19511
19512    private int getUidTargetSdkVersionLockedLPr(int uid) {
19513        Object obj = mSettings.getUserIdLPr(uid);
19514        if (obj instanceof SharedUserSetting) {
19515            final SharedUserSetting sus = (SharedUserSetting) obj;
19516            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19517            final Iterator<PackageSetting> it = sus.packages.iterator();
19518            while (it.hasNext()) {
19519                final PackageSetting ps = it.next();
19520                if (ps.pkg != null) {
19521                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19522                    if (v < vers) vers = v;
19523                }
19524            }
19525            return vers;
19526        } else if (obj instanceof PackageSetting) {
19527            final PackageSetting ps = (PackageSetting) obj;
19528            if (ps.pkg != null) {
19529                return ps.pkg.applicationInfo.targetSdkVersion;
19530            }
19531        }
19532        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19533    }
19534
19535    @Override
19536    public void addPreferredActivity(IntentFilter filter, int match,
19537            ComponentName[] set, ComponentName activity, int userId) {
19538        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19539                "Adding preferred");
19540    }
19541
19542    private void addPreferredActivityInternal(IntentFilter filter, int match,
19543            ComponentName[] set, ComponentName activity, boolean always, int userId,
19544            String opname) {
19545        // writer
19546        int callingUid = Binder.getCallingUid();
19547        enforceCrossUserPermission(callingUid, userId,
19548                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19549        if (filter.countActions() == 0) {
19550            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19551            return;
19552        }
19553        synchronized (mPackages) {
19554            if (mContext.checkCallingOrSelfPermission(
19555                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19556                    != PackageManager.PERMISSION_GRANTED) {
19557                if (getUidTargetSdkVersionLockedLPr(callingUid)
19558                        < Build.VERSION_CODES.FROYO) {
19559                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19560                            + callingUid);
19561                    return;
19562                }
19563                mContext.enforceCallingOrSelfPermission(
19564                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19565            }
19566
19567            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19568            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19569                    + userId + ":");
19570            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19571            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19572            scheduleWritePackageRestrictionsLocked(userId);
19573            postPreferredActivityChangedBroadcast(userId);
19574        }
19575    }
19576
19577    private void postPreferredActivityChangedBroadcast(int userId) {
19578        mHandler.post(() -> {
19579            final IActivityManager am = ActivityManager.getService();
19580            if (am == null) {
19581                return;
19582            }
19583
19584            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19585            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19586            try {
19587                am.broadcastIntent(null, intent, null, null,
19588                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19589                        null, false, false, userId);
19590            } catch (RemoteException e) {
19591            }
19592        });
19593    }
19594
19595    @Override
19596    public void replacePreferredActivity(IntentFilter filter, int match,
19597            ComponentName[] set, ComponentName activity, int userId) {
19598        if (filter.countActions() != 1) {
19599            throw new IllegalArgumentException(
19600                    "replacePreferredActivity expects filter to have only 1 action.");
19601        }
19602        if (filter.countDataAuthorities() != 0
19603                || filter.countDataPaths() != 0
19604                || filter.countDataSchemes() > 1
19605                || filter.countDataTypes() != 0) {
19606            throw new IllegalArgumentException(
19607                    "replacePreferredActivity expects filter to have no data authorities, " +
19608                    "paths, or types; and at most one scheme.");
19609        }
19610
19611        final int callingUid = Binder.getCallingUid();
19612        enforceCrossUserPermission(callingUid, userId,
19613                true /* requireFullPermission */, false /* checkShell */,
19614                "replace preferred activity");
19615        synchronized (mPackages) {
19616            if (mContext.checkCallingOrSelfPermission(
19617                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19618                    != PackageManager.PERMISSION_GRANTED) {
19619                if (getUidTargetSdkVersionLockedLPr(callingUid)
19620                        < Build.VERSION_CODES.FROYO) {
19621                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19622                            + Binder.getCallingUid());
19623                    return;
19624                }
19625                mContext.enforceCallingOrSelfPermission(
19626                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19627            }
19628
19629            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19630            if (pir != null) {
19631                // Get all of the existing entries that exactly match this filter.
19632                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19633                if (existing != null && existing.size() == 1) {
19634                    PreferredActivity cur = existing.get(0);
19635                    if (DEBUG_PREFERRED) {
19636                        Slog.i(TAG, "Checking replace of preferred:");
19637                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19638                        if (!cur.mPref.mAlways) {
19639                            Slog.i(TAG, "  -- CUR; not mAlways!");
19640                        } else {
19641                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19642                            Slog.i(TAG, "  -- CUR: mSet="
19643                                    + Arrays.toString(cur.mPref.mSetComponents));
19644                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19645                            Slog.i(TAG, "  -- NEW: mMatch="
19646                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19647                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19648                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19649                        }
19650                    }
19651                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19652                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19653                            && cur.mPref.sameSet(set)) {
19654                        // Setting the preferred activity to what it happens to be already
19655                        if (DEBUG_PREFERRED) {
19656                            Slog.i(TAG, "Replacing with same preferred activity "
19657                                    + cur.mPref.mShortComponent + " for user "
19658                                    + userId + ":");
19659                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19660                        }
19661                        return;
19662                    }
19663                }
19664
19665                if (existing != null) {
19666                    if (DEBUG_PREFERRED) {
19667                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19668                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19669                    }
19670                    for (int i = 0; i < existing.size(); i++) {
19671                        PreferredActivity pa = existing.get(i);
19672                        if (DEBUG_PREFERRED) {
19673                            Slog.i(TAG, "Removing existing preferred activity "
19674                                    + pa.mPref.mComponent + ":");
19675                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19676                        }
19677                        pir.removeFilter(pa);
19678                    }
19679                }
19680            }
19681            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19682                    "Replacing preferred");
19683        }
19684    }
19685
19686    @Override
19687    public void clearPackagePreferredActivities(String packageName) {
19688        final int callingUid = Binder.getCallingUid();
19689        if (getInstantAppPackageName(callingUid) != null) {
19690            return;
19691        }
19692        // writer
19693        synchronized (mPackages) {
19694            PackageParser.Package pkg = mPackages.get(packageName);
19695            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19696                if (mContext.checkCallingOrSelfPermission(
19697                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19698                        != PackageManager.PERMISSION_GRANTED) {
19699                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19700                            < Build.VERSION_CODES.FROYO) {
19701                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19702                                + callingUid);
19703                        return;
19704                    }
19705                    mContext.enforceCallingOrSelfPermission(
19706                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19707                }
19708            }
19709
19710            int user = UserHandle.getCallingUserId();
19711            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19712                scheduleWritePackageRestrictionsLocked(user);
19713            }
19714        }
19715    }
19716
19717    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19718    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19719        ArrayList<PreferredActivity> removed = null;
19720        boolean changed = false;
19721        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19722            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19723            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19724            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19725                continue;
19726            }
19727            Iterator<PreferredActivity> it = pir.filterIterator();
19728            while (it.hasNext()) {
19729                PreferredActivity pa = it.next();
19730                // Mark entry for removal only if it matches the package name
19731                // and the entry is of type "always".
19732                if (packageName == null ||
19733                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19734                                && pa.mPref.mAlways)) {
19735                    if (removed == null) {
19736                        removed = new ArrayList<PreferredActivity>();
19737                    }
19738                    removed.add(pa);
19739                }
19740            }
19741            if (removed != null) {
19742                for (int j=0; j<removed.size(); j++) {
19743                    PreferredActivity pa = removed.get(j);
19744                    pir.removeFilter(pa);
19745                }
19746                changed = true;
19747            }
19748        }
19749        if (changed) {
19750            postPreferredActivityChangedBroadcast(userId);
19751        }
19752        return changed;
19753    }
19754
19755    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19756    private void clearIntentFilterVerificationsLPw(int userId) {
19757        final int packageCount = mPackages.size();
19758        for (int i = 0; i < packageCount; i++) {
19759            PackageParser.Package pkg = mPackages.valueAt(i);
19760            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19761        }
19762    }
19763
19764    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19765    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19766        if (userId == UserHandle.USER_ALL) {
19767            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19768                    sUserManager.getUserIds())) {
19769                for (int oneUserId : sUserManager.getUserIds()) {
19770                    scheduleWritePackageRestrictionsLocked(oneUserId);
19771                }
19772            }
19773        } else {
19774            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19775                scheduleWritePackageRestrictionsLocked(userId);
19776            }
19777        }
19778    }
19779
19780    /** Clears state for all users, and touches intent filter verification policy */
19781    void clearDefaultBrowserIfNeeded(String packageName) {
19782        for (int oneUserId : sUserManager.getUserIds()) {
19783            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19784        }
19785    }
19786
19787    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19788        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19789        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19790            if (packageName.equals(defaultBrowserPackageName)) {
19791                setDefaultBrowserPackageName(null, userId);
19792            }
19793        }
19794    }
19795
19796    @Override
19797    public void resetApplicationPreferences(int userId) {
19798        mContext.enforceCallingOrSelfPermission(
19799                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19800        final long identity = Binder.clearCallingIdentity();
19801        // writer
19802        try {
19803            synchronized (mPackages) {
19804                clearPackagePreferredActivitiesLPw(null, userId);
19805                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19806                // TODO: We have to reset the default SMS and Phone. This requires
19807                // significant refactoring to keep all default apps in the package
19808                // manager (cleaner but more work) or have the services provide
19809                // callbacks to the package manager to request a default app reset.
19810                applyFactoryDefaultBrowserLPw(userId);
19811                clearIntentFilterVerificationsLPw(userId);
19812                primeDomainVerificationsLPw(userId);
19813                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19814                scheduleWritePackageRestrictionsLocked(userId);
19815            }
19816            resetNetworkPolicies(userId);
19817        } finally {
19818            Binder.restoreCallingIdentity(identity);
19819        }
19820    }
19821
19822    @Override
19823    public int getPreferredActivities(List<IntentFilter> outFilters,
19824            List<ComponentName> outActivities, String packageName) {
19825        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19826            return 0;
19827        }
19828        int num = 0;
19829        final int userId = UserHandle.getCallingUserId();
19830        // reader
19831        synchronized (mPackages) {
19832            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19833            if (pir != null) {
19834                final Iterator<PreferredActivity> it = pir.filterIterator();
19835                while (it.hasNext()) {
19836                    final PreferredActivity pa = it.next();
19837                    if (packageName == null
19838                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19839                                    && pa.mPref.mAlways)) {
19840                        if (outFilters != null) {
19841                            outFilters.add(new IntentFilter(pa));
19842                        }
19843                        if (outActivities != null) {
19844                            outActivities.add(pa.mPref.mComponent);
19845                        }
19846                    }
19847                }
19848            }
19849        }
19850
19851        return num;
19852    }
19853
19854    @Override
19855    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19856            int userId) {
19857        int callingUid = Binder.getCallingUid();
19858        if (callingUid != Process.SYSTEM_UID) {
19859            throw new SecurityException(
19860                    "addPersistentPreferredActivity can only be run by the system");
19861        }
19862        if (filter.countActions() == 0) {
19863            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19864            return;
19865        }
19866        synchronized (mPackages) {
19867            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19868                    ":");
19869            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19870            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19871                    new PersistentPreferredActivity(filter, activity));
19872            scheduleWritePackageRestrictionsLocked(userId);
19873            postPreferredActivityChangedBroadcast(userId);
19874        }
19875    }
19876
19877    @Override
19878    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19879        int callingUid = Binder.getCallingUid();
19880        if (callingUid != Process.SYSTEM_UID) {
19881            throw new SecurityException(
19882                    "clearPackagePersistentPreferredActivities can only be run by the system");
19883        }
19884        ArrayList<PersistentPreferredActivity> removed = null;
19885        boolean changed = false;
19886        synchronized (mPackages) {
19887            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19888                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19889                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19890                        .valueAt(i);
19891                if (userId != thisUserId) {
19892                    continue;
19893                }
19894                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19895                while (it.hasNext()) {
19896                    PersistentPreferredActivity ppa = it.next();
19897                    // Mark entry for removal only if it matches the package name.
19898                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19899                        if (removed == null) {
19900                            removed = new ArrayList<PersistentPreferredActivity>();
19901                        }
19902                        removed.add(ppa);
19903                    }
19904                }
19905                if (removed != null) {
19906                    for (int j=0; j<removed.size(); j++) {
19907                        PersistentPreferredActivity ppa = removed.get(j);
19908                        ppir.removeFilter(ppa);
19909                    }
19910                    changed = true;
19911                }
19912            }
19913
19914            if (changed) {
19915                scheduleWritePackageRestrictionsLocked(userId);
19916                postPreferredActivityChangedBroadcast(userId);
19917            }
19918        }
19919    }
19920
19921    /**
19922     * Common machinery for picking apart a restored XML blob and passing
19923     * it to a caller-supplied functor to be applied to the running system.
19924     */
19925    private void restoreFromXml(XmlPullParser parser, int userId,
19926            String expectedStartTag, BlobXmlRestorer functor)
19927            throws IOException, XmlPullParserException {
19928        int type;
19929        while ((type = parser.next()) != XmlPullParser.START_TAG
19930                && type != XmlPullParser.END_DOCUMENT) {
19931        }
19932        if (type != XmlPullParser.START_TAG) {
19933            // oops didn't find a start tag?!
19934            if (DEBUG_BACKUP) {
19935                Slog.e(TAG, "Didn't find start tag during restore");
19936            }
19937            return;
19938        }
19939Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19940        // this is supposed to be TAG_PREFERRED_BACKUP
19941        if (!expectedStartTag.equals(parser.getName())) {
19942            if (DEBUG_BACKUP) {
19943                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19944            }
19945            return;
19946        }
19947
19948        // skip interfering stuff, then we're aligned with the backing implementation
19949        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19950Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19951        functor.apply(parser, userId);
19952    }
19953
19954    private interface BlobXmlRestorer {
19955        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19956    }
19957
19958    /**
19959     * Non-Binder method, support for the backup/restore mechanism: write the
19960     * full set of preferred activities in its canonical XML format.  Returns the
19961     * XML output as a byte array, or null if there is none.
19962     */
19963    @Override
19964    public byte[] getPreferredActivityBackup(int userId) {
19965        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19966            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19967        }
19968
19969        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19970        try {
19971            final XmlSerializer serializer = new FastXmlSerializer();
19972            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19973            serializer.startDocument(null, true);
19974            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19975
19976            synchronized (mPackages) {
19977                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19978            }
19979
19980            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19981            serializer.endDocument();
19982            serializer.flush();
19983        } catch (Exception e) {
19984            if (DEBUG_BACKUP) {
19985                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19986            }
19987            return null;
19988        }
19989
19990        return dataStream.toByteArray();
19991    }
19992
19993    @Override
19994    public void restorePreferredActivities(byte[] backup, int userId) {
19995        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19996            throw new SecurityException("Only the system may call restorePreferredActivities()");
19997        }
19998
19999        try {
20000            final XmlPullParser parser = Xml.newPullParser();
20001            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20002            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20003                    new BlobXmlRestorer() {
20004                        @Override
20005                        public void apply(XmlPullParser parser, int userId)
20006                                throws XmlPullParserException, IOException {
20007                            synchronized (mPackages) {
20008                                mSettings.readPreferredActivitiesLPw(parser, userId);
20009                            }
20010                        }
20011                    } );
20012        } catch (Exception e) {
20013            if (DEBUG_BACKUP) {
20014                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20015            }
20016        }
20017    }
20018
20019    /**
20020     * Non-Binder method, support for the backup/restore mechanism: write the
20021     * default browser (etc) settings in its canonical XML format.  Returns the default
20022     * browser XML representation as a byte array, or null if there is none.
20023     */
20024    @Override
20025    public byte[] getDefaultAppsBackup(int userId) {
20026        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20027            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20028        }
20029
20030        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20031        try {
20032            final XmlSerializer serializer = new FastXmlSerializer();
20033            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20034            serializer.startDocument(null, true);
20035            serializer.startTag(null, TAG_DEFAULT_APPS);
20036
20037            synchronized (mPackages) {
20038                mSettings.writeDefaultAppsLPr(serializer, userId);
20039            }
20040
20041            serializer.endTag(null, TAG_DEFAULT_APPS);
20042            serializer.endDocument();
20043            serializer.flush();
20044        } catch (Exception e) {
20045            if (DEBUG_BACKUP) {
20046                Slog.e(TAG, "Unable to write default apps for backup", e);
20047            }
20048            return null;
20049        }
20050
20051        return dataStream.toByteArray();
20052    }
20053
20054    @Override
20055    public void restoreDefaultApps(byte[] backup, int userId) {
20056        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20057            throw new SecurityException("Only the system may call restoreDefaultApps()");
20058        }
20059
20060        try {
20061            final XmlPullParser parser = Xml.newPullParser();
20062            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20063            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20064                    new BlobXmlRestorer() {
20065                        @Override
20066                        public void apply(XmlPullParser parser, int userId)
20067                                throws XmlPullParserException, IOException {
20068                            synchronized (mPackages) {
20069                                mSettings.readDefaultAppsLPw(parser, userId);
20070                            }
20071                        }
20072                    } );
20073        } catch (Exception e) {
20074            if (DEBUG_BACKUP) {
20075                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20076            }
20077        }
20078    }
20079
20080    @Override
20081    public byte[] getIntentFilterVerificationBackup(int userId) {
20082        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20083            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20084        }
20085
20086        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20087        try {
20088            final XmlSerializer serializer = new FastXmlSerializer();
20089            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20090            serializer.startDocument(null, true);
20091            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20092
20093            synchronized (mPackages) {
20094                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20095            }
20096
20097            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20098            serializer.endDocument();
20099            serializer.flush();
20100        } catch (Exception e) {
20101            if (DEBUG_BACKUP) {
20102                Slog.e(TAG, "Unable to write default apps for backup", e);
20103            }
20104            return null;
20105        }
20106
20107        return dataStream.toByteArray();
20108    }
20109
20110    @Override
20111    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20112        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20113            throw new SecurityException("Only the system may call restorePreferredActivities()");
20114        }
20115
20116        try {
20117            final XmlPullParser parser = Xml.newPullParser();
20118            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20119            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20120                    new BlobXmlRestorer() {
20121                        @Override
20122                        public void apply(XmlPullParser parser, int userId)
20123                                throws XmlPullParserException, IOException {
20124                            synchronized (mPackages) {
20125                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20126                                mSettings.writeLPr();
20127                            }
20128                        }
20129                    } );
20130        } catch (Exception e) {
20131            if (DEBUG_BACKUP) {
20132                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20133            }
20134        }
20135    }
20136
20137    @Override
20138    public byte[] getPermissionGrantBackup(int userId) {
20139        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20140            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20141        }
20142
20143        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20144        try {
20145            final XmlSerializer serializer = new FastXmlSerializer();
20146            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20147            serializer.startDocument(null, true);
20148            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20149
20150            synchronized (mPackages) {
20151                serializeRuntimePermissionGrantsLPr(serializer, userId);
20152            }
20153
20154            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20155            serializer.endDocument();
20156            serializer.flush();
20157        } catch (Exception e) {
20158            if (DEBUG_BACKUP) {
20159                Slog.e(TAG, "Unable to write default apps for backup", e);
20160            }
20161            return null;
20162        }
20163
20164        return dataStream.toByteArray();
20165    }
20166
20167    @Override
20168    public void restorePermissionGrants(byte[] backup, int userId) {
20169        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20170            throw new SecurityException("Only the system may call restorePermissionGrants()");
20171        }
20172
20173        try {
20174            final XmlPullParser parser = Xml.newPullParser();
20175            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20176            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20177                    new BlobXmlRestorer() {
20178                        @Override
20179                        public void apply(XmlPullParser parser, int userId)
20180                                throws XmlPullParserException, IOException {
20181                            synchronized (mPackages) {
20182                                processRestoredPermissionGrantsLPr(parser, userId);
20183                            }
20184                        }
20185                    } );
20186        } catch (Exception e) {
20187            if (DEBUG_BACKUP) {
20188                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20189            }
20190        }
20191    }
20192
20193    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20194            throws IOException {
20195        serializer.startTag(null, TAG_ALL_GRANTS);
20196
20197        final int N = mSettings.mPackages.size();
20198        for (int i = 0; i < N; i++) {
20199            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20200            boolean pkgGrantsKnown = false;
20201
20202            PermissionsState packagePerms = ps.getPermissionsState();
20203
20204            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20205                final int grantFlags = state.getFlags();
20206                // only look at grants that are not system/policy fixed
20207                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20208                    final boolean isGranted = state.isGranted();
20209                    // And only back up the user-twiddled state bits
20210                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20211                        final String packageName = mSettings.mPackages.keyAt(i);
20212                        if (!pkgGrantsKnown) {
20213                            serializer.startTag(null, TAG_GRANT);
20214                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20215                            pkgGrantsKnown = true;
20216                        }
20217
20218                        final boolean userSet =
20219                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20220                        final boolean userFixed =
20221                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20222                        final boolean revoke =
20223                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20224
20225                        serializer.startTag(null, TAG_PERMISSION);
20226                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20227                        if (isGranted) {
20228                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20229                        }
20230                        if (userSet) {
20231                            serializer.attribute(null, ATTR_USER_SET, "true");
20232                        }
20233                        if (userFixed) {
20234                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20235                        }
20236                        if (revoke) {
20237                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20238                        }
20239                        serializer.endTag(null, TAG_PERMISSION);
20240                    }
20241                }
20242            }
20243
20244            if (pkgGrantsKnown) {
20245                serializer.endTag(null, TAG_GRANT);
20246            }
20247        }
20248
20249        serializer.endTag(null, TAG_ALL_GRANTS);
20250    }
20251
20252    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20253            throws XmlPullParserException, IOException {
20254        String pkgName = null;
20255        int outerDepth = parser.getDepth();
20256        int type;
20257        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20258                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20259            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20260                continue;
20261            }
20262
20263            final String tagName = parser.getName();
20264            if (tagName.equals(TAG_GRANT)) {
20265                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20266                if (DEBUG_BACKUP) {
20267                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20268                }
20269            } else if (tagName.equals(TAG_PERMISSION)) {
20270
20271                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20272                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20273
20274                int newFlagSet = 0;
20275                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20276                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20277                }
20278                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20279                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20280                }
20281                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20282                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20283                }
20284                if (DEBUG_BACKUP) {
20285                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20286                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20287                }
20288                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20289                if (ps != null) {
20290                    // Already installed so we apply the grant immediately
20291                    if (DEBUG_BACKUP) {
20292                        Slog.v(TAG, "        + already installed; applying");
20293                    }
20294                    PermissionsState perms = ps.getPermissionsState();
20295                    BasePermission bp = mSettings.mPermissions.get(permName);
20296                    if (bp != null) {
20297                        if (isGranted) {
20298                            perms.grantRuntimePermission(bp, userId);
20299                        }
20300                        if (newFlagSet != 0) {
20301                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20302                        }
20303                    }
20304                } else {
20305                    // Need to wait for post-restore install to apply the grant
20306                    if (DEBUG_BACKUP) {
20307                        Slog.v(TAG, "        - not yet installed; saving for later");
20308                    }
20309                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20310                            isGranted, newFlagSet, userId);
20311                }
20312            } else {
20313                PackageManagerService.reportSettingsProblem(Log.WARN,
20314                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20315                XmlUtils.skipCurrentTag(parser);
20316            }
20317        }
20318
20319        scheduleWriteSettingsLocked();
20320        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20321    }
20322
20323    @Override
20324    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20325            int sourceUserId, int targetUserId, int flags) {
20326        mContext.enforceCallingOrSelfPermission(
20327                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20328        int callingUid = Binder.getCallingUid();
20329        enforceOwnerRights(ownerPackage, callingUid);
20330        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20331        if (intentFilter.countActions() == 0) {
20332            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20333            return;
20334        }
20335        synchronized (mPackages) {
20336            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20337                    ownerPackage, targetUserId, flags);
20338            CrossProfileIntentResolver resolver =
20339                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20340            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20341            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20342            if (existing != null) {
20343                int size = existing.size();
20344                for (int i = 0; i < size; i++) {
20345                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20346                        return;
20347                    }
20348                }
20349            }
20350            resolver.addFilter(newFilter);
20351            scheduleWritePackageRestrictionsLocked(sourceUserId);
20352        }
20353    }
20354
20355    @Override
20356    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20357        mContext.enforceCallingOrSelfPermission(
20358                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20359        int callingUid = Binder.getCallingUid();
20360        enforceOwnerRights(ownerPackage, callingUid);
20361        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20362        synchronized (mPackages) {
20363            CrossProfileIntentResolver resolver =
20364                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20365            ArraySet<CrossProfileIntentFilter> set =
20366                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20367            for (CrossProfileIntentFilter filter : set) {
20368                if (filter.getOwnerPackage().equals(ownerPackage)) {
20369                    resolver.removeFilter(filter);
20370                }
20371            }
20372            scheduleWritePackageRestrictionsLocked(sourceUserId);
20373        }
20374    }
20375
20376    // Enforcing that callingUid is owning pkg on userId
20377    private void enforceOwnerRights(String pkg, int callingUid) {
20378        // The system owns everything.
20379        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20380            return;
20381        }
20382        int callingUserId = UserHandle.getUserId(callingUid);
20383        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20384        if (pi == null) {
20385            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20386                    + callingUserId);
20387        }
20388        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20389            throw new SecurityException("Calling uid " + callingUid
20390                    + " does not own package " + pkg);
20391        }
20392    }
20393
20394    @Override
20395    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20396        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20397            return null;
20398        }
20399        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20400    }
20401
20402    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20403        UserManagerService ums = UserManagerService.getInstance();
20404        if (ums != null) {
20405            final UserInfo parent = ums.getProfileParent(userId);
20406            final int launcherUid = (parent != null) ? parent.id : userId;
20407            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20408            if (launcherComponent != null) {
20409                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20410                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20411                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20412                        .setPackage(launcherComponent.getPackageName());
20413                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20414            }
20415        }
20416    }
20417
20418    /**
20419     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20420     * then reports the most likely home activity or null if there are more than one.
20421     */
20422    private ComponentName getDefaultHomeActivity(int userId) {
20423        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20424        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20425        if (cn != null) {
20426            return cn;
20427        }
20428
20429        // Find the launcher with the highest priority and return that component if there are no
20430        // other home activity with the same priority.
20431        int lastPriority = Integer.MIN_VALUE;
20432        ComponentName lastComponent = null;
20433        final int size = allHomeCandidates.size();
20434        for (int i = 0; i < size; i++) {
20435            final ResolveInfo ri = allHomeCandidates.get(i);
20436            if (ri.priority > lastPriority) {
20437                lastComponent = ri.activityInfo.getComponentName();
20438                lastPriority = ri.priority;
20439            } else if (ri.priority == lastPriority) {
20440                // Two components found with same priority.
20441                lastComponent = null;
20442            }
20443        }
20444        return lastComponent;
20445    }
20446
20447    private Intent getHomeIntent() {
20448        Intent intent = new Intent(Intent.ACTION_MAIN);
20449        intent.addCategory(Intent.CATEGORY_HOME);
20450        intent.addCategory(Intent.CATEGORY_DEFAULT);
20451        return intent;
20452    }
20453
20454    private IntentFilter getHomeFilter() {
20455        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20456        filter.addCategory(Intent.CATEGORY_HOME);
20457        filter.addCategory(Intent.CATEGORY_DEFAULT);
20458        return filter;
20459    }
20460
20461    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20462            int userId) {
20463        Intent intent  = getHomeIntent();
20464        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20465                PackageManager.GET_META_DATA, userId);
20466        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20467                true, false, false, userId);
20468
20469        allHomeCandidates.clear();
20470        if (list != null) {
20471            for (ResolveInfo ri : list) {
20472                allHomeCandidates.add(ri);
20473            }
20474        }
20475        return (preferred == null || preferred.activityInfo == null)
20476                ? null
20477                : new ComponentName(preferred.activityInfo.packageName,
20478                        preferred.activityInfo.name);
20479    }
20480
20481    @Override
20482    public void setHomeActivity(ComponentName comp, int userId) {
20483        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20484            return;
20485        }
20486        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20487        getHomeActivitiesAsUser(homeActivities, userId);
20488
20489        boolean found = false;
20490
20491        final int size = homeActivities.size();
20492        final ComponentName[] set = new ComponentName[size];
20493        for (int i = 0; i < size; i++) {
20494            final ResolveInfo candidate = homeActivities.get(i);
20495            final ActivityInfo info = candidate.activityInfo;
20496            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20497            set[i] = activityName;
20498            if (!found && activityName.equals(comp)) {
20499                found = true;
20500            }
20501        }
20502        if (!found) {
20503            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20504                    + userId);
20505        }
20506        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20507                set, comp, userId);
20508    }
20509
20510    private @Nullable String getSetupWizardPackageName() {
20511        final Intent intent = new Intent(Intent.ACTION_MAIN);
20512        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20513
20514        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20515                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20516                        | MATCH_DISABLED_COMPONENTS,
20517                UserHandle.myUserId());
20518        if (matches.size() == 1) {
20519            return matches.get(0).getComponentInfo().packageName;
20520        } else {
20521            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20522                    + ": matches=" + matches);
20523            return null;
20524        }
20525    }
20526
20527    private @Nullable String getStorageManagerPackageName() {
20528        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20529
20530        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20531                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20532                        | MATCH_DISABLED_COMPONENTS,
20533                UserHandle.myUserId());
20534        if (matches.size() == 1) {
20535            return matches.get(0).getComponentInfo().packageName;
20536        } else {
20537            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20538                    + matches.size() + ": matches=" + matches);
20539            return null;
20540        }
20541    }
20542
20543    @Override
20544    public void setApplicationEnabledSetting(String appPackageName,
20545            int newState, int flags, int userId, String callingPackage) {
20546        if (!sUserManager.exists(userId)) return;
20547        if (callingPackage == null) {
20548            callingPackage = Integer.toString(Binder.getCallingUid());
20549        }
20550        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20551    }
20552
20553    @Override
20554    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20555        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20556        synchronized (mPackages) {
20557            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20558            if (pkgSetting != null) {
20559                pkgSetting.setUpdateAvailable(updateAvailable);
20560            }
20561        }
20562    }
20563
20564    @Override
20565    public void setComponentEnabledSetting(ComponentName componentName,
20566            int newState, int flags, int userId) {
20567        if (!sUserManager.exists(userId)) return;
20568        setEnabledSetting(componentName.getPackageName(),
20569                componentName.getClassName(), newState, flags, userId, null);
20570    }
20571
20572    private void setEnabledSetting(final String packageName, String className, int newState,
20573            final int flags, int userId, String callingPackage) {
20574        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20575              || newState == COMPONENT_ENABLED_STATE_ENABLED
20576              || newState == COMPONENT_ENABLED_STATE_DISABLED
20577              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20578              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20579            throw new IllegalArgumentException("Invalid new component state: "
20580                    + newState);
20581        }
20582        PackageSetting pkgSetting;
20583        final int callingUid = Binder.getCallingUid();
20584        final int permission;
20585        if (callingUid == Process.SYSTEM_UID) {
20586            permission = PackageManager.PERMISSION_GRANTED;
20587        } else {
20588            permission = mContext.checkCallingOrSelfPermission(
20589                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20590        }
20591        enforceCrossUserPermission(callingUid, userId,
20592                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20593        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20594        boolean sendNow = false;
20595        boolean isApp = (className == null);
20596        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20597        String componentName = isApp ? packageName : className;
20598        int packageUid = -1;
20599        ArrayList<String> components;
20600
20601        // reader
20602        synchronized (mPackages) {
20603            pkgSetting = mSettings.mPackages.get(packageName);
20604            if (pkgSetting == null) {
20605                if (!isCallerInstantApp) {
20606                    if (className == null) {
20607                        throw new IllegalArgumentException("Unknown package: " + packageName);
20608                    }
20609                    throw new IllegalArgumentException(
20610                            "Unknown component: " + packageName + "/" + className);
20611                } else {
20612                    // throw SecurityException to prevent leaking package information
20613                    throw new SecurityException(
20614                            "Attempt to change component state; "
20615                            + "pid=" + Binder.getCallingPid()
20616                            + ", uid=" + callingUid
20617                            + (className == null
20618                                    ? ", package=" + packageName
20619                                    : ", component=" + packageName + "/" + className));
20620                }
20621            }
20622        }
20623
20624        // Limit who can change which apps
20625        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20626            // Don't allow apps that don't have permission to modify other apps
20627            if (!allowedByPermission) {
20628                throw new SecurityException(
20629                        "Attempt to change component state; "
20630                        + "pid=" + Binder.getCallingPid()
20631                        + ", uid=" + callingUid
20632                        + (className == null
20633                                ? ", package=" + packageName
20634                                : ", component=" + packageName + "/" + className));
20635            }
20636            // Don't allow changing protected packages.
20637            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20638                throw new SecurityException("Cannot disable a protected package: " + packageName);
20639            }
20640        }
20641
20642        synchronized (mPackages) {
20643            if (callingUid == Process.SHELL_UID
20644                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20645                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20646                // unless it is a test package.
20647                int oldState = pkgSetting.getEnabled(userId);
20648                if (className == null
20649                    &&
20650                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20651                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20652                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20653                    &&
20654                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20655                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20656                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20657                    // ok
20658                } else {
20659                    throw new SecurityException(
20660                            "Shell cannot change component state for " + packageName + "/"
20661                            + className + " to " + newState);
20662                }
20663            }
20664            if (className == null) {
20665                // We're dealing with an application/package level state change
20666                if (pkgSetting.getEnabled(userId) == newState) {
20667                    // Nothing to do
20668                    return;
20669                }
20670                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20671                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20672                    // Don't care about who enables an app.
20673                    callingPackage = null;
20674                }
20675                pkgSetting.setEnabled(newState, userId, callingPackage);
20676                // pkgSetting.pkg.mSetEnabled = newState;
20677            } else {
20678                // We're dealing with a component level state change
20679                // First, verify that this is a valid class name.
20680                PackageParser.Package pkg = pkgSetting.pkg;
20681                if (pkg == null || !pkg.hasComponentClassName(className)) {
20682                    if (pkg != null &&
20683                            pkg.applicationInfo.targetSdkVersion >=
20684                                    Build.VERSION_CODES.JELLY_BEAN) {
20685                        throw new IllegalArgumentException("Component class " + className
20686                                + " does not exist in " + packageName);
20687                    } else {
20688                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20689                                + className + " does not exist in " + packageName);
20690                    }
20691                }
20692                switch (newState) {
20693                case COMPONENT_ENABLED_STATE_ENABLED:
20694                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20695                        return;
20696                    }
20697                    break;
20698                case COMPONENT_ENABLED_STATE_DISABLED:
20699                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20700                        return;
20701                    }
20702                    break;
20703                case COMPONENT_ENABLED_STATE_DEFAULT:
20704                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20705                        return;
20706                    }
20707                    break;
20708                default:
20709                    Slog.e(TAG, "Invalid new component state: " + newState);
20710                    return;
20711                }
20712            }
20713            scheduleWritePackageRestrictionsLocked(userId);
20714            updateSequenceNumberLP(packageName, new int[] { userId });
20715            final long callingId = Binder.clearCallingIdentity();
20716            try {
20717                updateInstantAppInstallerLocked(packageName);
20718            } finally {
20719                Binder.restoreCallingIdentity(callingId);
20720            }
20721            components = mPendingBroadcasts.get(userId, packageName);
20722            final boolean newPackage = components == null;
20723            if (newPackage) {
20724                components = new ArrayList<String>();
20725            }
20726            if (!components.contains(componentName)) {
20727                components.add(componentName);
20728            }
20729            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20730                sendNow = true;
20731                // Purge entry from pending broadcast list if another one exists already
20732                // since we are sending one right away.
20733                mPendingBroadcasts.remove(userId, packageName);
20734            } else {
20735                if (newPackage) {
20736                    mPendingBroadcasts.put(userId, packageName, components);
20737                }
20738                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20739                    // Schedule a message
20740                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20741                }
20742            }
20743        }
20744
20745        long callingId = Binder.clearCallingIdentity();
20746        try {
20747            if (sendNow) {
20748                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20749                sendPackageChangedBroadcast(packageName,
20750                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20751            }
20752        } finally {
20753            Binder.restoreCallingIdentity(callingId);
20754        }
20755    }
20756
20757    @Override
20758    public void flushPackageRestrictionsAsUser(int userId) {
20759        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20760            return;
20761        }
20762        if (!sUserManager.exists(userId)) {
20763            return;
20764        }
20765        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20766                false /* checkShell */, "flushPackageRestrictions");
20767        synchronized (mPackages) {
20768            mSettings.writePackageRestrictionsLPr(userId);
20769            mDirtyUsers.remove(userId);
20770            if (mDirtyUsers.isEmpty()) {
20771                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20772            }
20773        }
20774    }
20775
20776    private void sendPackageChangedBroadcast(String packageName,
20777            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20778        if (DEBUG_INSTALL)
20779            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20780                    + componentNames);
20781        Bundle extras = new Bundle(4);
20782        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20783        String nameList[] = new String[componentNames.size()];
20784        componentNames.toArray(nameList);
20785        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20786        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20787        extras.putInt(Intent.EXTRA_UID, packageUid);
20788        // If this is not reporting a change of the overall package, then only send it
20789        // to registered receivers.  We don't want to launch a swath of apps for every
20790        // little component state change.
20791        final int flags = !componentNames.contains(packageName)
20792                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20793        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20794                new int[] {UserHandle.getUserId(packageUid)});
20795    }
20796
20797    @Override
20798    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20799        if (!sUserManager.exists(userId)) return;
20800        final int callingUid = Binder.getCallingUid();
20801        if (getInstantAppPackageName(callingUid) != null) {
20802            return;
20803        }
20804        final int permission = mContext.checkCallingOrSelfPermission(
20805                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20806        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20807        enforceCrossUserPermission(callingUid, userId,
20808                true /* requireFullPermission */, true /* checkShell */, "stop package");
20809        // writer
20810        synchronized (mPackages) {
20811            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20812                    allowedByPermission, callingUid, userId)) {
20813                scheduleWritePackageRestrictionsLocked(userId);
20814            }
20815        }
20816    }
20817
20818    @Override
20819    public String getInstallerPackageName(String packageName) {
20820        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20821            return null;
20822        }
20823        // reader
20824        synchronized (mPackages) {
20825            return mSettings.getInstallerPackageNameLPr(packageName);
20826        }
20827    }
20828
20829    public boolean isOrphaned(String packageName) {
20830        // reader
20831        synchronized (mPackages) {
20832            return mSettings.isOrphaned(packageName);
20833        }
20834    }
20835
20836    @Override
20837    public int getApplicationEnabledSetting(String packageName, int userId) {
20838        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20839        int uid = Binder.getCallingUid();
20840        enforceCrossUserPermission(uid, userId,
20841                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20842        // reader
20843        synchronized (mPackages) {
20844            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20845        }
20846    }
20847
20848    @Override
20849    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20850        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20851        int uid = Binder.getCallingUid();
20852        enforceCrossUserPermission(uid, userId,
20853                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20854        // reader
20855        synchronized (mPackages) {
20856            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20857        }
20858    }
20859
20860    @Override
20861    public void enterSafeMode() {
20862        enforceSystemOrRoot("Only the system can request entering safe mode");
20863
20864        if (!mSystemReady) {
20865            mSafeMode = true;
20866        }
20867    }
20868
20869    @Override
20870    public void systemReady() {
20871        enforceSystemOrRoot("Only the system can claim the system is ready");
20872
20873        mSystemReady = true;
20874        final ContentResolver resolver = mContext.getContentResolver();
20875        ContentObserver co = new ContentObserver(mHandler) {
20876            @Override
20877            public void onChange(boolean selfChange) {
20878                mEphemeralAppsDisabled =
20879                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20880                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20881            }
20882        };
20883        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20884                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20885                false, co, UserHandle.USER_SYSTEM);
20886        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20887                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20888        co.onChange(true);
20889
20890        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20891        // disabled after already being started.
20892        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20893                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20894
20895        // Read the compatibilty setting when the system is ready.
20896        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20897                mContext.getContentResolver(),
20898                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20899        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20900        if (DEBUG_SETTINGS) {
20901            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20902        }
20903
20904        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20905
20906        synchronized (mPackages) {
20907            // Verify that all of the preferred activity components actually
20908            // exist.  It is possible for applications to be updated and at
20909            // that point remove a previously declared activity component that
20910            // had been set as a preferred activity.  We try to clean this up
20911            // the next time we encounter that preferred activity, but it is
20912            // possible for the user flow to never be able to return to that
20913            // situation so here we do a sanity check to make sure we haven't
20914            // left any junk around.
20915            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20916            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20917                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20918                removed.clear();
20919                for (PreferredActivity pa : pir.filterSet()) {
20920                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20921                        removed.add(pa);
20922                    }
20923                }
20924                if (removed.size() > 0) {
20925                    for (int r=0; r<removed.size(); r++) {
20926                        PreferredActivity pa = removed.get(r);
20927                        Slog.w(TAG, "Removing dangling preferred activity: "
20928                                + pa.mPref.mComponent);
20929                        pir.removeFilter(pa);
20930                    }
20931                    mSettings.writePackageRestrictionsLPr(
20932                            mSettings.mPreferredActivities.keyAt(i));
20933                }
20934            }
20935
20936            for (int userId : UserManagerService.getInstance().getUserIds()) {
20937                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20938                    grantPermissionsUserIds = ArrayUtils.appendInt(
20939                            grantPermissionsUserIds, userId);
20940                }
20941            }
20942        }
20943        sUserManager.systemReady();
20944
20945        // If we upgraded grant all default permissions before kicking off.
20946        for (int userId : grantPermissionsUserIds) {
20947            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20948        }
20949
20950        // If we did not grant default permissions, we preload from this the
20951        // default permission exceptions lazily to ensure we don't hit the
20952        // disk on a new user creation.
20953        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20954            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20955        }
20956
20957        // Kick off any messages waiting for system ready
20958        if (mPostSystemReadyMessages != null) {
20959            for (Message msg : mPostSystemReadyMessages) {
20960                msg.sendToTarget();
20961            }
20962            mPostSystemReadyMessages = null;
20963        }
20964
20965        // Watch for external volumes that come and go over time
20966        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20967        storage.registerListener(mStorageListener);
20968
20969        mInstallerService.systemReady();
20970        mPackageDexOptimizer.systemReady();
20971
20972        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20973                StorageManagerInternal.class);
20974        StorageManagerInternal.addExternalStoragePolicy(
20975                new StorageManagerInternal.ExternalStorageMountPolicy() {
20976            @Override
20977            public int getMountMode(int uid, String packageName) {
20978                if (Process.isIsolated(uid)) {
20979                    return Zygote.MOUNT_EXTERNAL_NONE;
20980                }
20981                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20982                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20983                }
20984                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20985                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20986                }
20987                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20988                    return Zygote.MOUNT_EXTERNAL_READ;
20989                }
20990                return Zygote.MOUNT_EXTERNAL_WRITE;
20991            }
20992
20993            @Override
20994            public boolean hasExternalStorage(int uid, String packageName) {
20995                return true;
20996            }
20997        });
20998
20999        // Now that we're mostly running, clean up stale users and apps
21000        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21001        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21002
21003        if (mPrivappPermissionsViolations != null) {
21004            Slog.wtf(TAG,"Signature|privileged permissions not in "
21005                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21006            mPrivappPermissionsViolations = null;
21007        }
21008    }
21009
21010    public void waitForAppDataPrepared() {
21011        if (mPrepareAppDataFuture == null) {
21012            return;
21013        }
21014        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21015        mPrepareAppDataFuture = null;
21016    }
21017
21018    @Override
21019    public boolean isSafeMode() {
21020        // allow instant applications
21021        return mSafeMode;
21022    }
21023
21024    @Override
21025    public boolean hasSystemUidErrors() {
21026        // allow instant applications
21027        return mHasSystemUidErrors;
21028    }
21029
21030    static String arrayToString(int[] array) {
21031        StringBuffer buf = new StringBuffer(128);
21032        buf.append('[');
21033        if (array != null) {
21034            for (int i=0; i<array.length; i++) {
21035                if (i > 0) buf.append(", ");
21036                buf.append(array[i]);
21037            }
21038        }
21039        buf.append(']');
21040        return buf.toString();
21041    }
21042
21043    static class DumpState {
21044        public static final int DUMP_LIBS = 1 << 0;
21045        public static final int DUMP_FEATURES = 1 << 1;
21046        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
21047        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
21048        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
21049        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
21050        public static final int DUMP_PERMISSIONS = 1 << 6;
21051        public static final int DUMP_PACKAGES = 1 << 7;
21052        public static final int DUMP_SHARED_USERS = 1 << 8;
21053        public static final int DUMP_MESSAGES = 1 << 9;
21054        public static final int DUMP_PROVIDERS = 1 << 10;
21055        public static final int DUMP_VERIFIERS = 1 << 11;
21056        public static final int DUMP_PREFERRED = 1 << 12;
21057        public static final int DUMP_PREFERRED_XML = 1 << 13;
21058        public static final int DUMP_KEYSETS = 1 << 14;
21059        public static final int DUMP_VERSION = 1 << 15;
21060        public static final int DUMP_INSTALLS = 1 << 16;
21061        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
21062        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
21063        public static final int DUMP_FROZEN = 1 << 19;
21064        public static final int DUMP_DEXOPT = 1 << 20;
21065        public static final int DUMP_COMPILER_STATS = 1 << 21;
21066        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
21067        public static final int DUMP_CHANGES = 1 << 23;
21068
21069        public static final int OPTION_SHOW_FILTERS = 1 << 0;
21070
21071        private int mTypes;
21072
21073        private int mOptions;
21074
21075        private boolean mTitlePrinted;
21076
21077        private SharedUserSetting mSharedUser;
21078
21079        public boolean isDumping(int type) {
21080            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
21081                return true;
21082            }
21083
21084            return (mTypes & type) != 0;
21085        }
21086
21087        public void setDump(int type) {
21088            mTypes |= type;
21089        }
21090
21091        public boolean isOptionEnabled(int option) {
21092            return (mOptions & option) != 0;
21093        }
21094
21095        public void setOptionEnabled(int option) {
21096            mOptions |= option;
21097        }
21098
21099        public boolean onTitlePrinted() {
21100            final boolean printed = mTitlePrinted;
21101            mTitlePrinted = true;
21102            return printed;
21103        }
21104
21105        public boolean getTitlePrinted() {
21106            return mTitlePrinted;
21107        }
21108
21109        public void setTitlePrinted(boolean enabled) {
21110            mTitlePrinted = enabled;
21111        }
21112
21113        public SharedUserSetting getSharedUser() {
21114            return mSharedUser;
21115        }
21116
21117        public void setSharedUser(SharedUserSetting user) {
21118            mSharedUser = user;
21119        }
21120    }
21121
21122    @Override
21123    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21124            FileDescriptor err, String[] args, ShellCallback callback,
21125            ResultReceiver resultReceiver) {
21126        (new PackageManagerShellCommand(this)).exec(
21127                this, in, out, err, args, callback, resultReceiver);
21128    }
21129
21130    @Override
21131    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21132        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21133
21134        DumpState dumpState = new DumpState();
21135        boolean fullPreferred = false;
21136        boolean checkin = false;
21137
21138        String packageName = null;
21139        ArraySet<String> permissionNames = null;
21140
21141        int opti = 0;
21142        while (opti < args.length) {
21143            String opt = args[opti];
21144            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21145                break;
21146            }
21147            opti++;
21148
21149            if ("-a".equals(opt)) {
21150                // Right now we only know how to print all.
21151            } else if ("-h".equals(opt)) {
21152                pw.println("Package manager dump options:");
21153                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21154                pw.println("    --checkin: dump for a checkin");
21155                pw.println("    -f: print details of intent filters");
21156                pw.println("    -h: print this help");
21157                pw.println("  cmd may be one of:");
21158                pw.println("    l[ibraries]: list known shared libraries");
21159                pw.println("    f[eatures]: list device features");
21160                pw.println("    k[eysets]: print known keysets");
21161                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21162                pw.println("    perm[issions]: dump permissions");
21163                pw.println("    permission [name ...]: dump declaration and use of given permission");
21164                pw.println("    pref[erred]: print preferred package settings");
21165                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21166                pw.println("    prov[iders]: dump content providers");
21167                pw.println("    p[ackages]: dump installed packages");
21168                pw.println("    s[hared-users]: dump shared user IDs");
21169                pw.println("    m[essages]: print collected runtime messages");
21170                pw.println("    v[erifiers]: print package verifier info");
21171                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21172                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21173                pw.println("    version: print database version info");
21174                pw.println("    write: write current settings now");
21175                pw.println("    installs: details about install sessions");
21176                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21177                pw.println("    dexopt: dump dexopt state");
21178                pw.println("    compiler-stats: dump compiler statistics");
21179                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21180                pw.println("    <package.name>: info about given package");
21181                return;
21182            } else if ("--checkin".equals(opt)) {
21183                checkin = true;
21184            } else if ("-f".equals(opt)) {
21185                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21186            } else if ("--proto".equals(opt)) {
21187                dumpProto(fd);
21188                return;
21189            } else {
21190                pw.println("Unknown argument: " + opt + "; use -h for help");
21191            }
21192        }
21193
21194        // Is the caller requesting to dump a particular piece of data?
21195        if (opti < args.length) {
21196            String cmd = args[opti];
21197            opti++;
21198            // Is this a package name?
21199            if ("android".equals(cmd) || cmd.contains(".")) {
21200                packageName = cmd;
21201                // When dumping a single package, we always dump all of its
21202                // filter information since the amount of data will be reasonable.
21203                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21204            } else if ("check-permission".equals(cmd)) {
21205                if (opti >= args.length) {
21206                    pw.println("Error: check-permission missing permission argument");
21207                    return;
21208                }
21209                String perm = args[opti];
21210                opti++;
21211                if (opti >= args.length) {
21212                    pw.println("Error: check-permission missing package argument");
21213                    return;
21214                }
21215
21216                String pkg = args[opti];
21217                opti++;
21218                int user = UserHandle.getUserId(Binder.getCallingUid());
21219                if (opti < args.length) {
21220                    try {
21221                        user = Integer.parseInt(args[opti]);
21222                    } catch (NumberFormatException e) {
21223                        pw.println("Error: check-permission user argument is not a number: "
21224                                + args[opti]);
21225                        return;
21226                    }
21227                }
21228
21229                // Normalize package name to handle renamed packages and static libs
21230                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21231
21232                pw.println(checkPermission(perm, pkg, user));
21233                return;
21234            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21235                dumpState.setDump(DumpState.DUMP_LIBS);
21236            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21237                dumpState.setDump(DumpState.DUMP_FEATURES);
21238            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21239                if (opti >= args.length) {
21240                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21241                            | DumpState.DUMP_SERVICE_RESOLVERS
21242                            | DumpState.DUMP_RECEIVER_RESOLVERS
21243                            | DumpState.DUMP_CONTENT_RESOLVERS);
21244                } else {
21245                    while (opti < args.length) {
21246                        String name = args[opti];
21247                        if ("a".equals(name) || "activity".equals(name)) {
21248                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21249                        } else if ("s".equals(name) || "service".equals(name)) {
21250                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21251                        } else if ("r".equals(name) || "receiver".equals(name)) {
21252                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21253                        } else if ("c".equals(name) || "content".equals(name)) {
21254                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21255                        } else {
21256                            pw.println("Error: unknown resolver table type: " + name);
21257                            return;
21258                        }
21259                        opti++;
21260                    }
21261                }
21262            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21263                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21264            } else if ("permission".equals(cmd)) {
21265                if (opti >= args.length) {
21266                    pw.println("Error: permission requires permission name");
21267                    return;
21268                }
21269                permissionNames = new ArraySet<>();
21270                while (opti < args.length) {
21271                    permissionNames.add(args[opti]);
21272                    opti++;
21273                }
21274                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21275                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21276            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21277                dumpState.setDump(DumpState.DUMP_PREFERRED);
21278            } else if ("preferred-xml".equals(cmd)) {
21279                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21280                if (opti < args.length && "--full".equals(args[opti])) {
21281                    fullPreferred = true;
21282                    opti++;
21283                }
21284            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21285                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21286            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21287                dumpState.setDump(DumpState.DUMP_PACKAGES);
21288            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21289                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21290            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21291                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21292            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21293                dumpState.setDump(DumpState.DUMP_MESSAGES);
21294            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21295                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21296            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21297                    || "intent-filter-verifiers".equals(cmd)) {
21298                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21299            } else if ("version".equals(cmd)) {
21300                dumpState.setDump(DumpState.DUMP_VERSION);
21301            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21302                dumpState.setDump(DumpState.DUMP_KEYSETS);
21303            } else if ("installs".equals(cmd)) {
21304                dumpState.setDump(DumpState.DUMP_INSTALLS);
21305            } else if ("frozen".equals(cmd)) {
21306                dumpState.setDump(DumpState.DUMP_FROZEN);
21307            } else if ("dexopt".equals(cmd)) {
21308                dumpState.setDump(DumpState.DUMP_DEXOPT);
21309            } else if ("compiler-stats".equals(cmd)) {
21310                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21311            } else if ("enabled-overlays".equals(cmd)) {
21312                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
21313            } else if ("changes".equals(cmd)) {
21314                dumpState.setDump(DumpState.DUMP_CHANGES);
21315            } else if ("write".equals(cmd)) {
21316                synchronized (mPackages) {
21317                    mSettings.writeLPr();
21318                    pw.println("Settings written.");
21319                    return;
21320                }
21321            }
21322        }
21323
21324        if (checkin) {
21325            pw.println("vers,1");
21326        }
21327
21328        // reader
21329        synchronized (mPackages) {
21330            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21331                if (!checkin) {
21332                    if (dumpState.onTitlePrinted())
21333                        pw.println();
21334                    pw.println("Database versions:");
21335                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21336                }
21337            }
21338
21339            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21340                if (!checkin) {
21341                    if (dumpState.onTitlePrinted())
21342                        pw.println();
21343                    pw.println("Verifiers:");
21344                    pw.print("  Required: ");
21345                    pw.print(mRequiredVerifierPackage);
21346                    pw.print(" (uid=");
21347                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21348                            UserHandle.USER_SYSTEM));
21349                    pw.println(")");
21350                } else if (mRequiredVerifierPackage != null) {
21351                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21352                    pw.print(",");
21353                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21354                            UserHandle.USER_SYSTEM));
21355                }
21356            }
21357
21358            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21359                    packageName == null) {
21360                if (mIntentFilterVerifierComponent != null) {
21361                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21362                    if (!checkin) {
21363                        if (dumpState.onTitlePrinted())
21364                            pw.println();
21365                        pw.println("Intent Filter Verifier:");
21366                        pw.print("  Using: ");
21367                        pw.print(verifierPackageName);
21368                        pw.print(" (uid=");
21369                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21370                                UserHandle.USER_SYSTEM));
21371                        pw.println(")");
21372                    } else if (verifierPackageName != null) {
21373                        pw.print("ifv,"); pw.print(verifierPackageName);
21374                        pw.print(",");
21375                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21376                                UserHandle.USER_SYSTEM));
21377                    }
21378                } else {
21379                    pw.println();
21380                    pw.println("No Intent Filter Verifier available!");
21381                }
21382            }
21383
21384            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21385                boolean printedHeader = false;
21386                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21387                while (it.hasNext()) {
21388                    String libName = it.next();
21389                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21390                    if (versionedLib == null) {
21391                        continue;
21392                    }
21393                    final int versionCount = versionedLib.size();
21394                    for (int i = 0; i < versionCount; i++) {
21395                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21396                        if (!checkin) {
21397                            if (!printedHeader) {
21398                                if (dumpState.onTitlePrinted())
21399                                    pw.println();
21400                                pw.println("Libraries:");
21401                                printedHeader = true;
21402                            }
21403                            pw.print("  ");
21404                        } else {
21405                            pw.print("lib,");
21406                        }
21407                        pw.print(libEntry.info.getName());
21408                        if (libEntry.info.isStatic()) {
21409                            pw.print(" version=" + libEntry.info.getVersion());
21410                        }
21411                        if (!checkin) {
21412                            pw.print(" -> ");
21413                        }
21414                        if (libEntry.path != null) {
21415                            pw.print(" (jar) ");
21416                            pw.print(libEntry.path);
21417                        } else {
21418                            pw.print(" (apk) ");
21419                            pw.print(libEntry.apk);
21420                        }
21421                        pw.println();
21422                    }
21423                }
21424            }
21425
21426            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21427                if (dumpState.onTitlePrinted())
21428                    pw.println();
21429                if (!checkin) {
21430                    pw.println("Features:");
21431                }
21432
21433                synchronized (mAvailableFeatures) {
21434                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21435                        if (checkin) {
21436                            pw.print("feat,");
21437                            pw.print(feat.name);
21438                            pw.print(",");
21439                            pw.println(feat.version);
21440                        } else {
21441                            pw.print("  ");
21442                            pw.print(feat.name);
21443                            if (feat.version > 0) {
21444                                pw.print(" version=");
21445                                pw.print(feat.version);
21446                            }
21447                            pw.println();
21448                        }
21449                    }
21450                }
21451            }
21452
21453            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21454                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21455                        : "Activity Resolver Table:", "  ", packageName,
21456                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21457                    dumpState.setTitlePrinted(true);
21458                }
21459            }
21460            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21461                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21462                        : "Receiver Resolver Table:", "  ", packageName,
21463                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21464                    dumpState.setTitlePrinted(true);
21465                }
21466            }
21467            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21468                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21469                        : "Service Resolver Table:", "  ", packageName,
21470                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21471                    dumpState.setTitlePrinted(true);
21472                }
21473            }
21474            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21475                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21476                        : "Provider Resolver Table:", "  ", packageName,
21477                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21478                    dumpState.setTitlePrinted(true);
21479                }
21480            }
21481
21482            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21483                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21484                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21485                    int user = mSettings.mPreferredActivities.keyAt(i);
21486                    if (pir.dump(pw,
21487                            dumpState.getTitlePrinted()
21488                                ? "\nPreferred Activities User " + user + ":"
21489                                : "Preferred Activities User " + user + ":", "  ",
21490                            packageName, true, false)) {
21491                        dumpState.setTitlePrinted(true);
21492                    }
21493                }
21494            }
21495
21496            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21497                pw.flush();
21498                FileOutputStream fout = new FileOutputStream(fd);
21499                BufferedOutputStream str = new BufferedOutputStream(fout);
21500                XmlSerializer serializer = new FastXmlSerializer();
21501                try {
21502                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21503                    serializer.startDocument(null, true);
21504                    serializer.setFeature(
21505                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21506                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21507                    serializer.endDocument();
21508                    serializer.flush();
21509                } catch (IllegalArgumentException e) {
21510                    pw.println("Failed writing: " + e);
21511                } catch (IllegalStateException e) {
21512                    pw.println("Failed writing: " + e);
21513                } catch (IOException e) {
21514                    pw.println("Failed writing: " + e);
21515                }
21516            }
21517
21518            if (!checkin
21519                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21520                    && packageName == null) {
21521                pw.println();
21522                int count = mSettings.mPackages.size();
21523                if (count == 0) {
21524                    pw.println("No applications!");
21525                    pw.println();
21526                } else {
21527                    final String prefix = "  ";
21528                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21529                    if (allPackageSettings.size() == 0) {
21530                        pw.println("No domain preferred apps!");
21531                        pw.println();
21532                    } else {
21533                        pw.println("App verification status:");
21534                        pw.println();
21535                        count = 0;
21536                        for (PackageSetting ps : allPackageSettings) {
21537                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21538                            if (ivi == null || ivi.getPackageName() == null) continue;
21539                            pw.println(prefix + "Package: " + ivi.getPackageName());
21540                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21541                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21542                            pw.println();
21543                            count++;
21544                        }
21545                        if (count == 0) {
21546                            pw.println(prefix + "No app verification established.");
21547                            pw.println();
21548                        }
21549                        for (int userId : sUserManager.getUserIds()) {
21550                            pw.println("App linkages for user " + userId + ":");
21551                            pw.println();
21552                            count = 0;
21553                            for (PackageSetting ps : allPackageSettings) {
21554                                final long status = ps.getDomainVerificationStatusForUser(userId);
21555                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21556                                        && !DEBUG_DOMAIN_VERIFICATION) {
21557                                    continue;
21558                                }
21559                                pw.println(prefix + "Package: " + ps.name);
21560                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21561                                String statusStr = IntentFilterVerificationInfo.
21562                                        getStatusStringFromValue(status);
21563                                pw.println(prefix + "Status:  " + statusStr);
21564                                pw.println();
21565                                count++;
21566                            }
21567                            if (count == 0) {
21568                                pw.println(prefix + "No configured app linkages.");
21569                                pw.println();
21570                            }
21571                        }
21572                    }
21573                }
21574            }
21575
21576            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21577                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21578                if (packageName == null && permissionNames == null) {
21579                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21580                        if (iperm == 0) {
21581                            if (dumpState.onTitlePrinted())
21582                                pw.println();
21583                            pw.println("AppOp Permissions:");
21584                        }
21585                        pw.print("  AppOp Permission ");
21586                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21587                        pw.println(":");
21588                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21589                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21590                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21591                        }
21592                    }
21593                }
21594            }
21595
21596            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21597                boolean printedSomething = false;
21598                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21599                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21600                        continue;
21601                    }
21602                    if (!printedSomething) {
21603                        if (dumpState.onTitlePrinted())
21604                            pw.println();
21605                        pw.println("Registered ContentProviders:");
21606                        printedSomething = true;
21607                    }
21608                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21609                    pw.print("    "); pw.println(p.toString());
21610                }
21611                printedSomething = false;
21612                for (Map.Entry<String, PackageParser.Provider> entry :
21613                        mProvidersByAuthority.entrySet()) {
21614                    PackageParser.Provider p = entry.getValue();
21615                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21616                        continue;
21617                    }
21618                    if (!printedSomething) {
21619                        if (dumpState.onTitlePrinted())
21620                            pw.println();
21621                        pw.println("ContentProvider Authorities:");
21622                        printedSomething = true;
21623                    }
21624                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21625                    pw.print("    "); pw.println(p.toString());
21626                    if (p.info != null && p.info.applicationInfo != null) {
21627                        final String appInfo = p.info.applicationInfo.toString();
21628                        pw.print("      applicationInfo="); pw.println(appInfo);
21629                    }
21630                }
21631            }
21632
21633            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21634                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21635            }
21636
21637            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21638                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21639            }
21640
21641            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21642                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21643            }
21644
21645            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21646                if (dumpState.onTitlePrinted()) pw.println();
21647                pw.println("Package Changes:");
21648                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21649                final int K = mChangedPackages.size();
21650                for (int i = 0; i < K; i++) {
21651                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21652                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21653                    final int N = changes.size();
21654                    if (N == 0) {
21655                        pw.print("    "); pw.println("No packages changed");
21656                    } else {
21657                        for (int j = 0; j < N; j++) {
21658                            final String pkgName = changes.valueAt(j);
21659                            final int sequenceNumber = changes.keyAt(j);
21660                            pw.print("    ");
21661                            pw.print("seq=");
21662                            pw.print(sequenceNumber);
21663                            pw.print(", package=");
21664                            pw.println(pkgName);
21665                        }
21666                    }
21667                }
21668            }
21669
21670            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21671                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21672            }
21673
21674            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21675                // XXX should handle packageName != null by dumping only install data that
21676                // the given package is involved with.
21677                if (dumpState.onTitlePrinted()) pw.println();
21678
21679                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21680                ipw.println();
21681                ipw.println("Frozen packages:");
21682                ipw.increaseIndent();
21683                if (mFrozenPackages.size() == 0) {
21684                    ipw.println("(none)");
21685                } else {
21686                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21687                        ipw.println(mFrozenPackages.valueAt(i));
21688                    }
21689                }
21690                ipw.decreaseIndent();
21691            }
21692
21693            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21694                if (dumpState.onTitlePrinted()) pw.println();
21695                dumpDexoptStateLPr(pw, packageName);
21696            }
21697
21698            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21699                if (dumpState.onTitlePrinted()) pw.println();
21700                dumpCompilerStatsLPr(pw, packageName);
21701            }
21702
21703            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21704                if (dumpState.onTitlePrinted()) pw.println();
21705                dumpEnabledOverlaysLPr(pw);
21706            }
21707
21708            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21709                if (dumpState.onTitlePrinted()) pw.println();
21710                mSettings.dumpReadMessagesLPr(pw, dumpState);
21711
21712                pw.println();
21713                pw.println("Package warning messages:");
21714                BufferedReader in = null;
21715                String line = null;
21716                try {
21717                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21718                    while ((line = in.readLine()) != null) {
21719                        if (line.contains("ignored: updated version")) continue;
21720                        pw.println(line);
21721                    }
21722                } catch (IOException ignored) {
21723                } finally {
21724                    IoUtils.closeQuietly(in);
21725                }
21726            }
21727
21728            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21729                BufferedReader in = null;
21730                String line = null;
21731                try {
21732                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21733                    while ((line = in.readLine()) != null) {
21734                        if (line.contains("ignored: updated version")) continue;
21735                        pw.print("msg,");
21736                        pw.println(line);
21737                    }
21738                } catch (IOException ignored) {
21739                } finally {
21740                    IoUtils.closeQuietly(in);
21741                }
21742            }
21743        }
21744
21745        // PackageInstaller should be called outside of mPackages lock
21746        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21747            // XXX should handle packageName != null by dumping only install data that
21748            // the given package is involved with.
21749            if (dumpState.onTitlePrinted()) pw.println();
21750            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21751        }
21752    }
21753
21754    private void dumpProto(FileDescriptor fd) {
21755        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21756
21757        synchronized (mPackages) {
21758            final long requiredVerifierPackageToken =
21759                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21760            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21761            proto.write(
21762                    PackageServiceDumpProto.PackageShortProto.UID,
21763                    getPackageUid(
21764                            mRequiredVerifierPackage,
21765                            MATCH_DEBUG_TRIAGED_MISSING,
21766                            UserHandle.USER_SYSTEM));
21767            proto.end(requiredVerifierPackageToken);
21768
21769            if (mIntentFilterVerifierComponent != null) {
21770                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21771                final long verifierPackageToken =
21772                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21773                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21774                proto.write(
21775                        PackageServiceDumpProto.PackageShortProto.UID,
21776                        getPackageUid(
21777                                verifierPackageName,
21778                                MATCH_DEBUG_TRIAGED_MISSING,
21779                                UserHandle.USER_SYSTEM));
21780                proto.end(verifierPackageToken);
21781            }
21782
21783            dumpSharedLibrariesProto(proto);
21784            dumpFeaturesProto(proto);
21785            mSettings.dumpPackagesProto(proto);
21786            mSettings.dumpSharedUsersProto(proto);
21787            dumpMessagesProto(proto);
21788        }
21789        proto.flush();
21790    }
21791
21792    private void dumpMessagesProto(ProtoOutputStream proto) {
21793        BufferedReader in = null;
21794        String line = null;
21795        try {
21796            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21797            while ((line = in.readLine()) != null) {
21798                if (line.contains("ignored: updated version")) continue;
21799                proto.write(PackageServiceDumpProto.MESSAGES, line);
21800            }
21801        } catch (IOException ignored) {
21802        } finally {
21803            IoUtils.closeQuietly(in);
21804        }
21805    }
21806
21807    private void dumpFeaturesProto(ProtoOutputStream proto) {
21808        synchronized (mAvailableFeatures) {
21809            final int count = mAvailableFeatures.size();
21810            for (int i = 0; i < count; i++) {
21811                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21812                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21813                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21814                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21815                proto.end(featureToken);
21816            }
21817        }
21818    }
21819
21820    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21821        final int count = mSharedLibraries.size();
21822        for (int i = 0; i < count; i++) {
21823            final String libName = mSharedLibraries.keyAt(i);
21824            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21825            if (versionedLib == null) {
21826                continue;
21827            }
21828            final int versionCount = versionedLib.size();
21829            for (int j = 0; j < versionCount; j++) {
21830                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21831                final long sharedLibraryToken =
21832                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21833                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21834                final boolean isJar = (libEntry.path != null);
21835                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21836                if (isJar) {
21837                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21838                } else {
21839                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21840                }
21841                proto.end(sharedLibraryToken);
21842            }
21843        }
21844    }
21845
21846    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21847        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21848        ipw.println();
21849        ipw.println("Dexopt state:");
21850        ipw.increaseIndent();
21851        Collection<PackageParser.Package> packages = null;
21852        if (packageName != null) {
21853            PackageParser.Package targetPackage = mPackages.get(packageName);
21854            if (targetPackage != null) {
21855                packages = Collections.singletonList(targetPackage);
21856            } else {
21857                ipw.println("Unable to find package: " + packageName);
21858                return;
21859            }
21860        } else {
21861            packages = mPackages.values();
21862        }
21863
21864        for (PackageParser.Package pkg : packages) {
21865            ipw.println("[" + pkg.packageName + "]");
21866            ipw.increaseIndent();
21867            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21868            ipw.decreaseIndent();
21869        }
21870    }
21871
21872    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21873        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21874        ipw.println();
21875        ipw.println("Compiler stats:");
21876        ipw.increaseIndent();
21877        Collection<PackageParser.Package> packages = null;
21878        if (packageName != null) {
21879            PackageParser.Package targetPackage = mPackages.get(packageName);
21880            if (targetPackage != null) {
21881                packages = Collections.singletonList(targetPackage);
21882            } else {
21883                ipw.println("Unable to find package: " + packageName);
21884                return;
21885            }
21886        } else {
21887            packages = mPackages.values();
21888        }
21889
21890        for (PackageParser.Package pkg : packages) {
21891            ipw.println("[" + pkg.packageName + "]");
21892            ipw.increaseIndent();
21893
21894            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21895            if (stats == null) {
21896                ipw.println("(No recorded stats)");
21897            } else {
21898                stats.dump(ipw);
21899            }
21900            ipw.decreaseIndent();
21901        }
21902    }
21903
21904    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21905        pw.println("Enabled overlay paths:");
21906        final int N = mEnabledOverlayPaths.size();
21907        for (int i = 0; i < N; i++) {
21908            final int userId = mEnabledOverlayPaths.keyAt(i);
21909            pw.println(String.format("    User %d:", userId));
21910            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21911                mEnabledOverlayPaths.valueAt(i);
21912            final int M = userSpecificOverlays.size();
21913            for (int j = 0; j < M; j++) {
21914                final String targetPackageName = userSpecificOverlays.keyAt(j);
21915                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21916                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21917            }
21918        }
21919    }
21920
21921    private String dumpDomainString(String packageName) {
21922        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21923                .getList();
21924        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21925
21926        ArraySet<String> result = new ArraySet<>();
21927        if (iviList.size() > 0) {
21928            for (IntentFilterVerificationInfo ivi : iviList) {
21929                for (String host : ivi.getDomains()) {
21930                    result.add(host);
21931                }
21932            }
21933        }
21934        if (filters != null && filters.size() > 0) {
21935            for (IntentFilter filter : filters) {
21936                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21937                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21938                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21939                    result.addAll(filter.getHostsList());
21940                }
21941            }
21942        }
21943
21944        StringBuilder sb = new StringBuilder(result.size() * 16);
21945        for (String domain : result) {
21946            if (sb.length() > 0) sb.append(" ");
21947            sb.append(domain);
21948        }
21949        return sb.toString();
21950    }
21951
21952    // ------- apps on sdcard specific code -------
21953    static final boolean DEBUG_SD_INSTALL = false;
21954
21955    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21956
21957    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21958
21959    private boolean mMediaMounted = false;
21960
21961    static String getEncryptKey() {
21962        try {
21963            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21964                    SD_ENCRYPTION_KEYSTORE_NAME);
21965            if (sdEncKey == null) {
21966                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21967                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21968                if (sdEncKey == null) {
21969                    Slog.e(TAG, "Failed to create encryption keys");
21970                    return null;
21971                }
21972            }
21973            return sdEncKey;
21974        } catch (NoSuchAlgorithmException nsae) {
21975            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21976            return null;
21977        } catch (IOException ioe) {
21978            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21979            return null;
21980        }
21981    }
21982
21983    /*
21984     * Update media status on PackageManager.
21985     */
21986    @Override
21987    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21988        enforceSystemOrRoot("Media status can only be updated by the system");
21989        // reader; this apparently protects mMediaMounted, but should probably
21990        // be a different lock in that case.
21991        synchronized (mPackages) {
21992            Log.i(TAG, "Updating external media status from "
21993                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
21994                    + (mediaStatus ? "mounted" : "unmounted"));
21995            if (DEBUG_SD_INSTALL)
21996                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21997                        + ", mMediaMounted=" + mMediaMounted);
21998            if (mediaStatus == mMediaMounted) {
21999                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
22000                        : 0, -1);
22001                mHandler.sendMessage(msg);
22002                return;
22003            }
22004            mMediaMounted = mediaStatus;
22005        }
22006        // Queue up an async operation since the package installation may take a
22007        // little while.
22008        mHandler.post(new Runnable() {
22009            public void run() {
22010                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
22011            }
22012        });
22013    }
22014
22015    /**
22016     * Called by StorageManagerService when the initial ASECs to scan are available.
22017     * Should block until all the ASEC containers are finished being scanned.
22018     */
22019    public void scanAvailableAsecs() {
22020        updateExternalMediaStatusInner(true, false, false);
22021    }
22022
22023    /*
22024     * Collect information of applications on external media, map them against
22025     * existing containers and update information based on current mount status.
22026     * Please note that we always have to report status if reportStatus has been
22027     * set to true especially when unloading packages.
22028     */
22029    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
22030            boolean externalStorage) {
22031        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
22032        int[] uidArr = EmptyArray.INT;
22033
22034        final String[] list = PackageHelper.getSecureContainerList();
22035        if (ArrayUtils.isEmpty(list)) {
22036            Log.i(TAG, "No secure containers found");
22037        } else {
22038            // Process list of secure containers and categorize them
22039            // as active or stale based on their package internal state.
22040
22041            // reader
22042            synchronized (mPackages) {
22043                for (String cid : list) {
22044                    // Leave stages untouched for now; installer service owns them
22045                    if (PackageInstallerService.isStageName(cid)) continue;
22046
22047                    if (DEBUG_SD_INSTALL)
22048                        Log.i(TAG, "Processing container " + cid);
22049                    String pkgName = getAsecPackageName(cid);
22050                    if (pkgName == null) {
22051                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
22052                        continue;
22053                    }
22054                    if (DEBUG_SD_INSTALL)
22055                        Log.i(TAG, "Looking for pkg : " + pkgName);
22056
22057                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
22058                    if (ps == null) {
22059                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
22060                        continue;
22061                    }
22062
22063                    /*
22064                     * Skip packages that are not external if we're unmounting
22065                     * external storage.
22066                     */
22067                    if (externalStorage && !isMounted && !isExternal(ps)) {
22068                        continue;
22069                    }
22070
22071                    final AsecInstallArgs args = new AsecInstallArgs(cid,
22072                            getAppDexInstructionSets(ps), ps.isForwardLocked());
22073                    // The package status is changed only if the code path
22074                    // matches between settings and the container id.
22075                    if (ps.codePathString != null
22076                            && ps.codePathString.startsWith(args.getCodePath())) {
22077                        if (DEBUG_SD_INSTALL) {
22078                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
22079                                    + " at code path: " + ps.codePathString);
22080                        }
22081
22082                        // We do have a valid package installed on sdcard
22083                        processCids.put(args, ps.codePathString);
22084                        final int uid = ps.appId;
22085                        if (uid != -1) {
22086                            uidArr = ArrayUtils.appendInt(uidArr, uid);
22087                        }
22088                    } else {
22089                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
22090                                + ps.codePathString);
22091                    }
22092                }
22093            }
22094
22095            Arrays.sort(uidArr);
22096        }
22097
22098        // Process packages with valid entries.
22099        if (isMounted) {
22100            if (DEBUG_SD_INSTALL)
22101                Log.i(TAG, "Loading packages");
22102            loadMediaPackages(processCids, uidArr, externalStorage);
22103            startCleaningPackages();
22104            mInstallerService.onSecureContainersAvailable();
22105        } else {
22106            if (DEBUG_SD_INSTALL)
22107                Log.i(TAG, "Unloading packages");
22108            unloadMediaPackages(processCids, uidArr, reportStatus);
22109        }
22110    }
22111
22112    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22113            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22114        final int size = infos.size();
22115        final String[] packageNames = new String[size];
22116        final int[] packageUids = new int[size];
22117        for (int i = 0; i < size; i++) {
22118            final ApplicationInfo info = infos.get(i);
22119            packageNames[i] = info.packageName;
22120            packageUids[i] = info.uid;
22121        }
22122        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22123                finishedReceiver);
22124    }
22125
22126    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22127            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22128        sendResourcesChangedBroadcast(mediaStatus, replacing,
22129                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22130    }
22131
22132    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22133            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22134        int size = pkgList.length;
22135        if (size > 0) {
22136            // Send broadcasts here
22137            Bundle extras = new Bundle();
22138            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22139            if (uidArr != null) {
22140                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22141            }
22142            if (replacing) {
22143                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22144            }
22145            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22146                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22147            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
22148        }
22149    }
22150
22151   /*
22152     * Look at potentially valid container ids from processCids If package
22153     * information doesn't match the one on record or package scanning fails,
22154     * the cid is added to list of removeCids. We currently don't delete stale
22155     * containers.
22156     */
22157    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
22158            boolean externalStorage) {
22159        ArrayList<String> pkgList = new ArrayList<String>();
22160        Set<AsecInstallArgs> keys = processCids.keySet();
22161
22162        for (AsecInstallArgs args : keys) {
22163            String codePath = processCids.get(args);
22164            if (DEBUG_SD_INSTALL)
22165                Log.i(TAG, "Loading container : " + args.cid);
22166            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
22167            try {
22168                // Make sure there are no container errors first.
22169                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
22170                    Slog.e(TAG, "Failed to mount cid : " + args.cid
22171                            + " when installing from sdcard");
22172                    continue;
22173                }
22174                // Check code path here.
22175                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
22176                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
22177                            + " does not match one in settings " + codePath);
22178                    continue;
22179                }
22180                // Parse package
22181                int parseFlags = mDefParseFlags;
22182                if (args.isExternalAsec()) {
22183                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
22184                }
22185                if (args.isFwdLocked()) {
22186                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
22187                }
22188
22189                synchronized (mInstallLock) {
22190                    PackageParser.Package pkg = null;
22191                    try {
22192                        // Sadly we don't know the package name yet to freeze it
22193                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
22194                                SCAN_IGNORE_FROZEN, 0, null);
22195                    } catch (PackageManagerException e) {
22196                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
22197                    }
22198                    // Scan the package
22199                    if (pkg != null) {
22200                        /*
22201                         * TODO why is the lock being held? doPostInstall is
22202                         * called in other places without the lock. This needs
22203                         * to be straightened out.
22204                         */
22205                        // writer
22206                        synchronized (mPackages) {
22207                            retCode = PackageManager.INSTALL_SUCCEEDED;
22208                            pkgList.add(pkg.packageName);
22209                            // Post process args
22210                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
22211                                    pkg.applicationInfo.uid);
22212                        }
22213                    } else {
22214                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
22215                    }
22216                }
22217
22218            } finally {
22219                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
22220                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
22221                }
22222            }
22223        }
22224        // writer
22225        synchronized (mPackages) {
22226            // If the platform SDK has changed since the last time we booted,
22227            // we need to re-grant app permission to catch any new ones that
22228            // appear. This is really a hack, and means that apps can in some
22229            // cases get permissions that the user didn't initially explicitly
22230            // allow... it would be nice to have some better way to handle
22231            // this situation.
22232            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
22233                    : mSettings.getInternalVersion();
22234            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
22235                    : StorageManager.UUID_PRIVATE_INTERNAL;
22236
22237            int updateFlags = UPDATE_PERMISSIONS_ALL;
22238            if (ver.sdkVersion != mSdkVersion) {
22239                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22240                        + mSdkVersion + "; regranting permissions for external");
22241                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22242            }
22243            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22244
22245            // Yay, everything is now upgraded
22246            ver.forceCurrent();
22247
22248            // can downgrade to reader
22249            // Persist settings
22250            mSettings.writeLPr();
22251        }
22252        // Send a broadcast to let everyone know we are done processing
22253        if (pkgList.size() > 0) {
22254            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
22255        }
22256    }
22257
22258   /*
22259     * Utility method to unload a list of specified containers
22260     */
22261    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
22262        // Just unmount all valid containers.
22263        for (AsecInstallArgs arg : cidArgs) {
22264            synchronized (mInstallLock) {
22265                arg.doPostDeleteLI(false);
22266           }
22267       }
22268   }
22269
22270    /*
22271     * Unload packages mounted on external media. This involves deleting package
22272     * data from internal structures, sending broadcasts about disabled packages,
22273     * gc'ing to free up references, unmounting all secure containers
22274     * corresponding to packages on external media, and posting a
22275     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
22276     * that we always have to post this message if status has been requested no
22277     * matter what.
22278     */
22279    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
22280            final boolean reportStatus) {
22281        if (DEBUG_SD_INSTALL)
22282            Log.i(TAG, "unloading media packages");
22283        ArrayList<String> pkgList = new ArrayList<String>();
22284        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
22285        final Set<AsecInstallArgs> keys = processCids.keySet();
22286        for (AsecInstallArgs args : keys) {
22287            String pkgName = args.getPackageName();
22288            if (DEBUG_SD_INSTALL)
22289                Log.i(TAG, "Trying to unload pkg : " + pkgName);
22290            // Delete package internally
22291            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22292            synchronized (mInstallLock) {
22293                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22294                final boolean res;
22295                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
22296                        "unloadMediaPackages")) {
22297                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
22298                            null);
22299                }
22300                if (res) {
22301                    pkgList.add(pkgName);
22302                } else {
22303                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
22304                    failedList.add(args);
22305                }
22306            }
22307        }
22308
22309        // reader
22310        synchronized (mPackages) {
22311            // We didn't update the settings after removing each package;
22312            // write them now for all packages.
22313            mSettings.writeLPr();
22314        }
22315
22316        // We have to absolutely send UPDATED_MEDIA_STATUS only
22317        // after confirming that all the receivers processed the ordered
22318        // broadcast when packages get disabled, force a gc to clean things up.
22319        // and unload all the containers.
22320        if (pkgList.size() > 0) {
22321            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
22322                    new IIntentReceiver.Stub() {
22323                public void performReceive(Intent intent, int resultCode, String data,
22324                        Bundle extras, boolean ordered, boolean sticky,
22325                        int sendingUser) throws RemoteException {
22326                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
22327                            reportStatus ? 1 : 0, 1, keys);
22328                    mHandler.sendMessage(msg);
22329                }
22330            });
22331        } else {
22332            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
22333                    keys);
22334            mHandler.sendMessage(msg);
22335        }
22336    }
22337
22338    private void loadPrivatePackages(final VolumeInfo vol) {
22339        mHandler.post(new Runnable() {
22340            @Override
22341            public void run() {
22342                loadPrivatePackagesInner(vol);
22343            }
22344        });
22345    }
22346
22347    private void loadPrivatePackagesInner(VolumeInfo vol) {
22348        final String volumeUuid = vol.fsUuid;
22349        if (TextUtils.isEmpty(volumeUuid)) {
22350            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22351            return;
22352        }
22353
22354        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22355        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22356        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22357
22358        final VersionInfo ver;
22359        final List<PackageSetting> packages;
22360        synchronized (mPackages) {
22361            ver = mSettings.findOrCreateVersion(volumeUuid);
22362            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22363        }
22364
22365        for (PackageSetting ps : packages) {
22366            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22367            synchronized (mInstallLock) {
22368                final PackageParser.Package pkg;
22369                try {
22370                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22371                    loaded.add(pkg.applicationInfo);
22372
22373                } catch (PackageManagerException e) {
22374                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22375                }
22376
22377                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22378                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22379                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22380                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22381                }
22382            }
22383        }
22384
22385        // Reconcile app data for all started/unlocked users
22386        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22387        final UserManager um = mContext.getSystemService(UserManager.class);
22388        UserManagerInternal umInternal = getUserManagerInternal();
22389        for (UserInfo user : um.getUsers()) {
22390            final int flags;
22391            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22392                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22393            } else if (umInternal.isUserRunning(user.id)) {
22394                flags = StorageManager.FLAG_STORAGE_DE;
22395            } else {
22396                continue;
22397            }
22398
22399            try {
22400                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22401                synchronized (mInstallLock) {
22402                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22403                }
22404            } catch (IllegalStateException e) {
22405                // Device was probably ejected, and we'll process that event momentarily
22406                Slog.w(TAG, "Failed to prepare storage: " + e);
22407            }
22408        }
22409
22410        synchronized (mPackages) {
22411            int updateFlags = UPDATE_PERMISSIONS_ALL;
22412            if (ver.sdkVersion != mSdkVersion) {
22413                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22414                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22415                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22416            }
22417            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22418
22419            // Yay, everything is now upgraded
22420            ver.forceCurrent();
22421
22422            mSettings.writeLPr();
22423        }
22424
22425        for (PackageFreezer freezer : freezers) {
22426            freezer.close();
22427        }
22428
22429        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22430        sendResourcesChangedBroadcast(true, false, loaded, null);
22431    }
22432
22433    private void unloadPrivatePackages(final VolumeInfo vol) {
22434        mHandler.post(new Runnable() {
22435            @Override
22436            public void run() {
22437                unloadPrivatePackagesInner(vol);
22438            }
22439        });
22440    }
22441
22442    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22443        final String volumeUuid = vol.fsUuid;
22444        if (TextUtils.isEmpty(volumeUuid)) {
22445            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22446            return;
22447        }
22448
22449        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22450        synchronized (mInstallLock) {
22451        synchronized (mPackages) {
22452            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22453            for (PackageSetting ps : packages) {
22454                if (ps.pkg == null) continue;
22455
22456                final ApplicationInfo info = ps.pkg.applicationInfo;
22457                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22458                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22459
22460                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22461                        "unloadPrivatePackagesInner")) {
22462                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22463                            false, null)) {
22464                        unloaded.add(info);
22465                    } else {
22466                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22467                    }
22468                }
22469
22470                // Try very hard to release any references to this package
22471                // so we don't risk the system server being killed due to
22472                // open FDs
22473                AttributeCache.instance().removePackage(ps.name);
22474            }
22475
22476            mSettings.writeLPr();
22477        }
22478        }
22479
22480        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22481        sendResourcesChangedBroadcast(false, false, unloaded, null);
22482
22483        // Try very hard to release any references to this path so we don't risk
22484        // the system server being killed due to open FDs
22485        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22486
22487        for (int i = 0; i < 3; i++) {
22488            System.gc();
22489            System.runFinalization();
22490        }
22491    }
22492
22493    private void assertPackageKnown(String volumeUuid, String packageName)
22494            throws PackageManagerException {
22495        synchronized (mPackages) {
22496            // Normalize package name to handle renamed packages
22497            packageName = normalizePackageNameLPr(packageName);
22498
22499            final PackageSetting ps = mSettings.mPackages.get(packageName);
22500            if (ps == null) {
22501                throw new PackageManagerException("Package " + packageName + " is unknown");
22502            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22503                throw new PackageManagerException(
22504                        "Package " + packageName + " found on unknown volume " + volumeUuid
22505                                + "; expected volume " + ps.volumeUuid);
22506            }
22507        }
22508    }
22509
22510    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22511            throws PackageManagerException {
22512        synchronized (mPackages) {
22513            // Normalize package name to handle renamed packages
22514            packageName = normalizePackageNameLPr(packageName);
22515
22516            final PackageSetting ps = mSettings.mPackages.get(packageName);
22517            if (ps == null) {
22518                throw new PackageManagerException("Package " + packageName + " is unknown");
22519            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22520                throw new PackageManagerException(
22521                        "Package " + packageName + " found on unknown volume " + volumeUuid
22522                                + "; expected volume " + ps.volumeUuid);
22523            } else if (!ps.getInstalled(userId)) {
22524                throw new PackageManagerException(
22525                        "Package " + packageName + " not installed for user " + userId);
22526            }
22527        }
22528    }
22529
22530    private List<String> collectAbsoluteCodePaths() {
22531        synchronized (mPackages) {
22532            List<String> codePaths = new ArrayList<>();
22533            final int packageCount = mSettings.mPackages.size();
22534            for (int i = 0; i < packageCount; i++) {
22535                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22536                codePaths.add(ps.codePath.getAbsolutePath());
22537            }
22538            return codePaths;
22539        }
22540    }
22541
22542    /**
22543     * Examine all apps present on given mounted volume, and destroy apps that
22544     * aren't expected, either due to uninstallation or reinstallation on
22545     * another volume.
22546     */
22547    private void reconcileApps(String volumeUuid) {
22548        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22549        List<File> filesToDelete = null;
22550
22551        final File[] files = FileUtils.listFilesOrEmpty(
22552                Environment.getDataAppDirectory(volumeUuid));
22553        for (File file : files) {
22554            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22555                    && !PackageInstallerService.isStageName(file.getName());
22556            if (!isPackage) {
22557                // Ignore entries which are not packages
22558                continue;
22559            }
22560
22561            String absolutePath = file.getAbsolutePath();
22562
22563            boolean pathValid = false;
22564            final int absoluteCodePathCount = absoluteCodePaths.size();
22565            for (int i = 0; i < absoluteCodePathCount; i++) {
22566                String absoluteCodePath = absoluteCodePaths.get(i);
22567                if (absolutePath.startsWith(absoluteCodePath)) {
22568                    pathValid = true;
22569                    break;
22570                }
22571            }
22572
22573            if (!pathValid) {
22574                if (filesToDelete == null) {
22575                    filesToDelete = new ArrayList<>();
22576                }
22577                filesToDelete.add(file);
22578            }
22579        }
22580
22581        if (filesToDelete != null) {
22582            final int fileToDeleteCount = filesToDelete.size();
22583            for (int i = 0; i < fileToDeleteCount; i++) {
22584                File fileToDelete = filesToDelete.get(i);
22585                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22586                synchronized (mInstallLock) {
22587                    removeCodePathLI(fileToDelete);
22588                }
22589            }
22590        }
22591    }
22592
22593    /**
22594     * Reconcile all app data for the given user.
22595     * <p>
22596     * Verifies that directories exist and that ownership and labeling is
22597     * correct for all installed apps on all mounted volumes.
22598     */
22599    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22600        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22601        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22602            final String volumeUuid = vol.getFsUuid();
22603            synchronized (mInstallLock) {
22604                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22605            }
22606        }
22607    }
22608
22609    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22610            boolean migrateAppData) {
22611        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22612    }
22613
22614    /**
22615     * Reconcile all app data on given mounted volume.
22616     * <p>
22617     * Destroys app data that isn't expected, either due to uninstallation or
22618     * reinstallation on another volume.
22619     * <p>
22620     * Verifies that directories exist and that ownership and labeling is
22621     * correct for all installed apps.
22622     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22623     */
22624    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22625            boolean migrateAppData, boolean onlyCoreApps) {
22626        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22627                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22628        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22629
22630        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22631        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22632
22633        // First look for stale data that doesn't belong, and check if things
22634        // have changed since we did our last restorecon
22635        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22636            if (StorageManager.isFileEncryptedNativeOrEmulated()
22637                    && !StorageManager.isUserKeyUnlocked(userId)) {
22638                throw new RuntimeException(
22639                        "Yikes, someone asked us to reconcile CE storage while " + userId
22640                                + " was still locked; this would have caused massive data loss!");
22641            }
22642
22643            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22644            for (File file : files) {
22645                final String packageName = file.getName();
22646                try {
22647                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22648                } catch (PackageManagerException e) {
22649                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22650                    try {
22651                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22652                                StorageManager.FLAG_STORAGE_CE, 0);
22653                    } catch (InstallerException e2) {
22654                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22655                    }
22656                }
22657            }
22658        }
22659        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22660            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22661            for (File file : files) {
22662                final String packageName = file.getName();
22663                try {
22664                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22665                } catch (PackageManagerException e) {
22666                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22667                    try {
22668                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22669                                StorageManager.FLAG_STORAGE_DE, 0);
22670                    } catch (InstallerException e2) {
22671                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22672                    }
22673                }
22674            }
22675        }
22676
22677        // Ensure that data directories are ready to roll for all packages
22678        // installed for this volume and user
22679        final List<PackageSetting> packages;
22680        synchronized (mPackages) {
22681            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22682        }
22683        int preparedCount = 0;
22684        for (PackageSetting ps : packages) {
22685            final String packageName = ps.name;
22686            if (ps.pkg == null) {
22687                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22688                // TODO: might be due to legacy ASEC apps; we should circle back
22689                // and reconcile again once they're scanned
22690                continue;
22691            }
22692            // Skip non-core apps if requested
22693            if (onlyCoreApps && !ps.pkg.coreApp) {
22694                result.add(packageName);
22695                continue;
22696            }
22697
22698            if (ps.getInstalled(userId)) {
22699                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22700                preparedCount++;
22701            }
22702        }
22703
22704        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22705        return result;
22706    }
22707
22708    /**
22709     * Prepare app data for the given app just after it was installed or
22710     * upgraded. This method carefully only touches users that it's installed
22711     * for, and it forces a restorecon to handle any seinfo changes.
22712     * <p>
22713     * Verifies that directories exist and that ownership and labeling is
22714     * correct for all installed apps. If there is an ownership mismatch, it
22715     * will try recovering system apps by wiping data; third-party app data is
22716     * left intact.
22717     * <p>
22718     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22719     */
22720    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22721        final PackageSetting ps;
22722        synchronized (mPackages) {
22723            ps = mSettings.mPackages.get(pkg.packageName);
22724            mSettings.writeKernelMappingLPr(ps);
22725        }
22726
22727        final UserManager um = mContext.getSystemService(UserManager.class);
22728        UserManagerInternal umInternal = getUserManagerInternal();
22729        for (UserInfo user : um.getUsers()) {
22730            final int flags;
22731            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22732                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22733            } else if (umInternal.isUserRunning(user.id)) {
22734                flags = StorageManager.FLAG_STORAGE_DE;
22735            } else {
22736                continue;
22737            }
22738
22739            if (ps.getInstalled(user.id)) {
22740                // TODO: when user data is locked, mark that we're still dirty
22741                prepareAppDataLIF(pkg, user.id, flags);
22742            }
22743        }
22744    }
22745
22746    /**
22747     * Prepare app data for the given app.
22748     * <p>
22749     * Verifies that directories exist and that ownership and labeling is
22750     * correct for all installed apps. If there is an ownership mismatch, this
22751     * will try recovering system apps by wiping data; third-party app data is
22752     * left intact.
22753     */
22754    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22755        if (pkg == null) {
22756            Slog.wtf(TAG, "Package was null!", new Throwable());
22757            return;
22758        }
22759        prepareAppDataLeafLIF(pkg, userId, flags);
22760        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22761        for (int i = 0; i < childCount; i++) {
22762            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22763        }
22764    }
22765
22766    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22767            boolean maybeMigrateAppData) {
22768        prepareAppDataLIF(pkg, userId, flags);
22769
22770        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22771            // We may have just shuffled around app data directories, so
22772            // prepare them one more time
22773            prepareAppDataLIF(pkg, userId, flags);
22774        }
22775    }
22776
22777    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22778        if (DEBUG_APP_DATA) {
22779            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22780                    + Integer.toHexString(flags));
22781        }
22782
22783        final String volumeUuid = pkg.volumeUuid;
22784        final String packageName = pkg.packageName;
22785        final ApplicationInfo app = pkg.applicationInfo;
22786        final int appId = UserHandle.getAppId(app.uid);
22787
22788        Preconditions.checkNotNull(app.seInfo);
22789
22790        long ceDataInode = -1;
22791        try {
22792            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22793                    appId, app.seInfo, app.targetSdkVersion);
22794        } catch (InstallerException e) {
22795            if (app.isSystemApp()) {
22796                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22797                        + ", but trying to recover: " + e);
22798                destroyAppDataLeafLIF(pkg, userId, flags);
22799                try {
22800                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22801                            appId, app.seInfo, app.targetSdkVersion);
22802                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22803                } catch (InstallerException e2) {
22804                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22805                }
22806            } else {
22807                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22808            }
22809        }
22810
22811        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22812            // TODO: mark this structure as dirty so we persist it!
22813            synchronized (mPackages) {
22814                final PackageSetting ps = mSettings.mPackages.get(packageName);
22815                if (ps != null) {
22816                    ps.setCeDataInode(ceDataInode, userId);
22817                }
22818            }
22819        }
22820
22821        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22822    }
22823
22824    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22825        if (pkg == null) {
22826            Slog.wtf(TAG, "Package was null!", new Throwable());
22827            return;
22828        }
22829        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22830        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22831        for (int i = 0; i < childCount; i++) {
22832            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22833        }
22834    }
22835
22836    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22837        final String volumeUuid = pkg.volumeUuid;
22838        final String packageName = pkg.packageName;
22839        final ApplicationInfo app = pkg.applicationInfo;
22840
22841        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22842            // Create a native library symlink only if we have native libraries
22843            // and if the native libraries are 32 bit libraries. We do not provide
22844            // this symlink for 64 bit libraries.
22845            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22846                final String nativeLibPath = app.nativeLibraryDir;
22847                try {
22848                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22849                            nativeLibPath, userId);
22850                } catch (InstallerException e) {
22851                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22852                }
22853            }
22854        }
22855    }
22856
22857    /**
22858     * For system apps on non-FBE devices, this method migrates any existing
22859     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22860     * requested by the app.
22861     */
22862    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22863        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22864                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22865            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22866                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22867            try {
22868                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22869                        storageTarget);
22870            } catch (InstallerException e) {
22871                logCriticalInfo(Log.WARN,
22872                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22873            }
22874            return true;
22875        } else {
22876            return false;
22877        }
22878    }
22879
22880    public PackageFreezer freezePackage(String packageName, String killReason) {
22881        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22882    }
22883
22884    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22885        return new PackageFreezer(packageName, userId, killReason);
22886    }
22887
22888    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22889            String killReason) {
22890        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22891    }
22892
22893    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22894            String killReason) {
22895        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22896            return new PackageFreezer();
22897        } else {
22898            return freezePackage(packageName, userId, killReason);
22899        }
22900    }
22901
22902    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22903            String killReason) {
22904        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22905    }
22906
22907    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22908            String killReason) {
22909        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22910            return new PackageFreezer();
22911        } else {
22912            return freezePackage(packageName, userId, killReason);
22913        }
22914    }
22915
22916    /**
22917     * Class that freezes and kills the given package upon creation, and
22918     * unfreezes it upon closing. This is typically used when doing surgery on
22919     * app code/data to prevent the app from running while you're working.
22920     */
22921    private class PackageFreezer implements AutoCloseable {
22922        private final String mPackageName;
22923        private final PackageFreezer[] mChildren;
22924
22925        private final boolean mWeFroze;
22926
22927        private final AtomicBoolean mClosed = new AtomicBoolean();
22928        private final CloseGuard mCloseGuard = CloseGuard.get();
22929
22930        /**
22931         * Create and return a stub freezer that doesn't actually do anything,
22932         * typically used when someone requested
22933         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22934         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22935         */
22936        public PackageFreezer() {
22937            mPackageName = null;
22938            mChildren = null;
22939            mWeFroze = false;
22940            mCloseGuard.open("close");
22941        }
22942
22943        public PackageFreezer(String packageName, int userId, String killReason) {
22944            synchronized (mPackages) {
22945                mPackageName = packageName;
22946                mWeFroze = mFrozenPackages.add(mPackageName);
22947
22948                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22949                if (ps != null) {
22950                    killApplication(ps.name, ps.appId, userId, killReason);
22951                }
22952
22953                final PackageParser.Package p = mPackages.get(packageName);
22954                if (p != null && p.childPackages != null) {
22955                    final int N = p.childPackages.size();
22956                    mChildren = new PackageFreezer[N];
22957                    for (int i = 0; i < N; i++) {
22958                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22959                                userId, killReason);
22960                    }
22961                } else {
22962                    mChildren = null;
22963                }
22964            }
22965            mCloseGuard.open("close");
22966        }
22967
22968        @Override
22969        protected void finalize() throws Throwable {
22970            try {
22971                mCloseGuard.warnIfOpen();
22972                close();
22973            } finally {
22974                super.finalize();
22975            }
22976        }
22977
22978        @Override
22979        public void close() {
22980            mCloseGuard.close();
22981            if (mClosed.compareAndSet(false, true)) {
22982                synchronized (mPackages) {
22983                    if (mWeFroze) {
22984                        mFrozenPackages.remove(mPackageName);
22985                    }
22986
22987                    if (mChildren != null) {
22988                        for (PackageFreezer freezer : mChildren) {
22989                            freezer.close();
22990                        }
22991                    }
22992                }
22993            }
22994        }
22995    }
22996
22997    /**
22998     * Verify that given package is currently frozen.
22999     */
23000    private void checkPackageFrozen(String packageName) {
23001        synchronized (mPackages) {
23002            if (!mFrozenPackages.contains(packageName)) {
23003                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23004            }
23005        }
23006    }
23007
23008    @Override
23009    public int movePackage(final String packageName, final String volumeUuid) {
23010        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23011
23012        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
23013        final int moveId = mNextMoveId.getAndIncrement();
23014        mHandler.post(new Runnable() {
23015            @Override
23016            public void run() {
23017                try {
23018                    movePackageInternal(packageName, volumeUuid, moveId, user);
23019                } catch (PackageManagerException e) {
23020                    Slog.w(TAG, "Failed to move " + packageName, e);
23021                    mMoveCallbacks.notifyStatusChanged(moveId,
23022                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23023                }
23024            }
23025        });
23026        return moveId;
23027    }
23028
23029    private void movePackageInternal(final String packageName, final String volumeUuid,
23030            final int moveId, UserHandle user) throws PackageManagerException {
23031        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23032        final PackageManager pm = mContext.getPackageManager();
23033
23034        final boolean currentAsec;
23035        final String currentVolumeUuid;
23036        final File codeFile;
23037        final String installerPackageName;
23038        final String packageAbiOverride;
23039        final int appId;
23040        final String seinfo;
23041        final String label;
23042        final int targetSdkVersion;
23043        final PackageFreezer freezer;
23044        final int[] installedUserIds;
23045
23046        // reader
23047        synchronized (mPackages) {
23048            final PackageParser.Package pkg = mPackages.get(packageName);
23049            final PackageSetting ps = mSettings.mPackages.get(packageName);
23050            if (pkg == null || ps == null) {
23051                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23052            }
23053
23054            if (pkg.applicationInfo.isSystemApp()) {
23055                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23056                        "Cannot move system application");
23057            }
23058
23059            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23060            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23061                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23062            if (isInternalStorage && !allow3rdPartyOnInternal) {
23063                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23064                        "3rd party apps are not allowed on internal storage");
23065            }
23066
23067            if (pkg.applicationInfo.isExternalAsec()) {
23068                currentAsec = true;
23069                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
23070            } else if (pkg.applicationInfo.isForwardLocked()) {
23071                currentAsec = true;
23072                currentVolumeUuid = "forward_locked";
23073            } else {
23074                currentAsec = false;
23075                currentVolumeUuid = ps.volumeUuid;
23076
23077                final File probe = new File(pkg.codePath);
23078                final File probeOat = new File(probe, "oat");
23079                if (!probe.isDirectory() || !probeOat.isDirectory()) {
23080                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23081                            "Move only supported for modern cluster style installs");
23082                }
23083            }
23084
23085            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23086                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23087                        "Package already moved to " + volumeUuid);
23088            }
23089            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23090                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23091                        "Device admin cannot be moved");
23092            }
23093
23094            if (mFrozenPackages.contains(packageName)) {
23095                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23096                        "Failed to move already frozen package");
23097            }
23098
23099            codeFile = new File(pkg.codePath);
23100            installerPackageName = ps.installerPackageName;
23101            packageAbiOverride = ps.cpuAbiOverrideString;
23102            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23103            seinfo = pkg.applicationInfo.seInfo;
23104            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23105            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23106            freezer = freezePackage(packageName, "movePackageInternal");
23107            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23108        }
23109
23110        final Bundle extras = new Bundle();
23111        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23112        extras.putString(Intent.EXTRA_TITLE, label);
23113        mMoveCallbacks.notifyCreated(moveId, extras);
23114
23115        int installFlags;
23116        final boolean moveCompleteApp;
23117        final File measurePath;
23118
23119        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23120            installFlags = INSTALL_INTERNAL;
23121            moveCompleteApp = !currentAsec;
23122            measurePath = Environment.getDataAppDirectory(volumeUuid);
23123        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23124            installFlags = INSTALL_EXTERNAL;
23125            moveCompleteApp = false;
23126            measurePath = storage.getPrimaryPhysicalVolume().getPath();
23127        } else {
23128            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23129            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23130                    || !volume.isMountedWritable()) {
23131                freezer.close();
23132                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23133                        "Move location not mounted private volume");
23134            }
23135
23136            Preconditions.checkState(!currentAsec);
23137
23138            installFlags = INSTALL_INTERNAL;
23139            moveCompleteApp = true;
23140            measurePath = Environment.getDataAppDirectory(volumeUuid);
23141        }
23142
23143        final PackageStats stats = new PackageStats(null, -1);
23144        synchronized (mInstaller) {
23145            for (int userId : installedUserIds) {
23146                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23147                    freezer.close();
23148                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23149                            "Failed to measure package size");
23150                }
23151            }
23152        }
23153
23154        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23155                + stats.dataSize);
23156
23157        final long startFreeBytes = measurePath.getUsableSpace();
23158        final long sizeBytes;
23159        if (moveCompleteApp) {
23160            sizeBytes = stats.codeSize + stats.dataSize;
23161        } else {
23162            sizeBytes = stats.codeSize;
23163        }
23164
23165        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23166            freezer.close();
23167            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23168                    "Not enough free space to move");
23169        }
23170
23171        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23172
23173        final CountDownLatch installedLatch = new CountDownLatch(1);
23174        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23175            @Override
23176            public void onUserActionRequired(Intent intent) throws RemoteException {
23177                throw new IllegalStateException();
23178            }
23179
23180            @Override
23181            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23182                    Bundle extras) throws RemoteException {
23183                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23184                        + PackageManager.installStatusToString(returnCode, msg));
23185
23186                installedLatch.countDown();
23187                freezer.close();
23188
23189                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23190                switch (status) {
23191                    case PackageInstaller.STATUS_SUCCESS:
23192                        mMoveCallbacks.notifyStatusChanged(moveId,
23193                                PackageManager.MOVE_SUCCEEDED);
23194                        break;
23195                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23196                        mMoveCallbacks.notifyStatusChanged(moveId,
23197                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23198                        break;
23199                    default:
23200                        mMoveCallbacks.notifyStatusChanged(moveId,
23201                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23202                        break;
23203                }
23204            }
23205        };
23206
23207        final MoveInfo move;
23208        if (moveCompleteApp) {
23209            // Kick off a thread to report progress estimates
23210            new Thread() {
23211                @Override
23212                public void run() {
23213                    while (true) {
23214                        try {
23215                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23216                                break;
23217                            }
23218                        } catch (InterruptedException ignored) {
23219                        }
23220
23221                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23222                        final int progress = 10 + (int) MathUtils.constrain(
23223                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23224                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23225                    }
23226                }
23227            }.start();
23228
23229            final String dataAppName = codeFile.getName();
23230            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23231                    dataAppName, appId, seinfo, targetSdkVersion);
23232        } else {
23233            move = null;
23234        }
23235
23236        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23237
23238        final Message msg = mHandler.obtainMessage(INIT_COPY);
23239        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23240        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23241                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23242                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23243                PackageManager.INSTALL_REASON_UNKNOWN);
23244        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23245        msg.obj = params;
23246
23247        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23248                System.identityHashCode(msg.obj));
23249        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23250                System.identityHashCode(msg.obj));
23251
23252        mHandler.sendMessage(msg);
23253    }
23254
23255    @Override
23256    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23257        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23258
23259        final int realMoveId = mNextMoveId.getAndIncrement();
23260        final Bundle extras = new Bundle();
23261        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23262        mMoveCallbacks.notifyCreated(realMoveId, extras);
23263
23264        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23265            @Override
23266            public void onCreated(int moveId, Bundle extras) {
23267                // Ignored
23268            }
23269
23270            @Override
23271            public void onStatusChanged(int moveId, int status, long estMillis) {
23272                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23273            }
23274        };
23275
23276        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23277        storage.setPrimaryStorageUuid(volumeUuid, callback);
23278        return realMoveId;
23279    }
23280
23281    @Override
23282    public int getMoveStatus(int moveId) {
23283        mContext.enforceCallingOrSelfPermission(
23284                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23285        return mMoveCallbacks.mLastStatus.get(moveId);
23286    }
23287
23288    @Override
23289    public void registerMoveCallback(IPackageMoveObserver callback) {
23290        mContext.enforceCallingOrSelfPermission(
23291                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23292        mMoveCallbacks.register(callback);
23293    }
23294
23295    @Override
23296    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23297        mContext.enforceCallingOrSelfPermission(
23298                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23299        mMoveCallbacks.unregister(callback);
23300    }
23301
23302    @Override
23303    public boolean setInstallLocation(int loc) {
23304        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23305                null);
23306        if (getInstallLocation() == loc) {
23307            return true;
23308        }
23309        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23310                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23311            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23312                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23313            return true;
23314        }
23315        return false;
23316   }
23317
23318    @Override
23319    public int getInstallLocation() {
23320        // allow instant app access
23321        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23322                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23323                PackageHelper.APP_INSTALL_AUTO);
23324    }
23325
23326    /** Called by UserManagerService */
23327    void cleanUpUser(UserManagerService userManager, int userHandle) {
23328        synchronized (mPackages) {
23329            mDirtyUsers.remove(userHandle);
23330            mUserNeedsBadging.delete(userHandle);
23331            mSettings.removeUserLPw(userHandle);
23332            mPendingBroadcasts.remove(userHandle);
23333            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23334            removeUnusedPackagesLPw(userManager, userHandle);
23335        }
23336    }
23337
23338    /**
23339     * We're removing userHandle and would like to remove any downloaded packages
23340     * that are no longer in use by any other user.
23341     * @param userHandle the user being removed
23342     */
23343    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23344        final boolean DEBUG_CLEAN_APKS = false;
23345        int [] users = userManager.getUserIds();
23346        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23347        while (psit.hasNext()) {
23348            PackageSetting ps = psit.next();
23349            if (ps.pkg == null) {
23350                continue;
23351            }
23352            final String packageName = ps.pkg.packageName;
23353            // Skip over if system app
23354            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23355                continue;
23356            }
23357            if (DEBUG_CLEAN_APKS) {
23358                Slog.i(TAG, "Checking package " + packageName);
23359            }
23360            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23361            if (keep) {
23362                if (DEBUG_CLEAN_APKS) {
23363                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23364                }
23365            } else {
23366                for (int i = 0; i < users.length; i++) {
23367                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23368                        keep = true;
23369                        if (DEBUG_CLEAN_APKS) {
23370                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23371                                    + users[i]);
23372                        }
23373                        break;
23374                    }
23375                }
23376            }
23377            if (!keep) {
23378                if (DEBUG_CLEAN_APKS) {
23379                    Slog.i(TAG, "  Removing package " + packageName);
23380                }
23381                mHandler.post(new Runnable() {
23382                    public void run() {
23383                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23384                                userHandle, 0);
23385                    } //end run
23386                });
23387            }
23388        }
23389    }
23390
23391    /** Called by UserManagerService */
23392    void createNewUser(int userId, String[] disallowedPackages) {
23393        synchronized (mInstallLock) {
23394            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23395        }
23396        synchronized (mPackages) {
23397            scheduleWritePackageRestrictionsLocked(userId);
23398            scheduleWritePackageListLocked(userId);
23399            applyFactoryDefaultBrowserLPw(userId);
23400            primeDomainVerificationsLPw(userId);
23401        }
23402    }
23403
23404    void onNewUserCreated(final int userId) {
23405        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23406        // If permission review for legacy apps is required, we represent
23407        // dagerous permissions for such apps as always granted runtime
23408        // permissions to keep per user flag state whether review is needed.
23409        // Hence, if a new user is added we have to propagate dangerous
23410        // permission grants for these legacy apps.
23411        if (mPermissionReviewRequired) {
23412            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23413                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23414        }
23415    }
23416
23417    @Override
23418    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23419        mContext.enforceCallingOrSelfPermission(
23420                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23421                "Only package verification agents can read the verifier device identity");
23422
23423        synchronized (mPackages) {
23424            return mSettings.getVerifierDeviceIdentityLPw();
23425        }
23426    }
23427
23428    @Override
23429    public void setPermissionEnforced(String permission, boolean enforced) {
23430        // TODO: Now that we no longer change GID for storage, this should to away.
23431        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23432                "setPermissionEnforced");
23433        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23434            synchronized (mPackages) {
23435                if (mSettings.mReadExternalStorageEnforced == null
23436                        || mSettings.mReadExternalStorageEnforced != enforced) {
23437                    mSettings.mReadExternalStorageEnforced = enforced;
23438                    mSettings.writeLPr();
23439                }
23440            }
23441            // kill any non-foreground processes so we restart them and
23442            // grant/revoke the GID.
23443            final IActivityManager am = ActivityManager.getService();
23444            if (am != null) {
23445                final long token = Binder.clearCallingIdentity();
23446                try {
23447                    am.killProcessesBelowForeground("setPermissionEnforcement");
23448                } catch (RemoteException e) {
23449                } finally {
23450                    Binder.restoreCallingIdentity(token);
23451                }
23452            }
23453        } else {
23454            throw new IllegalArgumentException("No selective enforcement for " + permission);
23455        }
23456    }
23457
23458    @Override
23459    @Deprecated
23460    public boolean isPermissionEnforced(String permission) {
23461        // allow instant applications
23462        return true;
23463    }
23464
23465    @Override
23466    public boolean isStorageLow() {
23467        // allow instant applications
23468        final long token = Binder.clearCallingIdentity();
23469        try {
23470            final DeviceStorageMonitorInternal
23471                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23472            if (dsm != null) {
23473                return dsm.isMemoryLow();
23474            } else {
23475                return false;
23476            }
23477        } finally {
23478            Binder.restoreCallingIdentity(token);
23479        }
23480    }
23481
23482    @Override
23483    public IPackageInstaller getPackageInstaller() {
23484        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23485            return null;
23486        }
23487        return mInstallerService;
23488    }
23489
23490    private boolean userNeedsBadging(int userId) {
23491        int index = mUserNeedsBadging.indexOfKey(userId);
23492        if (index < 0) {
23493            final UserInfo userInfo;
23494            final long token = Binder.clearCallingIdentity();
23495            try {
23496                userInfo = sUserManager.getUserInfo(userId);
23497            } finally {
23498                Binder.restoreCallingIdentity(token);
23499            }
23500            final boolean b;
23501            if (userInfo != null && userInfo.isManagedProfile()) {
23502                b = true;
23503            } else {
23504                b = false;
23505            }
23506            mUserNeedsBadging.put(userId, b);
23507            return b;
23508        }
23509        return mUserNeedsBadging.valueAt(index);
23510    }
23511
23512    @Override
23513    public KeySet getKeySetByAlias(String packageName, String alias) {
23514        if (packageName == null || alias == null) {
23515            return null;
23516        }
23517        synchronized(mPackages) {
23518            final PackageParser.Package pkg = mPackages.get(packageName);
23519            if (pkg == null) {
23520                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23521                throw new IllegalArgumentException("Unknown package: " + packageName);
23522            }
23523            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23524            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23525        }
23526    }
23527
23528    @Override
23529    public KeySet getSigningKeySet(String packageName) {
23530        if (packageName == null) {
23531            return null;
23532        }
23533        synchronized(mPackages) {
23534            final PackageParser.Package pkg = mPackages.get(packageName);
23535            if (pkg == null) {
23536                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23537                throw new IllegalArgumentException("Unknown package: " + packageName);
23538            }
23539            if (pkg.applicationInfo.uid != Binder.getCallingUid()
23540                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
23541                throw new SecurityException("May not access signing KeySet of other apps.");
23542            }
23543            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23544            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23545        }
23546    }
23547
23548    @Override
23549    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23550        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23551            return false;
23552        }
23553        if (packageName == null || ks == null) {
23554            return false;
23555        }
23556        synchronized(mPackages) {
23557            final PackageParser.Package pkg = mPackages.get(packageName);
23558            if (pkg == null) {
23559                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23560                throw new IllegalArgumentException("Unknown package: " + packageName);
23561            }
23562            IBinder ksh = ks.getToken();
23563            if (ksh instanceof KeySetHandle) {
23564                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23565                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23566            }
23567            return false;
23568        }
23569    }
23570
23571    @Override
23572    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23573        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23574            return false;
23575        }
23576        if (packageName == null || ks == null) {
23577            return false;
23578        }
23579        synchronized(mPackages) {
23580            final PackageParser.Package pkg = mPackages.get(packageName);
23581            if (pkg == null) {
23582                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23583                throw new IllegalArgumentException("Unknown package: " + packageName);
23584            }
23585            IBinder ksh = ks.getToken();
23586            if (ksh instanceof KeySetHandle) {
23587                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23588                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23589            }
23590            return false;
23591        }
23592    }
23593
23594    private void deletePackageIfUnusedLPr(final String packageName) {
23595        PackageSetting ps = mSettings.mPackages.get(packageName);
23596        if (ps == null) {
23597            return;
23598        }
23599        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23600            // TODO Implement atomic delete if package is unused
23601            // It is currently possible that the package will be deleted even if it is installed
23602            // after this method returns.
23603            mHandler.post(new Runnable() {
23604                public void run() {
23605                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23606                            0, PackageManager.DELETE_ALL_USERS);
23607                }
23608            });
23609        }
23610    }
23611
23612    /**
23613     * Check and throw if the given before/after packages would be considered a
23614     * downgrade.
23615     */
23616    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23617            throws PackageManagerException {
23618        if (after.versionCode < before.mVersionCode) {
23619            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23620                    "Update version code " + after.versionCode + " is older than current "
23621                    + before.mVersionCode);
23622        } else if (after.versionCode == before.mVersionCode) {
23623            if (after.baseRevisionCode < before.baseRevisionCode) {
23624                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23625                        "Update base revision code " + after.baseRevisionCode
23626                        + " is older than current " + before.baseRevisionCode);
23627            }
23628
23629            if (!ArrayUtils.isEmpty(after.splitNames)) {
23630                for (int i = 0; i < after.splitNames.length; i++) {
23631                    final String splitName = after.splitNames[i];
23632                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23633                    if (j != -1) {
23634                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23635                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23636                                    "Update split " + splitName + " revision code "
23637                                    + after.splitRevisionCodes[i] + " is older than current "
23638                                    + before.splitRevisionCodes[j]);
23639                        }
23640                    }
23641                }
23642            }
23643        }
23644    }
23645
23646    private static class MoveCallbacks extends Handler {
23647        private static final int MSG_CREATED = 1;
23648        private static final int MSG_STATUS_CHANGED = 2;
23649
23650        private final RemoteCallbackList<IPackageMoveObserver>
23651                mCallbacks = new RemoteCallbackList<>();
23652
23653        private final SparseIntArray mLastStatus = new SparseIntArray();
23654
23655        public MoveCallbacks(Looper looper) {
23656            super(looper);
23657        }
23658
23659        public void register(IPackageMoveObserver callback) {
23660            mCallbacks.register(callback);
23661        }
23662
23663        public void unregister(IPackageMoveObserver callback) {
23664            mCallbacks.unregister(callback);
23665        }
23666
23667        @Override
23668        public void handleMessage(Message msg) {
23669            final SomeArgs args = (SomeArgs) msg.obj;
23670            final int n = mCallbacks.beginBroadcast();
23671            for (int i = 0; i < n; i++) {
23672                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23673                try {
23674                    invokeCallback(callback, msg.what, args);
23675                } catch (RemoteException ignored) {
23676                }
23677            }
23678            mCallbacks.finishBroadcast();
23679            args.recycle();
23680        }
23681
23682        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23683                throws RemoteException {
23684            switch (what) {
23685                case MSG_CREATED: {
23686                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23687                    break;
23688                }
23689                case MSG_STATUS_CHANGED: {
23690                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23691                    break;
23692                }
23693            }
23694        }
23695
23696        private void notifyCreated(int moveId, Bundle extras) {
23697            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23698
23699            final SomeArgs args = SomeArgs.obtain();
23700            args.argi1 = moveId;
23701            args.arg2 = extras;
23702            obtainMessage(MSG_CREATED, args).sendToTarget();
23703        }
23704
23705        private void notifyStatusChanged(int moveId, int status) {
23706            notifyStatusChanged(moveId, status, -1);
23707        }
23708
23709        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23710            Slog.v(TAG, "Move " + moveId + " status " + status);
23711
23712            final SomeArgs args = SomeArgs.obtain();
23713            args.argi1 = moveId;
23714            args.argi2 = status;
23715            args.arg3 = estMillis;
23716            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23717
23718            synchronized (mLastStatus) {
23719                mLastStatus.put(moveId, status);
23720            }
23721        }
23722    }
23723
23724    private final static class OnPermissionChangeListeners extends Handler {
23725        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23726
23727        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23728                new RemoteCallbackList<>();
23729
23730        public OnPermissionChangeListeners(Looper looper) {
23731            super(looper);
23732        }
23733
23734        @Override
23735        public void handleMessage(Message msg) {
23736            switch (msg.what) {
23737                case MSG_ON_PERMISSIONS_CHANGED: {
23738                    final int uid = msg.arg1;
23739                    handleOnPermissionsChanged(uid);
23740                } break;
23741            }
23742        }
23743
23744        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23745            mPermissionListeners.register(listener);
23746
23747        }
23748
23749        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23750            mPermissionListeners.unregister(listener);
23751        }
23752
23753        public void onPermissionsChanged(int uid) {
23754            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23755                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23756            }
23757        }
23758
23759        private void handleOnPermissionsChanged(int uid) {
23760            final int count = mPermissionListeners.beginBroadcast();
23761            try {
23762                for (int i = 0; i < count; i++) {
23763                    IOnPermissionsChangeListener callback = mPermissionListeners
23764                            .getBroadcastItem(i);
23765                    try {
23766                        callback.onPermissionsChanged(uid);
23767                    } catch (RemoteException e) {
23768                        Log.e(TAG, "Permission listener is dead", e);
23769                    }
23770                }
23771            } finally {
23772                mPermissionListeners.finishBroadcast();
23773            }
23774        }
23775    }
23776
23777    private class PackageManagerInternalImpl extends PackageManagerInternal {
23778        @Override
23779        public void setLocationPackagesProvider(PackagesProvider provider) {
23780            synchronized (mPackages) {
23781                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23782            }
23783        }
23784
23785        @Override
23786        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23787            synchronized (mPackages) {
23788                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23789            }
23790        }
23791
23792        @Override
23793        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23794            synchronized (mPackages) {
23795                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23796            }
23797        }
23798
23799        @Override
23800        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23801            synchronized (mPackages) {
23802                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23803            }
23804        }
23805
23806        @Override
23807        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23808            synchronized (mPackages) {
23809                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23810            }
23811        }
23812
23813        @Override
23814        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23815            synchronized (mPackages) {
23816                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23817            }
23818        }
23819
23820        @Override
23821        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23822            synchronized (mPackages) {
23823                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23824                        packageName, userId);
23825            }
23826        }
23827
23828        @Override
23829        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23830            synchronized (mPackages) {
23831                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23832                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23833                        packageName, userId);
23834            }
23835        }
23836
23837        @Override
23838        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23839            synchronized (mPackages) {
23840                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23841                        packageName, userId);
23842            }
23843        }
23844
23845        @Override
23846        public void setKeepUninstalledPackages(final List<String> packageList) {
23847            Preconditions.checkNotNull(packageList);
23848            List<String> removedFromList = null;
23849            synchronized (mPackages) {
23850                if (mKeepUninstalledPackages != null) {
23851                    final int packagesCount = mKeepUninstalledPackages.size();
23852                    for (int i = 0; i < packagesCount; i++) {
23853                        String oldPackage = mKeepUninstalledPackages.get(i);
23854                        if (packageList != null && packageList.contains(oldPackage)) {
23855                            continue;
23856                        }
23857                        if (removedFromList == null) {
23858                            removedFromList = new ArrayList<>();
23859                        }
23860                        removedFromList.add(oldPackage);
23861                    }
23862                }
23863                mKeepUninstalledPackages = new ArrayList<>(packageList);
23864                if (removedFromList != null) {
23865                    final int removedCount = removedFromList.size();
23866                    for (int i = 0; i < removedCount; i++) {
23867                        deletePackageIfUnusedLPr(removedFromList.get(i));
23868                    }
23869                }
23870            }
23871        }
23872
23873        @Override
23874        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23875            synchronized (mPackages) {
23876                // If we do not support permission review, done.
23877                if (!mPermissionReviewRequired) {
23878                    return false;
23879                }
23880
23881                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23882                if (packageSetting == null) {
23883                    return false;
23884                }
23885
23886                // Permission review applies only to apps not supporting the new permission model.
23887                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23888                    return false;
23889                }
23890
23891                // Legacy apps have the permission and get user consent on launch.
23892                PermissionsState permissionsState = packageSetting.getPermissionsState();
23893                return permissionsState.isPermissionReviewRequired(userId);
23894            }
23895        }
23896
23897        @Override
23898        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23899            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23900        }
23901
23902        @Override
23903        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23904                int userId) {
23905            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23906        }
23907
23908        @Override
23909        public void setDeviceAndProfileOwnerPackages(
23910                int deviceOwnerUserId, String deviceOwnerPackage,
23911                SparseArray<String> profileOwnerPackages) {
23912            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23913                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23914        }
23915
23916        @Override
23917        public boolean isPackageDataProtected(int userId, String packageName) {
23918            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23919        }
23920
23921        @Override
23922        public boolean isPackageEphemeral(int userId, String packageName) {
23923            synchronized (mPackages) {
23924                final PackageSetting ps = mSettings.mPackages.get(packageName);
23925                return ps != null ? ps.getInstantApp(userId) : false;
23926            }
23927        }
23928
23929        @Override
23930        public boolean wasPackageEverLaunched(String packageName, int userId) {
23931            synchronized (mPackages) {
23932                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23933            }
23934        }
23935
23936        @Override
23937        public void grantRuntimePermission(String packageName, String name, int userId,
23938                boolean overridePolicy) {
23939            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23940                    overridePolicy);
23941        }
23942
23943        @Override
23944        public void revokeRuntimePermission(String packageName, String name, int userId,
23945                boolean overridePolicy) {
23946            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23947                    overridePolicy);
23948        }
23949
23950        @Override
23951        public String getNameForUid(int uid) {
23952            return PackageManagerService.this.getNameForUid(uid);
23953        }
23954
23955        @Override
23956        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23957                Intent origIntent, String resolvedType, String callingPackage,
23958                Bundle verificationBundle, int userId) {
23959            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23960                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23961                    userId);
23962        }
23963
23964        @Override
23965        public void grantEphemeralAccess(int userId, Intent intent,
23966                int targetAppId, int ephemeralAppId) {
23967            synchronized (mPackages) {
23968                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23969                        targetAppId, ephemeralAppId);
23970            }
23971        }
23972
23973        @Override
23974        public boolean isInstantAppInstallerComponent(ComponentName component) {
23975            synchronized (mPackages) {
23976                return mInstantAppInstallerActivity != null
23977                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23978            }
23979        }
23980
23981        @Override
23982        public void pruneInstantApps() {
23983            synchronized (mPackages) {
23984                mInstantAppRegistry.pruneInstantAppsLPw();
23985            }
23986        }
23987
23988        @Override
23989        public String getSetupWizardPackageName() {
23990            return mSetupWizardPackage;
23991        }
23992
23993        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23994            if (policy != null) {
23995                mExternalSourcesPolicy = policy;
23996            }
23997        }
23998
23999        @Override
24000        public boolean isPackagePersistent(String packageName) {
24001            synchronized (mPackages) {
24002                PackageParser.Package pkg = mPackages.get(packageName);
24003                return pkg != null
24004                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24005                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
24006                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24007                        : false;
24008            }
24009        }
24010
24011        @Override
24012        public List<PackageInfo> getOverlayPackages(int userId) {
24013            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24014            synchronized (mPackages) {
24015                for (PackageParser.Package p : mPackages.values()) {
24016                    if (p.mOverlayTarget != null) {
24017                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24018                        if (pkg != null) {
24019                            overlayPackages.add(pkg);
24020                        }
24021                    }
24022                }
24023            }
24024            return overlayPackages;
24025        }
24026
24027        @Override
24028        public List<String> getTargetPackageNames(int userId) {
24029            List<String> targetPackages = new ArrayList<>();
24030            synchronized (mPackages) {
24031                for (PackageParser.Package p : mPackages.values()) {
24032                    if (p.mOverlayTarget == null) {
24033                        targetPackages.add(p.packageName);
24034                    }
24035                }
24036            }
24037            return targetPackages;
24038        }
24039
24040        @Override
24041        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24042                @Nullable List<String> overlayPackageNames) {
24043            synchronized (mPackages) {
24044                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24045                    Slog.e(TAG, "failed to find package " + targetPackageName);
24046                    return false;
24047                }
24048
24049                ArrayList<String> paths = null;
24050                if (overlayPackageNames != null) {
24051                    final int N = overlayPackageNames.size();
24052                    paths = new ArrayList<>(N);
24053                    for (int i = 0; i < N; i++) {
24054                        final String packageName = overlayPackageNames.get(i);
24055                        final PackageParser.Package pkg = mPackages.get(packageName);
24056                        if (pkg == null) {
24057                            Slog.e(TAG, "failed to find package " + packageName);
24058                            return false;
24059                        }
24060                        paths.add(pkg.baseCodePath);
24061                    }
24062                }
24063
24064                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
24065                    mEnabledOverlayPaths.get(userId);
24066                if (userSpecificOverlays == null) {
24067                    userSpecificOverlays = new ArrayMap<>();
24068                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
24069                }
24070
24071                if (paths != null && paths.size() > 0) {
24072                    userSpecificOverlays.put(targetPackageName, paths);
24073                } else {
24074                    userSpecificOverlays.remove(targetPackageName);
24075                }
24076                return true;
24077            }
24078        }
24079
24080        @Override
24081        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24082                int flags, int userId) {
24083            return resolveIntentInternal(
24084                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
24085        }
24086
24087        @Override
24088        public ResolveInfo resolveService(Intent intent, String resolvedType,
24089                int flags, int userId, int callingUid) {
24090            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24091        }
24092
24093        @Override
24094        public void addIsolatedUid(int isolatedUid, int ownerUid) {
24095            synchronized (mPackages) {
24096                mIsolatedOwners.put(isolatedUid, ownerUid);
24097            }
24098        }
24099
24100        @Override
24101        public void removeIsolatedUid(int isolatedUid) {
24102            synchronized (mPackages) {
24103                mIsolatedOwners.delete(isolatedUid);
24104            }
24105        }
24106
24107        @Override
24108        public int getUidTargetSdkVersion(int uid) {
24109            synchronized (mPackages) {
24110                return getUidTargetSdkVersionLockedLPr(uid);
24111            }
24112        }
24113
24114        @Override
24115        public boolean canAccessInstantApps(int callingUid) {
24116            return PackageManagerService.this.canAccessInstantApps(callingUid);
24117        }
24118    }
24119
24120    @Override
24121    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24122        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24123        synchronized (mPackages) {
24124            final long identity = Binder.clearCallingIdentity();
24125            try {
24126                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
24127                        packageNames, userId);
24128            } finally {
24129                Binder.restoreCallingIdentity(identity);
24130            }
24131        }
24132    }
24133
24134    @Override
24135    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24136        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24137        synchronized (mPackages) {
24138            final long identity = Binder.clearCallingIdentity();
24139            try {
24140                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
24141                        packageNames, userId);
24142            } finally {
24143                Binder.restoreCallingIdentity(identity);
24144            }
24145        }
24146    }
24147
24148    private static void enforceSystemOrPhoneCaller(String tag) {
24149        int callingUid = Binder.getCallingUid();
24150        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24151            throw new SecurityException(
24152                    "Cannot call " + tag + " from UID " + callingUid);
24153        }
24154    }
24155
24156    boolean isHistoricalPackageUsageAvailable() {
24157        return mPackageUsage.isHistoricalPackageUsageAvailable();
24158    }
24159
24160    /**
24161     * Return a <b>copy</b> of the collection of packages known to the package manager.
24162     * @return A copy of the values of mPackages.
24163     */
24164    Collection<PackageParser.Package> getPackages() {
24165        synchronized (mPackages) {
24166            return new ArrayList<>(mPackages.values());
24167        }
24168    }
24169
24170    /**
24171     * Logs process start information (including base APK hash) to the security log.
24172     * @hide
24173     */
24174    @Override
24175    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24176            String apkFile, int pid) {
24177        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24178            return;
24179        }
24180        if (!SecurityLog.isLoggingEnabled()) {
24181            return;
24182        }
24183        Bundle data = new Bundle();
24184        data.putLong("startTimestamp", System.currentTimeMillis());
24185        data.putString("processName", processName);
24186        data.putInt("uid", uid);
24187        data.putString("seinfo", seinfo);
24188        data.putString("apkFile", apkFile);
24189        data.putInt("pid", pid);
24190        Message msg = mProcessLoggingHandler.obtainMessage(
24191                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24192        msg.setData(data);
24193        mProcessLoggingHandler.sendMessage(msg);
24194    }
24195
24196    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24197        return mCompilerStats.getPackageStats(pkgName);
24198    }
24199
24200    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24201        return getOrCreateCompilerPackageStats(pkg.packageName);
24202    }
24203
24204    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24205        return mCompilerStats.getOrCreatePackageStats(pkgName);
24206    }
24207
24208    public void deleteCompilerPackageStats(String pkgName) {
24209        mCompilerStats.deletePackageStats(pkgName);
24210    }
24211
24212    @Override
24213    public int getInstallReason(String packageName, int userId) {
24214        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24215                true /* requireFullPermission */, false /* checkShell */,
24216                "get install reason");
24217        synchronized (mPackages) {
24218            final PackageSetting ps = mSettings.mPackages.get(packageName);
24219            if (ps != null) {
24220                return ps.getInstallReason(userId);
24221            }
24222        }
24223        return PackageManager.INSTALL_REASON_UNKNOWN;
24224    }
24225
24226    @Override
24227    public boolean canRequestPackageInstalls(String packageName, int userId) {
24228        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24229            return false;
24230        }
24231        return canRequestPackageInstallsInternal(packageName, 0, userId,
24232                true /* throwIfPermNotDeclared*/);
24233    }
24234
24235    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24236            boolean throwIfPermNotDeclared) {
24237        int callingUid = Binder.getCallingUid();
24238        int uid = getPackageUid(packageName, 0, userId);
24239        if (callingUid != uid && callingUid != Process.ROOT_UID
24240                && callingUid != Process.SYSTEM_UID) {
24241            throw new SecurityException(
24242                    "Caller uid " + callingUid + " does not own package " + packageName);
24243        }
24244        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24245        if (info == null) {
24246            return false;
24247        }
24248        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24249            return false;
24250        }
24251        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24252        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24253        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24254            if (throwIfPermNotDeclared) {
24255                throw new SecurityException("Need to declare " + appOpPermission
24256                        + " to call this api");
24257            } else {
24258                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24259                return false;
24260            }
24261        }
24262        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24263            return false;
24264        }
24265        if (mExternalSourcesPolicy != null) {
24266            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24267            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24268                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24269            }
24270        }
24271        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24272    }
24273
24274    @Override
24275    public ComponentName getInstantAppResolverSettingsComponent() {
24276        return mInstantAppResolverSettingsComponent;
24277    }
24278
24279    @Override
24280    public ComponentName getInstantAppInstallerComponent() {
24281        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24282            return null;
24283        }
24284        return mInstantAppInstallerActivity == null
24285                ? null : mInstantAppInstallerActivity.getComponentName();
24286    }
24287
24288    @Override
24289    public String getInstantAppAndroidId(String packageName, int userId) {
24290        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24291                "getInstantAppAndroidId");
24292        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24293                true /* requireFullPermission */, false /* checkShell */,
24294                "getInstantAppAndroidId");
24295        // Make sure the target is an Instant App.
24296        if (!isInstantApp(packageName, userId)) {
24297            return null;
24298        }
24299        synchronized (mPackages) {
24300            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24301        }
24302    }
24303}
24304
24305interface PackageSender {
24306    void sendPackageBroadcast(final String action, final String pkg,
24307        final Bundle extras, final int flags, final String targetPkg,
24308        final IIntentReceiver finishedReceiver, final int[] userIds);
24309    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
24310        int appId, int... userIds);
24311}
24312