PackageManagerService.java revision 4ff5defa5328411035183b785a77db41778bc272
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
86import static android.content.pm.PackageParser.isApkFile;
87import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88import static android.system.OsConstants.O_CREAT;
89import static android.system.OsConstants.O_RDWR;
90
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
93import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
94import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
95import static com.android.internal.util.ArrayUtils.appendInt;
96import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
99import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
100import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
104import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
105import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
106
107import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
108
109import android.Manifest;
110import android.annotation.IntDef;
111import android.annotation.NonNull;
112import android.annotation.Nullable;
113import android.app.ActivityManager;
114import android.app.AppOpsManager;
115import android.app.IActivityManager;
116import android.app.ResourcesManager;
117import android.app.admin.IDevicePolicyManager;
118import android.app.admin.SecurityLog;
119import android.app.backup.IBackupManager;
120import android.content.BroadcastReceiver;
121import android.content.ComponentName;
122import android.content.ContentResolver;
123import android.content.Context;
124import android.content.IIntentReceiver;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.IntentSender.SendIntentException;
129import android.content.ServiceConnection;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.AppsQueryHelper;
133import android.content.pm.AuxiliaryResolveInfo;
134import android.content.pm.ChangedPackages;
135import android.content.pm.ComponentInfo;
136import android.content.pm.FallbackCategoryProvider;
137import android.content.pm.FeatureInfo;
138import android.content.pm.IDexModuleRegisterCallback;
139import android.content.pm.IOnPermissionsChangeListener;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageDeleteObserver;
142import android.content.pm.IPackageDeleteObserver2;
143import android.content.pm.IPackageInstallObserver2;
144import android.content.pm.IPackageInstaller;
145import android.content.pm.IPackageManager;
146import android.content.pm.IPackageMoveObserver;
147import android.content.pm.IPackageStatsObserver;
148import android.content.pm.InstantAppInfo;
149import android.content.pm.InstantAppRequest;
150import android.content.pm.InstantAppResolveInfo;
151import android.content.pm.InstrumentationInfo;
152import android.content.pm.IntentFilterVerificationInfo;
153import android.content.pm.KeySet;
154import android.content.pm.PackageCleanItem;
155import android.content.pm.PackageInfo;
156import android.content.pm.PackageInfoLite;
157import android.content.pm.PackageInstaller;
158import android.content.pm.PackageManager;
159import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
160import android.content.pm.PackageManagerInternal;
161import android.content.pm.PackageParser;
162import android.content.pm.PackageParser.ActivityIntentInfo;
163import android.content.pm.PackageParser.PackageLite;
164import android.content.pm.PackageParser.PackageParserException;
165import android.content.pm.PackageStats;
166import android.content.pm.PackageUserState;
167import android.content.pm.ParceledListSlice;
168import android.content.pm.PermissionGroupInfo;
169import android.content.pm.PermissionInfo;
170import android.content.pm.ProviderInfo;
171import android.content.pm.ResolveInfo;
172import android.content.pm.ServiceInfo;
173import android.content.pm.SharedLibraryInfo;
174import android.content.pm.Signature;
175import android.content.pm.UserInfo;
176import android.content.pm.VerifierDeviceIdentity;
177import android.content.pm.VerifierInfo;
178import android.content.pm.VersionedPackage;
179import android.content.res.Resources;
180import android.database.ContentObserver;
181import android.graphics.Bitmap;
182import android.hardware.display.DisplayManager;
183import android.net.Uri;
184import android.os.Binder;
185import android.os.Build;
186import android.os.Bundle;
187import android.os.Debug;
188import android.os.Environment;
189import android.os.Environment.UserEnvironment;
190import android.os.FileUtils;
191import android.os.Handler;
192import android.os.IBinder;
193import android.os.Looper;
194import android.os.Message;
195import android.os.Parcel;
196import android.os.ParcelFileDescriptor;
197import android.os.PatternMatcher;
198import android.os.Process;
199import android.os.RemoteCallbackList;
200import android.os.RemoteException;
201import android.os.ResultReceiver;
202import android.os.SELinux;
203import android.os.ServiceManager;
204import android.os.ShellCallback;
205import android.os.SystemClock;
206import android.os.SystemProperties;
207import android.os.Trace;
208import android.os.UserHandle;
209import android.os.UserManager;
210import android.os.UserManagerInternal;
211import android.os.storage.IStorageManager;
212import android.os.storage.StorageEventListener;
213import android.os.storage.StorageManager;
214import android.os.storage.StorageManagerInternal;
215import android.os.storage.VolumeInfo;
216import android.os.storage.VolumeRecord;
217import android.provider.Settings.Global;
218import android.provider.Settings.Secure;
219import android.security.KeyStore;
220import android.security.SystemKeyStore;
221import android.service.pm.PackageServiceDumpProto;
222import android.system.ErrnoException;
223import android.system.Os;
224import android.text.TextUtils;
225import android.text.format.DateUtils;
226import android.util.ArrayMap;
227import android.util.ArraySet;
228import android.util.Base64;
229import android.util.BootTimingsTraceLog;
230import android.util.DisplayMetrics;
231import android.util.EventLog;
232import android.util.ExceptionUtils;
233import android.util.Log;
234import android.util.LogPrinter;
235import android.util.MathUtils;
236import android.util.PackageUtils;
237import android.util.Pair;
238import android.util.PrintStreamPrinter;
239import android.util.Slog;
240import android.util.SparseArray;
241import android.util.SparseBooleanArray;
242import android.util.SparseIntArray;
243import android.util.Xml;
244import android.util.jar.StrictJarFile;
245import android.util.proto.ProtoOutputStream;
246import android.view.Display;
247
248import com.android.internal.R;
249import com.android.internal.annotations.GuardedBy;
250import com.android.internal.app.IMediaContainerService;
251import com.android.internal.app.ResolverActivity;
252import com.android.internal.content.NativeLibraryHelper;
253import com.android.internal.content.PackageHelper;
254import com.android.internal.logging.MetricsLogger;
255import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
256import com.android.internal.os.IParcelFileDescriptorFactory;
257import com.android.internal.os.RoSystemProperties;
258import com.android.internal.os.SomeArgs;
259import com.android.internal.os.Zygote;
260import com.android.internal.telephony.CarrierAppUtils;
261import com.android.internal.util.ArrayUtils;
262import com.android.internal.util.ConcurrentUtils;
263import com.android.internal.util.DumpUtils;
264import com.android.internal.util.FastPrintWriter;
265import com.android.internal.util.FastXmlSerializer;
266import com.android.internal.util.IndentingPrintWriter;
267import com.android.internal.util.Preconditions;
268import com.android.internal.util.XmlUtils;
269import com.android.server.AttributeCache;
270import com.android.server.DeviceIdleController;
271import com.android.server.EventLogTags;
272import com.android.server.FgThread;
273import com.android.server.IntentResolver;
274import com.android.server.LocalServices;
275import com.android.server.LockGuard;
276import com.android.server.ServiceThread;
277import com.android.server.SystemConfig;
278import com.android.server.SystemServerInitThreadPool;
279import com.android.server.Watchdog;
280import com.android.server.net.NetworkPolicyManagerInternal;
281import com.android.server.pm.Installer.InstallerException;
282import com.android.server.pm.PermissionsState.PermissionState;
283import com.android.server.pm.Settings.DatabaseVersion;
284import com.android.server.pm.Settings.VersionInfo;
285import com.android.server.pm.dex.DexManager;
286import com.android.server.pm.dex.DexoptOptions;
287import com.android.server.pm.dex.PackageDexUsage;
288import com.android.server.storage.DeviceStorageMonitorInternal;
289
290import dalvik.system.CloseGuard;
291import dalvik.system.DexFile;
292import dalvik.system.VMRuntime;
293
294import libcore.io.IoUtils;
295import libcore.io.Streams;
296import libcore.util.EmptyArray;
297
298import org.xmlpull.v1.XmlPullParser;
299import org.xmlpull.v1.XmlPullParserException;
300import org.xmlpull.v1.XmlSerializer;
301
302import java.io.BufferedOutputStream;
303import java.io.BufferedReader;
304import java.io.ByteArrayInputStream;
305import java.io.ByteArrayOutputStream;
306import java.io.File;
307import java.io.FileDescriptor;
308import java.io.FileInputStream;
309import java.io.FileOutputStream;
310import java.io.FileReader;
311import java.io.FilenameFilter;
312import java.io.IOException;
313import java.io.InputStream;
314import java.io.OutputStream;
315import java.io.PrintWriter;
316import java.lang.annotation.Retention;
317import java.lang.annotation.RetentionPolicy;
318import java.nio.charset.StandardCharsets;
319import java.security.DigestInputStream;
320import java.security.MessageDigest;
321import java.security.NoSuchAlgorithmException;
322import java.security.PublicKey;
323import java.security.SecureRandom;
324import java.security.cert.Certificate;
325import java.security.cert.CertificateEncodingException;
326import java.security.cert.CertificateException;
327import java.text.SimpleDateFormat;
328import java.util.ArrayList;
329import java.util.Arrays;
330import java.util.Collection;
331import java.util.Collections;
332import java.util.Comparator;
333import java.util.Date;
334import java.util.HashMap;
335import java.util.HashSet;
336import java.util.Iterator;
337import java.util.List;
338import java.util.Map;
339import java.util.Objects;
340import java.util.Set;
341import java.util.concurrent.CountDownLatch;
342import java.util.concurrent.Future;
343import java.util.concurrent.TimeUnit;
344import java.util.concurrent.atomic.AtomicBoolean;
345import java.util.concurrent.atomic.AtomicInteger;
346import java.util.zip.GZIPInputStream;
347
348/**
349 * Keep track of all those APKs everywhere.
350 * <p>
351 * Internally there are two important locks:
352 * <ul>
353 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
354 * and other related state. It is a fine-grained lock that should only be held
355 * momentarily, as it's one of the most contended locks in the system.
356 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
357 * operations typically involve heavy lifting of application data on disk. Since
358 * {@code installd} is single-threaded, and it's operations can often be slow,
359 * this lock should never be acquired while already holding {@link #mPackages}.
360 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
361 * holding {@link #mInstallLock}.
362 * </ul>
363 * Many internal methods rely on the caller to hold the appropriate locks, and
364 * this contract is expressed through method name suffixes:
365 * <ul>
366 * <li>fooLI(): the caller must hold {@link #mInstallLock}
367 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
368 * being modified must be frozen
369 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
370 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
371 * </ul>
372 * <p>
373 * Because this class is very central to the platform's security; please run all
374 * CTS and unit tests whenever making modifications:
375 *
376 * <pre>
377 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
378 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
379 * </pre>
380 */
381public class PackageManagerService extends IPackageManager.Stub
382        implements PackageSender {
383    static final String TAG = "PackageManager";
384    static final boolean DEBUG_SETTINGS = false;
385    static final boolean DEBUG_PREFERRED = false;
386    static final boolean DEBUG_UPGRADE = false;
387    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
388    private static final boolean DEBUG_BACKUP = false;
389    private static final boolean DEBUG_INSTALL = false;
390    private static final boolean DEBUG_REMOVE = false;
391    private static final boolean DEBUG_BROADCASTS = false;
392    private static final boolean DEBUG_SHOW_INFO = false;
393    private static final boolean DEBUG_PACKAGE_INFO = false;
394    private static final boolean DEBUG_INTENT_MATCHING = false;
395    private static final boolean DEBUG_PACKAGE_SCANNING = false;
396    private static final boolean DEBUG_VERIFY = false;
397    private static final boolean DEBUG_FILTERS = false;
398    private static final boolean DEBUG_PERMISSIONS = false;
399    private static final boolean DEBUG_SHARED_LIBRARIES = false;
400    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
401
402    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
403    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
404    // user, but by default initialize to this.
405    public static final boolean DEBUG_DEXOPT = false;
406
407    private static final boolean DEBUG_ABI_SELECTION = false;
408    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
409    private static final boolean DEBUG_TRIAGED_MISSING = false;
410    private static final boolean DEBUG_APP_DATA = false;
411
412    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
413    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
414
415    private static final boolean HIDE_EPHEMERAL_APIS = false;
416
417    private static final boolean ENABLE_FREE_CACHE_V2 =
418            SystemProperties.getBoolean("fw.free_cache_v2", true);
419
420    private static final int RADIO_UID = Process.PHONE_UID;
421    private static final int LOG_UID = Process.LOG_UID;
422    private static final int NFC_UID = Process.NFC_UID;
423    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
424    private static final int SHELL_UID = Process.SHELL_UID;
425
426    // Cap the size of permission trees that 3rd party apps can define
427    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
428
429    // Suffix used during package installation when copying/moving
430    // package apks to install directory.
431    private static final String INSTALL_PACKAGE_SUFFIX = "-";
432
433    static final int SCAN_NO_DEX = 1<<1;
434    static final int SCAN_FORCE_DEX = 1<<2;
435    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
436    static final int SCAN_NEW_INSTALL = 1<<4;
437    static final int SCAN_UPDATE_TIME = 1<<5;
438    static final int SCAN_BOOTING = 1<<6;
439    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
440    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
441    static final int SCAN_REPLACING = 1<<9;
442    static final int SCAN_REQUIRE_KNOWN = 1<<10;
443    static final int SCAN_MOVE = 1<<11;
444    static final int SCAN_INITIAL = 1<<12;
445    static final int SCAN_CHECK_ONLY = 1<<13;
446    static final int SCAN_DONT_KILL_APP = 1<<14;
447    static final int SCAN_IGNORE_FROZEN = 1<<15;
448    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
449    static final int SCAN_AS_INSTANT_APP = 1<<17;
450    static final int SCAN_AS_FULL_APP = 1<<18;
451    /** Should not be with the scan flags */
452    static final int FLAGS_REMOVE_CHATTY = 1<<31;
453
454    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
455    /** Extension of the compressed packages */
456    private final static String COMPRESSED_EXTENSION = ".gz";
457
458    private static final int[] EMPTY_INT_ARRAY = new int[0];
459
460    private static final int TYPE_UNKNOWN = 0;
461    private static final int TYPE_ACTIVITY = 1;
462    private static final int TYPE_RECEIVER = 2;
463    private static final int TYPE_SERVICE = 3;
464    private static final int TYPE_PROVIDER = 4;
465    @IntDef(prefix = { "TYPE_" }, value = {
466            TYPE_UNKNOWN,
467            TYPE_ACTIVITY,
468            TYPE_RECEIVER,
469            TYPE_SERVICE,
470            TYPE_PROVIDER,
471    })
472    @Retention(RetentionPolicy.SOURCE)
473    public @interface ComponentType {}
474
475    /**
476     * Timeout (in milliseconds) after which the watchdog should declare that
477     * our handler thread is wedged.  The usual default for such things is one
478     * minute but we sometimes do very lengthy I/O operations on this thread,
479     * such as installing multi-gigabyte applications, so ours needs to be longer.
480     */
481    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
482
483    /**
484     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
485     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
486     * settings entry if available, otherwise we use the hardcoded default.  If it's been
487     * more than this long since the last fstrim, we force one during the boot sequence.
488     *
489     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
490     * one gets run at the next available charging+idle time.  This final mandatory
491     * no-fstrim check kicks in only of the other scheduling criteria is never met.
492     */
493    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
494
495    /**
496     * Whether verification is enabled by default.
497     */
498    private static final boolean DEFAULT_VERIFY_ENABLE = true;
499
500    /**
501     * The default maximum time to wait for the verification agent to return in
502     * milliseconds.
503     */
504    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
505
506    /**
507     * The default response for package verification timeout.
508     *
509     * This can be either PackageManager.VERIFICATION_ALLOW or
510     * PackageManager.VERIFICATION_REJECT.
511     */
512    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
513
514    static final String PLATFORM_PACKAGE_NAME = "android";
515
516    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
517
518    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
519            DEFAULT_CONTAINER_PACKAGE,
520            "com.android.defcontainer.DefaultContainerService");
521
522    private static final String KILL_APP_REASON_GIDS_CHANGED =
523            "permission grant or revoke changed gids";
524
525    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
526            "permissions revoked";
527
528    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
529
530    private static final String PACKAGE_SCHEME = "package";
531
532    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
533
534    /** Permission grant: not grant the permission. */
535    private static final int GRANT_DENIED = 1;
536
537    /** Permission grant: grant the permission as an install permission. */
538    private static final int GRANT_INSTALL = 2;
539
540    /** Permission grant: grant the permission as a runtime one. */
541    private static final int GRANT_RUNTIME = 3;
542
543    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
544    private static final int GRANT_UPGRADE = 4;
545
546    /** Canonical intent used to identify what counts as a "web browser" app */
547    private static final Intent sBrowserIntent;
548    static {
549        sBrowserIntent = new Intent();
550        sBrowserIntent.setAction(Intent.ACTION_VIEW);
551        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
552        sBrowserIntent.setData(Uri.parse("http:"));
553    }
554
555    /**
556     * The set of all protected actions [i.e. those actions for which a high priority
557     * intent filter is disallowed].
558     */
559    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
560    static {
561        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
562        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
563        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
564        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
565    }
566
567    // Compilation reasons.
568    public static final int REASON_FIRST_BOOT = 0;
569    public static final int REASON_BOOT = 1;
570    public static final int REASON_INSTALL = 2;
571    public static final int REASON_BACKGROUND_DEXOPT = 3;
572    public static final int REASON_AB_OTA = 4;
573    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
574
575    public static final int REASON_LAST = REASON_INACTIVE_PACKAGE_DOWNGRADE;
576
577    /** All dangerous permission names in the same order as the events in MetricsEvent */
578    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
579            Manifest.permission.READ_CALENDAR,
580            Manifest.permission.WRITE_CALENDAR,
581            Manifest.permission.CAMERA,
582            Manifest.permission.READ_CONTACTS,
583            Manifest.permission.WRITE_CONTACTS,
584            Manifest.permission.GET_ACCOUNTS,
585            Manifest.permission.ACCESS_FINE_LOCATION,
586            Manifest.permission.ACCESS_COARSE_LOCATION,
587            Manifest.permission.RECORD_AUDIO,
588            Manifest.permission.READ_PHONE_STATE,
589            Manifest.permission.CALL_PHONE,
590            Manifest.permission.READ_CALL_LOG,
591            Manifest.permission.WRITE_CALL_LOG,
592            Manifest.permission.ADD_VOICEMAIL,
593            Manifest.permission.USE_SIP,
594            Manifest.permission.PROCESS_OUTGOING_CALLS,
595            Manifest.permission.READ_CELL_BROADCASTS,
596            Manifest.permission.BODY_SENSORS,
597            Manifest.permission.SEND_SMS,
598            Manifest.permission.RECEIVE_SMS,
599            Manifest.permission.READ_SMS,
600            Manifest.permission.RECEIVE_WAP_PUSH,
601            Manifest.permission.RECEIVE_MMS,
602            Manifest.permission.READ_EXTERNAL_STORAGE,
603            Manifest.permission.WRITE_EXTERNAL_STORAGE,
604            Manifest.permission.READ_PHONE_NUMBERS,
605            Manifest.permission.ANSWER_PHONE_CALLS);
606
607
608    /**
609     * Version number for the package parser cache. Increment this whenever the format or
610     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
611     */
612    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
613
614    /**
615     * Whether the package parser cache is enabled.
616     */
617    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
618
619    final ServiceThread mHandlerThread;
620
621    final PackageHandler mHandler;
622
623    private final ProcessLoggingHandler mProcessLoggingHandler;
624
625    /**
626     * Messages for {@link #mHandler} that need to wait for system ready before
627     * being dispatched.
628     */
629    private ArrayList<Message> mPostSystemReadyMessages;
630
631    final int mSdkVersion = Build.VERSION.SDK_INT;
632
633    final Context mContext;
634    final boolean mFactoryTest;
635    final boolean mOnlyCore;
636    final DisplayMetrics mMetrics;
637    final int mDefParseFlags;
638    final String[] mSeparateProcesses;
639    final boolean mIsUpgrade;
640    final boolean mIsPreNUpgrade;
641    final boolean mIsPreNMR1Upgrade;
642
643    // Have we told the Activity Manager to whitelist the default container service by uid yet?
644    @GuardedBy("mPackages")
645    boolean mDefaultContainerWhitelisted = false;
646
647    @GuardedBy("mPackages")
648    private boolean mDexOptDialogShown;
649
650    /** The location for ASEC container files on internal storage. */
651    final String mAsecInternalPath;
652
653    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
654    // LOCK HELD.  Can be called with mInstallLock held.
655    @GuardedBy("mInstallLock")
656    final Installer mInstaller;
657
658    /** Directory where installed third-party apps stored */
659    final File mAppInstallDir;
660
661    /**
662     * Directory to which applications installed internally have their
663     * 32 bit native libraries copied.
664     */
665    private File mAppLib32InstallDir;
666
667    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
668    // apps.
669    final File mDrmAppPrivateInstallDir;
670
671    // ----------------------------------------------------------------
672
673    // Lock for state used when installing and doing other long running
674    // operations.  Methods that must be called with this lock held have
675    // the suffix "LI".
676    final Object mInstallLock = new Object();
677
678    // ----------------------------------------------------------------
679
680    // Keys are String (package name), values are Package.  This also serves
681    // as the lock for the global state.  Methods that must be called with
682    // this lock held have the prefix "LP".
683    @GuardedBy("mPackages")
684    final ArrayMap<String, PackageParser.Package> mPackages =
685            new ArrayMap<String, PackageParser.Package>();
686
687    final ArrayMap<String, Set<String>> mKnownCodebase =
688            new ArrayMap<String, Set<String>>();
689
690    // Keys are isolated uids and values are the uid of the application
691    // that created the isolated proccess.
692    @GuardedBy("mPackages")
693    final SparseIntArray mIsolatedOwners = new SparseIntArray();
694
695    /**
696     * Tracks new system packages [received in an OTA] that we expect to
697     * find updated user-installed versions. Keys are package name, values
698     * are package location.
699     */
700    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
701    /**
702     * Tracks high priority intent filters for protected actions. During boot, certain
703     * filter actions are protected and should never be allowed to have a high priority
704     * intent filter for them. However, there is one, and only one exception -- the
705     * setup wizard. It must be able to define a high priority intent filter for these
706     * actions to ensure there are no escapes from the wizard. We need to delay processing
707     * of these during boot as we need to look at all of the system packages in order
708     * to know which component is the setup wizard.
709     */
710    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
711    /**
712     * Whether or not processing protected filters should be deferred.
713     */
714    private boolean mDeferProtectedFilters = true;
715
716    /**
717     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
718     */
719    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
720    /**
721     * Whether or not system app permissions should be promoted from install to runtime.
722     */
723    boolean mPromoteSystemApps;
724
725    @GuardedBy("mPackages")
726    final Settings mSettings;
727
728    /**
729     * Set of package names that are currently "frozen", which means active
730     * surgery is being done on the code/data for that package. The platform
731     * will refuse to launch frozen packages to avoid race conditions.
732     *
733     * @see PackageFreezer
734     */
735    @GuardedBy("mPackages")
736    final ArraySet<String> mFrozenPackages = new ArraySet<>();
737
738    final ProtectedPackages mProtectedPackages;
739
740    @GuardedBy("mLoadedVolumes")
741    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
742
743    boolean mFirstBoot;
744
745    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
746
747    // System configuration read by SystemConfig.
748    final int[] mGlobalGids;
749    final SparseArray<ArraySet<String>> mSystemPermissions;
750    @GuardedBy("mAvailableFeatures")
751    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
752
753    // If mac_permissions.xml was found for seinfo labeling.
754    boolean mFoundPolicyFile;
755
756    private final InstantAppRegistry mInstantAppRegistry;
757
758    @GuardedBy("mPackages")
759    int mChangedPackagesSequenceNumber;
760    /**
761     * List of changed [installed, removed or updated] packages.
762     * mapping from user id -> sequence number -> package name
763     */
764    @GuardedBy("mPackages")
765    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
766    /**
767     * The sequence number of the last change to a package.
768     * mapping from user id -> package name -> sequence number
769     */
770    @GuardedBy("mPackages")
771    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
772
773    class PackageParserCallback implements PackageParser.Callback {
774        @Override public final boolean hasFeature(String feature) {
775            return PackageManagerService.this.hasSystemFeature(feature, 0);
776        }
777
778        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
779                Collection<PackageParser.Package> allPackages, String targetPackageName) {
780            List<PackageParser.Package> overlayPackages = null;
781            for (PackageParser.Package p : allPackages) {
782                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
783                    if (overlayPackages == null) {
784                        overlayPackages = new ArrayList<PackageParser.Package>();
785                    }
786                    overlayPackages.add(p);
787                }
788            }
789            if (overlayPackages != null) {
790                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
791                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
792                        return p1.mOverlayPriority - p2.mOverlayPriority;
793                    }
794                };
795                Collections.sort(overlayPackages, cmp);
796            }
797            return overlayPackages;
798        }
799
800        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
801                String targetPackageName, String targetPath) {
802            if ("android".equals(targetPackageName)) {
803                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
804                // native AssetManager.
805                return null;
806            }
807            List<PackageParser.Package> overlayPackages =
808                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
809            if (overlayPackages == null || overlayPackages.isEmpty()) {
810                return null;
811            }
812            List<String> overlayPathList = null;
813            for (PackageParser.Package overlayPackage : overlayPackages) {
814                if (targetPath == null) {
815                    if (overlayPathList == null) {
816                        overlayPathList = new ArrayList<String>();
817                    }
818                    overlayPathList.add(overlayPackage.baseCodePath);
819                    continue;
820                }
821
822                try {
823                    // Creates idmaps for system to parse correctly the Android manifest of the
824                    // target package.
825                    //
826                    // OverlayManagerService will update each of them with a correct gid from its
827                    // target package app id.
828                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
829                            UserHandle.getSharedAppGid(
830                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
831                    if (overlayPathList == null) {
832                        overlayPathList = new ArrayList<String>();
833                    }
834                    overlayPathList.add(overlayPackage.baseCodePath);
835                } catch (InstallerException e) {
836                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
837                            overlayPackage.baseCodePath);
838                }
839            }
840            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
841        }
842
843        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
844            synchronized (mPackages) {
845                return getStaticOverlayPathsLocked(
846                        mPackages.values(), targetPackageName, targetPath);
847            }
848        }
849
850        @Override public final String[] getOverlayApks(String targetPackageName) {
851            return getStaticOverlayPaths(targetPackageName, null);
852        }
853
854        @Override public final String[] getOverlayPaths(String targetPackageName,
855                String targetPath) {
856            return getStaticOverlayPaths(targetPackageName, targetPath);
857        }
858    };
859
860    class ParallelPackageParserCallback extends PackageParserCallback {
861        List<PackageParser.Package> mOverlayPackages = null;
862
863        void findStaticOverlayPackages() {
864            synchronized (mPackages) {
865                for (PackageParser.Package p : mPackages.values()) {
866                    if (p.mIsStaticOverlay) {
867                        if (mOverlayPackages == null) {
868                            mOverlayPackages = new ArrayList<PackageParser.Package>();
869                        }
870                        mOverlayPackages.add(p);
871                    }
872                }
873            }
874        }
875
876        @Override
877        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
878            // We can trust mOverlayPackages without holding mPackages because package uninstall
879            // can't happen while running parallel parsing.
880            // Moreover holding mPackages on each parsing thread causes dead-lock.
881            return mOverlayPackages == null ? null :
882                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
883        }
884    }
885
886    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
887    final ParallelPackageParserCallback mParallelPackageParserCallback =
888            new ParallelPackageParserCallback();
889
890    public static final class SharedLibraryEntry {
891        public final @Nullable String path;
892        public final @Nullable String apk;
893        public final @NonNull SharedLibraryInfo info;
894
895        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
896                String declaringPackageName, int declaringPackageVersionCode) {
897            path = _path;
898            apk = _apk;
899            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
900                    declaringPackageName, declaringPackageVersionCode), null);
901        }
902    }
903
904    // Currently known shared libraries.
905    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
906    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
907            new ArrayMap<>();
908
909    // All available activities, for your resolving pleasure.
910    final ActivityIntentResolver mActivities =
911            new ActivityIntentResolver();
912
913    // All available receivers, for your resolving pleasure.
914    final ActivityIntentResolver mReceivers =
915            new ActivityIntentResolver();
916
917    // All available services, for your resolving pleasure.
918    final ServiceIntentResolver mServices = new ServiceIntentResolver();
919
920    // All available providers, for your resolving pleasure.
921    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
922
923    // Mapping from provider base names (first directory in content URI codePath)
924    // to the provider information.
925    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
926            new ArrayMap<String, PackageParser.Provider>();
927
928    // Mapping from instrumentation class names to info about them.
929    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
930            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
931
932    // Mapping from permission names to info about them.
933    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
934            new ArrayMap<String, PackageParser.PermissionGroup>();
935
936    // Packages whose data we have transfered into another package, thus
937    // should no longer exist.
938    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
939
940    // Broadcast actions that are only available to the system.
941    @GuardedBy("mProtectedBroadcasts")
942    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
943
944    /** List of packages waiting for verification. */
945    final SparseArray<PackageVerificationState> mPendingVerification
946            = new SparseArray<PackageVerificationState>();
947
948    /** Set of packages associated with each app op permission. */
949    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
950
951    final PackageInstallerService mInstallerService;
952
953    private final PackageDexOptimizer mPackageDexOptimizer;
954    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
955    // is used by other apps).
956    private final DexManager mDexManager;
957
958    private AtomicInteger mNextMoveId = new AtomicInteger();
959    private final MoveCallbacks mMoveCallbacks;
960
961    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
962
963    // Cache of users who need badging.
964    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
965
966    /** Token for keys in mPendingVerification. */
967    private int mPendingVerificationToken = 0;
968
969    volatile boolean mSystemReady;
970    volatile boolean mSafeMode;
971    volatile boolean mHasSystemUidErrors;
972    private volatile boolean mEphemeralAppsDisabled;
973
974    ApplicationInfo mAndroidApplication;
975    final ActivityInfo mResolveActivity = new ActivityInfo();
976    final ResolveInfo mResolveInfo = new ResolveInfo();
977    ComponentName mResolveComponentName;
978    PackageParser.Package mPlatformPackage;
979    ComponentName mCustomResolverComponentName;
980
981    boolean mResolverReplaced = false;
982
983    private final @Nullable ComponentName mIntentFilterVerifierComponent;
984    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
985
986    private int mIntentFilterVerificationToken = 0;
987
988    /** The service connection to the ephemeral resolver */
989    final EphemeralResolverConnection mInstantAppResolverConnection;
990    /** Component used to show resolver settings for Instant Apps */
991    final ComponentName mInstantAppResolverSettingsComponent;
992
993    /** Activity used to install instant applications */
994    ActivityInfo mInstantAppInstallerActivity;
995    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
996
997    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
998            = new SparseArray<IntentFilterVerificationState>();
999
1000    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1001
1002    // List of packages names to keep cached, even if they are uninstalled for all users
1003    private List<String> mKeepUninstalledPackages;
1004
1005    private UserManagerInternal mUserManagerInternal;
1006
1007    private DeviceIdleController.LocalService mDeviceIdleController;
1008
1009    private File mCacheDir;
1010
1011    private ArraySet<String> mPrivappPermissionsViolations;
1012
1013    private Future<?> mPrepareAppDataFuture;
1014
1015    private static class IFVerificationParams {
1016        PackageParser.Package pkg;
1017        boolean replacing;
1018        int userId;
1019        int verifierUid;
1020
1021        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1022                int _userId, int _verifierUid) {
1023            pkg = _pkg;
1024            replacing = _replacing;
1025            userId = _userId;
1026            replacing = _replacing;
1027            verifierUid = _verifierUid;
1028        }
1029    }
1030
1031    private interface IntentFilterVerifier<T extends IntentFilter> {
1032        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1033                                               T filter, String packageName);
1034        void startVerifications(int userId);
1035        void receiveVerificationResponse(int verificationId);
1036    }
1037
1038    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1039        private Context mContext;
1040        private ComponentName mIntentFilterVerifierComponent;
1041        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1042
1043        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1044            mContext = context;
1045            mIntentFilterVerifierComponent = verifierComponent;
1046        }
1047
1048        private String getDefaultScheme() {
1049            return IntentFilter.SCHEME_HTTPS;
1050        }
1051
1052        @Override
1053        public void startVerifications(int userId) {
1054            // Launch verifications requests
1055            int count = mCurrentIntentFilterVerifications.size();
1056            for (int n=0; n<count; n++) {
1057                int verificationId = mCurrentIntentFilterVerifications.get(n);
1058                final IntentFilterVerificationState ivs =
1059                        mIntentFilterVerificationStates.get(verificationId);
1060
1061                String packageName = ivs.getPackageName();
1062
1063                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1064                final int filterCount = filters.size();
1065                ArraySet<String> domainsSet = new ArraySet<>();
1066                for (int m=0; m<filterCount; m++) {
1067                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1068                    domainsSet.addAll(filter.getHostsList());
1069                }
1070                synchronized (mPackages) {
1071                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1072                            packageName, domainsSet) != null) {
1073                        scheduleWriteSettingsLocked();
1074                    }
1075                }
1076                sendVerificationRequest(verificationId, ivs);
1077            }
1078            mCurrentIntentFilterVerifications.clear();
1079        }
1080
1081        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1082            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1083            verificationIntent.putExtra(
1084                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1085                    verificationId);
1086            verificationIntent.putExtra(
1087                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1088                    getDefaultScheme());
1089            verificationIntent.putExtra(
1090                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1091                    ivs.getHostsString());
1092            verificationIntent.putExtra(
1093                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1094                    ivs.getPackageName());
1095            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1096            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1097
1098            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1099            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1100                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1101                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1102
1103            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1104            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1105                    "Sending IntentFilter verification broadcast");
1106        }
1107
1108        public void receiveVerificationResponse(int verificationId) {
1109            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1110
1111            final boolean verified = ivs.isVerified();
1112
1113            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1114            final int count = filters.size();
1115            if (DEBUG_DOMAIN_VERIFICATION) {
1116                Slog.i(TAG, "Received verification response " + verificationId
1117                        + " for " + count + " filters, verified=" + verified);
1118            }
1119            for (int n=0; n<count; n++) {
1120                PackageParser.ActivityIntentInfo filter = filters.get(n);
1121                filter.setVerified(verified);
1122
1123                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1124                        + " verified with result:" + verified + " and hosts:"
1125                        + ivs.getHostsString());
1126            }
1127
1128            mIntentFilterVerificationStates.remove(verificationId);
1129
1130            final String packageName = ivs.getPackageName();
1131            IntentFilterVerificationInfo ivi = null;
1132
1133            synchronized (mPackages) {
1134                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1135            }
1136            if (ivi == null) {
1137                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1138                        + verificationId + " packageName:" + packageName);
1139                return;
1140            }
1141            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1142                    "Updating IntentFilterVerificationInfo for package " + packageName
1143                            +" verificationId:" + verificationId);
1144
1145            synchronized (mPackages) {
1146                if (verified) {
1147                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1148                } else {
1149                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1150                }
1151                scheduleWriteSettingsLocked();
1152
1153                final int userId = ivs.getUserId();
1154                if (userId != UserHandle.USER_ALL) {
1155                    final int userStatus =
1156                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1157
1158                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1159                    boolean needUpdate = false;
1160
1161                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1162                    // already been set by the User thru the Disambiguation dialog
1163                    switch (userStatus) {
1164                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1165                            if (verified) {
1166                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1167                            } else {
1168                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1169                            }
1170                            needUpdate = true;
1171                            break;
1172
1173                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1174                            if (verified) {
1175                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1176                                needUpdate = true;
1177                            }
1178                            break;
1179
1180                        default:
1181                            // Nothing to do
1182                    }
1183
1184                    if (needUpdate) {
1185                        mSettings.updateIntentFilterVerificationStatusLPw(
1186                                packageName, updatedStatus, userId);
1187                        scheduleWritePackageRestrictionsLocked(userId);
1188                    }
1189                }
1190            }
1191        }
1192
1193        @Override
1194        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1195                    ActivityIntentInfo filter, String packageName) {
1196            if (!hasValidDomains(filter)) {
1197                return false;
1198            }
1199            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1200            if (ivs == null) {
1201                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1202                        packageName);
1203            }
1204            if (DEBUG_DOMAIN_VERIFICATION) {
1205                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1206            }
1207            ivs.addFilter(filter);
1208            return true;
1209        }
1210
1211        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1212                int userId, int verificationId, String packageName) {
1213            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1214                    verifierUid, userId, packageName);
1215            ivs.setPendingState();
1216            synchronized (mPackages) {
1217                mIntentFilterVerificationStates.append(verificationId, ivs);
1218                mCurrentIntentFilterVerifications.add(verificationId);
1219            }
1220            return ivs;
1221        }
1222    }
1223
1224    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1225        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1226                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1227                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1228    }
1229
1230    // Set of pending broadcasts for aggregating enable/disable of components.
1231    static class PendingPackageBroadcasts {
1232        // for each user id, a map of <package name -> components within that package>
1233        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1234
1235        public PendingPackageBroadcasts() {
1236            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1237        }
1238
1239        public ArrayList<String> get(int userId, String packageName) {
1240            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1241            return packages.get(packageName);
1242        }
1243
1244        public void put(int userId, String packageName, ArrayList<String> components) {
1245            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1246            packages.put(packageName, components);
1247        }
1248
1249        public void remove(int userId, String packageName) {
1250            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1251            if (packages != null) {
1252                packages.remove(packageName);
1253            }
1254        }
1255
1256        public void remove(int userId) {
1257            mUidMap.remove(userId);
1258        }
1259
1260        public int userIdCount() {
1261            return mUidMap.size();
1262        }
1263
1264        public int userIdAt(int n) {
1265            return mUidMap.keyAt(n);
1266        }
1267
1268        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1269            return mUidMap.get(userId);
1270        }
1271
1272        public int size() {
1273            // total number of pending broadcast entries across all userIds
1274            int num = 0;
1275            for (int i = 0; i< mUidMap.size(); i++) {
1276                num += mUidMap.valueAt(i).size();
1277            }
1278            return num;
1279        }
1280
1281        public void clear() {
1282            mUidMap.clear();
1283        }
1284
1285        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1286            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1287            if (map == null) {
1288                map = new ArrayMap<String, ArrayList<String>>();
1289                mUidMap.put(userId, map);
1290            }
1291            return map;
1292        }
1293    }
1294    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1295
1296    // Service Connection to remote media container service to copy
1297    // package uri's from external media onto secure containers
1298    // or internal storage.
1299    private IMediaContainerService mContainerService = null;
1300
1301    static final int SEND_PENDING_BROADCAST = 1;
1302    static final int MCS_BOUND = 3;
1303    static final int END_COPY = 4;
1304    static final int INIT_COPY = 5;
1305    static final int MCS_UNBIND = 6;
1306    static final int START_CLEANING_PACKAGE = 7;
1307    static final int FIND_INSTALL_LOC = 8;
1308    static final int POST_INSTALL = 9;
1309    static final int MCS_RECONNECT = 10;
1310    static final int MCS_GIVE_UP = 11;
1311    static final int UPDATED_MEDIA_STATUS = 12;
1312    static final int WRITE_SETTINGS = 13;
1313    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1314    static final int PACKAGE_VERIFIED = 15;
1315    static final int CHECK_PENDING_VERIFICATION = 16;
1316    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1317    static final int INTENT_FILTER_VERIFIED = 18;
1318    static final int WRITE_PACKAGE_LIST = 19;
1319    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1320
1321    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1322
1323    // Delay time in millisecs
1324    static final int BROADCAST_DELAY = 10 * 1000;
1325
1326    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1327            2 * 60 * 60 * 1000L; /* two hours */
1328
1329    static UserManagerService sUserManager;
1330
1331    // Stores a list of users whose package restrictions file needs to be updated
1332    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1333
1334    final private DefaultContainerConnection mDefContainerConn =
1335            new DefaultContainerConnection();
1336    class DefaultContainerConnection implements ServiceConnection {
1337        public void onServiceConnected(ComponentName name, IBinder service) {
1338            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1339            final IMediaContainerService imcs = IMediaContainerService.Stub
1340                    .asInterface(Binder.allowBlocking(service));
1341            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1342        }
1343
1344        public void onServiceDisconnected(ComponentName name) {
1345            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1346        }
1347    }
1348
1349    // Recordkeeping of restore-after-install operations that are currently in flight
1350    // between the Package Manager and the Backup Manager
1351    static class PostInstallData {
1352        public InstallArgs args;
1353        public PackageInstalledInfo res;
1354
1355        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1356            args = _a;
1357            res = _r;
1358        }
1359    }
1360
1361    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1362    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1363
1364    // XML tags for backup/restore of various bits of state
1365    private static final String TAG_PREFERRED_BACKUP = "pa";
1366    private static final String TAG_DEFAULT_APPS = "da";
1367    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1368
1369    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1370    private static final String TAG_ALL_GRANTS = "rt-grants";
1371    private static final String TAG_GRANT = "grant";
1372    private static final String ATTR_PACKAGE_NAME = "pkg";
1373
1374    private static final String TAG_PERMISSION = "perm";
1375    private static final String ATTR_PERMISSION_NAME = "name";
1376    private static final String ATTR_IS_GRANTED = "g";
1377    private static final String ATTR_USER_SET = "set";
1378    private static final String ATTR_USER_FIXED = "fixed";
1379    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1380
1381    // System/policy permission grants are not backed up
1382    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1383            FLAG_PERMISSION_POLICY_FIXED
1384            | FLAG_PERMISSION_SYSTEM_FIXED
1385            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1386
1387    // And we back up these user-adjusted states
1388    private static final int USER_RUNTIME_GRANT_MASK =
1389            FLAG_PERMISSION_USER_SET
1390            | FLAG_PERMISSION_USER_FIXED
1391            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1392
1393    final @Nullable String mRequiredVerifierPackage;
1394    final @NonNull String mRequiredInstallerPackage;
1395    final @NonNull String mRequiredUninstallerPackage;
1396    final @Nullable String mSetupWizardPackage;
1397    final @Nullable String mStorageManagerPackage;
1398    final @NonNull String mServicesSystemSharedLibraryPackageName;
1399    final @NonNull String mSharedSystemSharedLibraryPackageName;
1400
1401    final boolean mPermissionReviewRequired;
1402
1403    private final PackageUsage mPackageUsage = new PackageUsage();
1404    private final CompilerStats mCompilerStats = new CompilerStats();
1405
1406    class PackageHandler extends Handler {
1407        private boolean mBound = false;
1408        final ArrayList<HandlerParams> mPendingInstalls =
1409            new ArrayList<HandlerParams>();
1410
1411        private boolean connectToService() {
1412            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1413                    " DefaultContainerService");
1414            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1415            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1416            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1417                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1418                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1419                mBound = true;
1420                return true;
1421            }
1422            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1423            return false;
1424        }
1425
1426        private void disconnectService() {
1427            mContainerService = null;
1428            mBound = false;
1429            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1430            mContext.unbindService(mDefContainerConn);
1431            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1432        }
1433
1434        PackageHandler(Looper looper) {
1435            super(looper);
1436        }
1437
1438        public void handleMessage(Message msg) {
1439            try {
1440                doHandleMessage(msg);
1441            } finally {
1442                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1443            }
1444        }
1445
1446        void doHandleMessage(Message msg) {
1447            switch (msg.what) {
1448                case INIT_COPY: {
1449                    HandlerParams params = (HandlerParams) msg.obj;
1450                    int idx = mPendingInstalls.size();
1451                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1452                    // If a bind was already initiated we dont really
1453                    // need to do anything. The pending install
1454                    // will be processed later on.
1455                    if (!mBound) {
1456                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1457                                System.identityHashCode(mHandler));
1458                        // If this is the only one pending we might
1459                        // have to bind to the service again.
1460                        if (!connectToService()) {
1461                            Slog.e(TAG, "Failed to bind to media container service");
1462                            params.serviceError();
1463                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1464                                    System.identityHashCode(mHandler));
1465                            if (params.traceMethod != null) {
1466                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1467                                        params.traceCookie);
1468                            }
1469                            return;
1470                        } else {
1471                            // Once we bind to the service, the first
1472                            // pending request will be processed.
1473                            mPendingInstalls.add(idx, params);
1474                        }
1475                    } else {
1476                        mPendingInstalls.add(idx, params);
1477                        // Already bound to the service. Just make
1478                        // sure we trigger off processing the first request.
1479                        if (idx == 0) {
1480                            mHandler.sendEmptyMessage(MCS_BOUND);
1481                        }
1482                    }
1483                    break;
1484                }
1485                case MCS_BOUND: {
1486                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1487                    if (msg.obj != null) {
1488                        mContainerService = (IMediaContainerService) msg.obj;
1489                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1490                                System.identityHashCode(mHandler));
1491                    }
1492                    if (mContainerService == null) {
1493                        if (!mBound) {
1494                            // Something seriously wrong since we are not bound and we are not
1495                            // waiting for connection. Bail out.
1496                            Slog.e(TAG, "Cannot bind to media container service");
1497                            for (HandlerParams params : mPendingInstalls) {
1498                                // Indicate service bind error
1499                                params.serviceError();
1500                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1501                                        System.identityHashCode(params));
1502                                if (params.traceMethod != null) {
1503                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1504                                            params.traceMethod, params.traceCookie);
1505                                }
1506                                return;
1507                            }
1508                            mPendingInstalls.clear();
1509                        } else {
1510                            Slog.w(TAG, "Waiting to connect to media container service");
1511                        }
1512                    } else if (mPendingInstalls.size() > 0) {
1513                        HandlerParams params = mPendingInstalls.get(0);
1514                        if (params != null) {
1515                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1516                                    System.identityHashCode(params));
1517                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1518                            if (params.startCopy()) {
1519                                // We are done...  look for more work or to
1520                                // go idle.
1521                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1522                                        "Checking for more work or unbind...");
1523                                // Delete pending install
1524                                if (mPendingInstalls.size() > 0) {
1525                                    mPendingInstalls.remove(0);
1526                                }
1527                                if (mPendingInstalls.size() == 0) {
1528                                    if (mBound) {
1529                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1530                                                "Posting delayed MCS_UNBIND");
1531                                        removeMessages(MCS_UNBIND);
1532                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1533                                        // Unbind after a little delay, to avoid
1534                                        // continual thrashing.
1535                                        sendMessageDelayed(ubmsg, 10000);
1536                                    }
1537                                } else {
1538                                    // There are more pending requests in queue.
1539                                    // Just post MCS_BOUND message to trigger processing
1540                                    // of next pending install.
1541                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1542                                            "Posting MCS_BOUND for next work");
1543                                    mHandler.sendEmptyMessage(MCS_BOUND);
1544                                }
1545                            }
1546                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1547                        }
1548                    } else {
1549                        // Should never happen ideally.
1550                        Slog.w(TAG, "Empty queue");
1551                    }
1552                    break;
1553                }
1554                case MCS_RECONNECT: {
1555                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1556                    if (mPendingInstalls.size() > 0) {
1557                        if (mBound) {
1558                            disconnectService();
1559                        }
1560                        if (!connectToService()) {
1561                            Slog.e(TAG, "Failed to bind to media container service");
1562                            for (HandlerParams params : mPendingInstalls) {
1563                                // Indicate service bind error
1564                                params.serviceError();
1565                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1566                                        System.identityHashCode(params));
1567                            }
1568                            mPendingInstalls.clear();
1569                        }
1570                    }
1571                    break;
1572                }
1573                case MCS_UNBIND: {
1574                    // If there is no actual work left, then time to unbind.
1575                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1576
1577                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1578                        if (mBound) {
1579                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1580
1581                            disconnectService();
1582                        }
1583                    } else if (mPendingInstalls.size() > 0) {
1584                        // There are more pending requests in queue.
1585                        // Just post MCS_BOUND message to trigger processing
1586                        // of next pending install.
1587                        mHandler.sendEmptyMessage(MCS_BOUND);
1588                    }
1589
1590                    break;
1591                }
1592                case MCS_GIVE_UP: {
1593                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1594                    HandlerParams params = mPendingInstalls.remove(0);
1595                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1596                            System.identityHashCode(params));
1597                    break;
1598                }
1599                case SEND_PENDING_BROADCAST: {
1600                    String packages[];
1601                    ArrayList<String> components[];
1602                    int size = 0;
1603                    int uids[];
1604                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1605                    synchronized (mPackages) {
1606                        if (mPendingBroadcasts == null) {
1607                            return;
1608                        }
1609                        size = mPendingBroadcasts.size();
1610                        if (size <= 0) {
1611                            // Nothing to be done. Just return
1612                            return;
1613                        }
1614                        packages = new String[size];
1615                        components = new ArrayList[size];
1616                        uids = new int[size];
1617                        int i = 0;  // filling out the above arrays
1618
1619                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1620                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1621                            Iterator<Map.Entry<String, ArrayList<String>>> it
1622                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1623                                            .entrySet().iterator();
1624                            while (it.hasNext() && i < size) {
1625                                Map.Entry<String, ArrayList<String>> ent = it.next();
1626                                packages[i] = ent.getKey();
1627                                components[i] = ent.getValue();
1628                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1629                                uids[i] = (ps != null)
1630                                        ? UserHandle.getUid(packageUserId, ps.appId)
1631                                        : -1;
1632                                i++;
1633                            }
1634                        }
1635                        size = i;
1636                        mPendingBroadcasts.clear();
1637                    }
1638                    // Send broadcasts
1639                    for (int i = 0; i < size; i++) {
1640                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1641                    }
1642                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1643                    break;
1644                }
1645                case START_CLEANING_PACKAGE: {
1646                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1647                    final String packageName = (String)msg.obj;
1648                    final int userId = msg.arg1;
1649                    final boolean andCode = msg.arg2 != 0;
1650                    synchronized (mPackages) {
1651                        if (userId == UserHandle.USER_ALL) {
1652                            int[] users = sUserManager.getUserIds();
1653                            for (int user : users) {
1654                                mSettings.addPackageToCleanLPw(
1655                                        new PackageCleanItem(user, packageName, andCode));
1656                            }
1657                        } else {
1658                            mSettings.addPackageToCleanLPw(
1659                                    new PackageCleanItem(userId, packageName, andCode));
1660                        }
1661                    }
1662                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1663                    startCleaningPackages();
1664                } break;
1665                case POST_INSTALL: {
1666                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1667
1668                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1669                    final boolean didRestore = (msg.arg2 != 0);
1670                    mRunningInstalls.delete(msg.arg1);
1671
1672                    if (data != null) {
1673                        InstallArgs args = data.args;
1674                        PackageInstalledInfo parentRes = data.res;
1675
1676                        final boolean grantPermissions = (args.installFlags
1677                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1678                        final boolean killApp = (args.installFlags
1679                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1680                        final boolean virtualPreload = ((args.installFlags
1681                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1682                        final String[] grantedPermissions = args.installGrantPermissions;
1683
1684                        // Handle the parent package
1685                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1686                                virtualPreload, grantedPermissions, didRestore,
1687                                args.installerPackageName, args.observer);
1688
1689                        // Handle the child packages
1690                        final int childCount = (parentRes.addedChildPackages != null)
1691                                ? parentRes.addedChildPackages.size() : 0;
1692                        for (int i = 0; i < childCount; i++) {
1693                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1694                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1695                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1696                                    args.installerPackageName, args.observer);
1697                        }
1698
1699                        // Log tracing if needed
1700                        if (args.traceMethod != null) {
1701                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1702                                    args.traceCookie);
1703                        }
1704                    } else {
1705                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1706                    }
1707
1708                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1709                } break;
1710                case UPDATED_MEDIA_STATUS: {
1711                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1712                    boolean reportStatus = msg.arg1 == 1;
1713                    boolean doGc = msg.arg2 == 1;
1714                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1715                    if (doGc) {
1716                        // Force a gc to clear up stale containers.
1717                        Runtime.getRuntime().gc();
1718                    }
1719                    if (msg.obj != null) {
1720                        @SuppressWarnings("unchecked")
1721                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1722                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1723                        // Unload containers
1724                        unloadAllContainers(args);
1725                    }
1726                    if (reportStatus) {
1727                        try {
1728                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1729                                    "Invoking StorageManagerService call back");
1730                            PackageHelper.getStorageManager().finishMediaUpdate();
1731                        } catch (RemoteException e) {
1732                            Log.e(TAG, "StorageManagerService not running?");
1733                        }
1734                    }
1735                } break;
1736                case WRITE_SETTINGS: {
1737                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1738                    synchronized (mPackages) {
1739                        removeMessages(WRITE_SETTINGS);
1740                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1741                        mSettings.writeLPr();
1742                        mDirtyUsers.clear();
1743                    }
1744                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1745                } break;
1746                case WRITE_PACKAGE_RESTRICTIONS: {
1747                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1748                    synchronized (mPackages) {
1749                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1750                        for (int userId : mDirtyUsers) {
1751                            mSettings.writePackageRestrictionsLPr(userId);
1752                        }
1753                        mDirtyUsers.clear();
1754                    }
1755                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1756                } break;
1757                case WRITE_PACKAGE_LIST: {
1758                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1759                    synchronized (mPackages) {
1760                        removeMessages(WRITE_PACKAGE_LIST);
1761                        mSettings.writePackageListLPr(msg.arg1);
1762                    }
1763                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1764                } break;
1765                case CHECK_PENDING_VERIFICATION: {
1766                    final int verificationId = msg.arg1;
1767                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1768
1769                    if ((state != null) && !state.timeoutExtended()) {
1770                        final InstallArgs args = state.getInstallArgs();
1771                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1772
1773                        Slog.i(TAG, "Verification timed out for " + originUri);
1774                        mPendingVerification.remove(verificationId);
1775
1776                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1777
1778                        final UserHandle user = args.getUser();
1779                        if (getDefaultVerificationResponse(user)
1780                                == PackageManager.VERIFICATION_ALLOW) {
1781                            Slog.i(TAG, "Continuing with installation of " + originUri);
1782                            state.setVerifierResponse(Binder.getCallingUid(),
1783                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1784                            broadcastPackageVerified(verificationId, originUri,
1785                                    PackageManager.VERIFICATION_ALLOW, user);
1786                            try {
1787                                ret = args.copyApk(mContainerService, true);
1788                            } catch (RemoteException e) {
1789                                Slog.e(TAG, "Could not contact the ContainerService");
1790                            }
1791                        } else {
1792                            broadcastPackageVerified(verificationId, originUri,
1793                                    PackageManager.VERIFICATION_REJECT, user);
1794                        }
1795
1796                        Trace.asyncTraceEnd(
1797                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1798
1799                        processPendingInstall(args, ret);
1800                        mHandler.sendEmptyMessage(MCS_UNBIND);
1801                    }
1802                    break;
1803                }
1804                case PACKAGE_VERIFIED: {
1805                    final int verificationId = msg.arg1;
1806
1807                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1808                    if (state == null) {
1809                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1810                        break;
1811                    }
1812
1813                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1814
1815                    state.setVerifierResponse(response.callerUid, response.code);
1816
1817                    if (state.isVerificationComplete()) {
1818                        mPendingVerification.remove(verificationId);
1819
1820                        final InstallArgs args = state.getInstallArgs();
1821                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1822
1823                        int ret;
1824                        if (state.isInstallAllowed()) {
1825                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1826                            broadcastPackageVerified(verificationId, originUri,
1827                                    response.code, state.getInstallArgs().getUser());
1828                            try {
1829                                ret = args.copyApk(mContainerService, true);
1830                            } catch (RemoteException e) {
1831                                Slog.e(TAG, "Could not contact the ContainerService");
1832                            }
1833                        } else {
1834                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1835                        }
1836
1837                        Trace.asyncTraceEnd(
1838                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1839
1840                        processPendingInstall(args, ret);
1841                        mHandler.sendEmptyMessage(MCS_UNBIND);
1842                    }
1843
1844                    break;
1845                }
1846                case START_INTENT_FILTER_VERIFICATIONS: {
1847                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1848                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1849                            params.replacing, params.pkg);
1850                    break;
1851                }
1852                case INTENT_FILTER_VERIFIED: {
1853                    final int verificationId = msg.arg1;
1854
1855                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1856                            verificationId);
1857                    if (state == null) {
1858                        Slog.w(TAG, "Invalid IntentFilter verification token "
1859                                + verificationId + " received");
1860                        break;
1861                    }
1862
1863                    final int userId = state.getUserId();
1864
1865                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1866                            "Processing IntentFilter verification with token:"
1867                            + verificationId + " and userId:" + userId);
1868
1869                    final IntentFilterVerificationResponse response =
1870                            (IntentFilterVerificationResponse) msg.obj;
1871
1872                    state.setVerifierResponse(response.callerUid, response.code);
1873
1874                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1875                            "IntentFilter verification with token:" + verificationId
1876                            + " and userId:" + userId
1877                            + " is settings verifier response with response code:"
1878                            + response.code);
1879
1880                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1881                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1882                                + response.getFailedDomainsString());
1883                    }
1884
1885                    if (state.isVerificationComplete()) {
1886                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1887                    } else {
1888                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1889                                "IntentFilter verification with token:" + verificationId
1890                                + " was not said to be complete");
1891                    }
1892
1893                    break;
1894                }
1895                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1896                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1897                            mInstantAppResolverConnection,
1898                            (InstantAppRequest) msg.obj,
1899                            mInstantAppInstallerActivity,
1900                            mHandler);
1901                }
1902            }
1903        }
1904    }
1905
1906    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1907            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1908            boolean launchedForRestore, String installerPackage,
1909            IPackageInstallObserver2 installObserver) {
1910        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1911            // Send the removed broadcasts
1912            if (res.removedInfo != null) {
1913                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1914            }
1915
1916            // Now that we successfully installed the package, grant runtime
1917            // permissions if requested before broadcasting the install. Also
1918            // for legacy apps in permission review mode we clear the permission
1919            // review flag which is used to emulate runtime permissions for
1920            // legacy apps.
1921            if (grantPermissions) {
1922                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1923            }
1924
1925            final boolean update = res.removedInfo != null
1926                    && res.removedInfo.removedPackage != null;
1927            final String origInstallerPackageName = res.removedInfo != null
1928                    ? res.removedInfo.installerPackageName : null;
1929
1930            // If this is the first time we have child packages for a disabled privileged
1931            // app that had no children, we grant requested runtime permissions to the new
1932            // children if the parent on the system image had them already granted.
1933            if (res.pkg.parentPackage != null) {
1934                synchronized (mPackages) {
1935                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1936                }
1937            }
1938
1939            synchronized (mPackages) {
1940                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1941            }
1942
1943            final String packageName = res.pkg.applicationInfo.packageName;
1944
1945            // Determine the set of users who are adding this package for
1946            // the first time vs. those who are seeing an update.
1947            int[] firstUsers = EMPTY_INT_ARRAY;
1948            int[] updateUsers = EMPTY_INT_ARRAY;
1949            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1950            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1951            for (int newUser : res.newUsers) {
1952                if (ps.getInstantApp(newUser)) {
1953                    continue;
1954                }
1955                if (allNewUsers) {
1956                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1957                    continue;
1958                }
1959                boolean isNew = true;
1960                for (int origUser : res.origUsers) {
1961                    if (origUser == newUser) {
1962                        isNew = false;
1963                        break;
1964                    }
1965                }
1966                if (isNew) {
1967                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1968                } else {
1969                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1970                }
1971            }
1972
1973            // Send installed broadcasts if the package is not a static shared lib.
1974            if (res.pkg.staticSharedLibName == null) {
1975                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1976
1977                // Send added for users that see the package for the first time
1978                // sendPackageAddedForNewUsers also deals with system apps
1979                int appId = UserHandle.getAppId(res.uid);
1980                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1981                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1982                        virtualPreload /*startReceiver*/, appId, firstUsers);
1983
1984                // Send added for users that don't see the package for the first time
1985                Bundle extras = new Bundle(1);
1986                extras.putInt(Intent.EXTRA_UID, res.uid);
1987                if (update) {
1988                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1989                }
1990                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1991                        extras, 0 /*flags*/,
1992                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1993                if (origInstallerPackageName != null) {
1994                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1995                            extras, 0 /*flags*/,
1996                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1997                }
1998
1999                // Send replaced for users that don't see the package for the first time
2000                if (update) {
2001                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2002                            packageName, extras, 0 /*flags*/,
2003                            null /*targetPackage*/, null /*finishedReceiver*/,
2004                            updateUsers);
2005                    if (origInstallerPackageName != null) {
2006                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2007                                extras, 0 /*flags*/,
2008                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
2009                    }
2010                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2011                            null /*package*/, null /*extras*/, 0 /*flags*/,
2012                            packageName /*targetPackage*/,
2013                            null /*finishedReceiver*/, updateUsers);
2014                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2015                    // First-install and we did a restore, so we're responsible for the
2016                    // first-launch broadcast.
2017                    if (DEBUG_BACKUP) {
2018                        Slog.i(TAG, "Post-restore of " + packageName
2019                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2020                    }
2021                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2022                }
2023
2024                // Send broadcast package appeared if forward locked/external for all users
2025                // treat asec-hosted packages like removable media on upgrade
2026                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2027                    if (DEBUG_INSTALL) {
2028                        Slog.i(TAG, "upgrading pkg " + res.pkg
2029                                + " is ASEC-hosted -> AVAILABLE");
2030                    }
2031                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2032                    ArrayList<String> pkgList = new ArrayList<>(1);
2033                    pkgList.add(packageName);
2034                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2035                }
2036            }
2037
2038            // Work that needs to happen on first install within each user
2039            if (firstUsers != null && firstUsers.length > 0) {
2040                synchronized (mPackages) {
2041                    for (int userId : firstUsers) {
2042                        // If this app is a browser and it's newly-installed for some
2043                        // users, clear any default-browser state in those users. The
2044                        // app's nature doesn't depend on the user, so we can just check
2045                        // its browser nature in any user and generalize.
2046                        if (packageIsBrowser(packageName, userId)) {
2047                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2048                        }
2049
2050                        // We may also need to apply pending (restored) runtime
2051                        // permission grants within these users.
2052                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2053                    }
2054                }
2055            }
2056
2057            // Log current value of "unknown sources" setting
2058            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2059                    getUnknownSourcesSettings());
2060
2061            // Remove the replaced package's older resources safely now
2062            // We delete after a gc for applications  on sdcard.
2063            if (res.removedInfo != null && res.removedInfo.args != null) {
2064                Runtime.getRuntime().gc();
2065                synchronized (mInstallLock) {
2066                    res.removedInfo.args.doPostDeleteLI(true);
2067                }
2068            } else {
2069                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2070                // and not block here.
2071                VMRuntime.getRuntime().requestConcurrentGC();
2072            }
2073
2074            // Notify DexManager that the package was installed for new users.
2075            // The updated users should already be indexed and the package code paths
2076            // should not change.
2077            // Don't notify the manager for ephemeral apps as they are not expected to
2078            // survive long enough to benefit of background optimizations.
2079            for (int userId : firstUsers) {
2080                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2081                // There's a race currently where some install events may interleave with an uninstall.
2082                // This can lead to package info being null (b/36642664).
2083                if (info != null) {
2084                    mDexManager.notifyPackageInstalled(info, userId);
2085                }
2086            }
2087        }
2088
2089        // If someone is watching installs - notify them
2090        if (installObserver != null) {
2091            try {
2092                Bundle extras = extrasForInstallResult(res);
2093                installObserver.onPackageInstalled(res.name, res.returnCode,
2094                        res.returnMsg, extras);
2095            } catch (RemoteException e) {
2096                Slog.i(TAG, "Observer no longer exists.");
2097            }
2098        }
2099    }
2100
2101    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2102            PackageParser.Package pkg) {
2103        if (pkg.parentPackage == null) {
2104            return;
2105        }
2106        if (pkg.requestedPermissions == null) {
2107            return;
2108        }
2109        final PackageSetting disabledSysParentPs = mSettings
2110                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2111        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2112                || !disabledSysParentPs.isPrivileged()
2113                || (disabledSysParentPs.childPackageNames != null
2114                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2115            return;
2116        }
2117        final int[] allUserIds = sUserManager.getUserIds();
2118        final int permCount = pkg.requestedPermissions.size();
2119        for (int i = 0; i < permCount; i++) {
2120            String permission = pkg.requestedPermissions.get(i);
2121            BasePermission bp = mSettings.mPermissions.get(permission);
2122            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2123                continue;
2124            }
2125            for (int userId : allUserIds) {
2126                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2127                        permission, userId)) {
2128                    grantRuntimePermission(pkg.packageName, permission, userId);
2129                }
2130            }
2131        }
2132    }
2133
2134    private StorageEventListener mStorageListener = new StorageEventListener() {
2135        @Override
2136        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2137            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2138                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2139                    final String volumeUuid = vol.getFsUuid();
2140
2141                    // Clean up any users or apps that were removed or recreated
2142                    // while this volume was missing
2143                    sUserManager.reconcileUsers(volumeUuid);
2144                    reconcileApps(volumeUuid);
2145
2146                    // Clean up any install sessions that expired or were
2147                    // cancelled while this volume was missing
2148                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2149
2150                    loadPrivatePackages(vol);
2151
2152                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2153                    unloadPrivatePackages(vol);
2154                }
2155            }
2156
2157            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2158                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2159                    updateExternalMediaStatus(true, false);
2160                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2161                    updateExternalMediaStatus(false, false);
2162                }
2163            }
2164        }
2165
2166        @Override
2167        public void onVolumeForgotten(String fsUuid) {
2168            if (TextUtils.isEmpty(fsUuid)) {
2169                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2170                return;
2171            }
2172
2173            // Remove any apps installed on the forgotten volume
2174            synchronized (mPackages) {
2175                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2176                for (PackageSetting ps : packages) {
2177                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2178                    deletePackageVersioned(new VersionedPackage(ps.name,
2179                            PackageManager.VERSION_CODE_HIGHEST),
2180                            new LegacyPackageDeleteObserver(null).getBinder(),
2181                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2182                    // Try very hard to release any references to this package
2183                    // so we don't risk the system server being killed due to
2184                    // open FDs
2185                    AttributeCache.instance().removePackage(ps.name);
2186                }
2187
2188                mSettings.onVolumeForgotten(fsUuid);
2189                mSettings.writeLPr();
2190            }
2191        }
2192    };
2193
2194    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2195            String[] grantedPermissions) {
2196        for (int userId : userIds) {
2197            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2198        }
2199    }
2200
2201    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2202            String[] grantedPermissions) {
2203        PackageSetting ps = (PackageSetting) pkg.mExtras;
2204        if (ps == null) {
2205            return;
2206        }
2207
2208        PermissionsState permissionsState = ps.getPermissionsState();
2209
2210        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2211                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2212
2213        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2214                >= Build.VERSION_CODES.M;
2215
2216        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2217
2218        for (String permission : pkg.requestedPermissions) {
2219            final BasePermission bp;
2220            synchronized (mPackages) {
2221                bp = mSettings.mPermissions.get(permission);
2222            }
2223            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2224                    && (!instantApp || bp.isInstant())
2225                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2226                    && (grantedPermissions == null
2227                           || ArrayUtils.contains(grantedPermissions, permission))) {
2228                final int flags = permissionsState.getPermissionFlags(permission, userId);
2229                if (supportsRuntimePermissions) {
2230                    // Installer cannot change immutable permissions.
2231                    if ((flags & immutableFlags) == 0) {
2232                        grantRuntimePermission(pkg.packageName, permission, userId);
2233                    }
2234                } else if (mPermissionReviewRequired) {
2235                    // In permission review mode we clear the review flag when we
2236                    // are asked to install the app with all permissions granted.
2237                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2238                        updatePermissionFlags(permission, pkg.packageName,
2239                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2240                    }
2241                }
2242            }
2243        }
2244    }
2245
2246    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2247        Bundle extras = null;
2248        switch (res.returnCode) {
2249            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2250                extras = new Bundle();
2251                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2252                        res.origPermission);
2253                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2254                        res.origPackage);
2255                break;
2256            }
2257            case PackageManager.INSTALL_SUCCEEDED: {
2258                extras = new Bundle();
2259                extras.putBoolean(Intent.EXTRA_REPLACING,
2260                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2261                break;
2262            }
2263        }
2264        return extras;
2265    }
2266
2267    void scheduleWriteSettingsLocked() {
2268        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2269            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2270        }
2271    }
2272
2273    void scheduleWritePackageListLocked(int userId) {
2274        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2275            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2276            msg.arg1 = userId;
2277            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2278        }
2279    }
2280
2281    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2282        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2283        scheduleWritePackageRestrictionsLocked(userId);
2284    }
2285
2286    void scheduleWritePackageRestrictionsLocked(int userId) {
2287        final int[] userIds = (userId == UserHandle.USER_ALL)
2288                ? sUserManager.getUserIds() : new int[]{userId};
2289        for (int nextUserId : userIds) {
2290            if (!sUserManager.exists(nextUserId)) return;
2291            mDirtyUsers.add(nextUserId);
2292            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2293                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2294            }
2295        }
2296    }
2297
2298    public static PackageManagerService main(Context context, Installer installer,
2299            boolean factoryTest, boolean onlyCore) {
2300        // Self-check for initial settings.
2301        PackageManagerServiceCompilerMapping.checkProperties();
2302
2303        PackageManagerService m = new PackageManagerService(context, installer,
2304                factoryTest, onlyCore);
2305        m.enableSystemUserPackages();
2306        ServiceManager.addService("package", m);
2307        return m;
2308    }
2309
2310    private void enableSystemUserPackages() {
2311        if (!UserManager.isSplitSystemUser()) {
2312            return;
2313        }
2314        // For system user, enable apps based on the following conditions:
2315        // - app is whitelisted or belong to one of these groups:
2316        //   -- system app which has no launcher icons
2317        //   -- system app which has INTERACT_ACROSS_USERS permission
2318        //   -- system IME app
2319        // - app is not in the blacklist
2320        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2321        Set<String> enableApps = new ArraySet<>();
2322        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2323                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2324                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2325        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2326        enableApps.addAll(wlApps);
2327        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2328                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2329        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2330        enableApps.removeAll(blApps);
2331        Log.i(TAG, "Applications installed for system user: " + enableApps);
2332        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2333                UserHandle.SYSTEM);
2334        final int allAppsSize = allAps.size();
2335        synchronized (mPackages) {
2336            for (int i = 0; i < allAppsSize; i++) {
2337                String pName = allAps.get(i);
2338                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2339                // Should not happen, but we shouldn't be failing if it does
2340                if (pkgSetting == null) {
2341                    continue;
2342                }
2343                boolean install = enableApps.contains(pName);
2344                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2345                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2346                            + " for system user");
2347                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2348                }
2349            }
2350            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2351        }
2352    }
2353
2354    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2355        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2356                Context.DISPLAY_SERVICE);
2357        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2358    }
2359
2360    /**
2361     * Requests that files preopted on a secondary system partition be copied to the data partition
2362     * if possible.  Note that the actual copying of the files is accomplished by init for security
2363     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2364     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2365     */
2366    private static void requestCopyPreoptedFiles() {
2367        final int WAIT_TIME_MS = 100;
2368        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2369        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2370            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2371            // We will wait for up to 100 seconds.
2372            final long timeStart = SystemClock.uptimeMillis();
2373            final long timeEnd = timeStart + 100 * 1000;
2374            long timeNow = timeStart;
2375            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2376                try {
2377                    Thread.sleep(WAIT_TIME_MS);
2378                } catch (InterruptedException e) {
2379                    // Do nothing
2380                }
2381                timeNow = SystemClock.uptimeMillis();
2382                if (timeNow > timeEnd) {
2383                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2384                    Slog.wtf(TAG, "cppreopt did not finish!");
2385                    break;
2386                }
2387            }
2388
2389            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2390        }
2391    }
2392
2393    public PackageManagerService(Context context, Installer installer,
2394            boolean factoryTest, boolean onlyCore) {
2395        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2396        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2397        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2398                SystemClock.uptimeMillis());
2399
2400        if (mSdkVersion <= 0) {
2401            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2402        }
2403
2404        mContext = context;
2405
2406        mPermissionReviewRequired = context.getResources().getBoolean(
2407                R.bool.config_permissionReviewRequired);
2408
2409        mFactoryTest = factoryTest;
2410        mOnlyCore = onlyCore;
2411        mMetrics = new DisplayMetrics();
2412        mSettings = new Settings(mPackages);
2413        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2414                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2415        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2416                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2417        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2418                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2419        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2420                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2421        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2422                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2423        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2424                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2425
2426        String separateProcesses = SystemProperties.get("debug.separate_processes");
2427        if (separateProcesses != null && separateProcesses.length() > 0) {
2428            if ("*".equals(separateProcesses)) {
2429                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2430                mSeparateProcesses = null;
2431                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2432            } else {
2433                mDefParseFlags = 0;
2434                mSeparateProcesses = separateProcesses.split(",");
2435                Slog.w(TAG, "Running with debug.separate_processes: "
2436                        + separateProcesses);
2437            }
2438        } else {
2439            mDefParseFlags = 0;
2440            mSeparateProcesses = null;
2441        }
2442
2443        mInstaller = installer;
2444        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2445                "*dexopt*");
2446        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2447        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2448
2449        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2450                FgThread.get().getLooper());
2451
2452        getDefaultDisplayMetrics(context, mMetrics);
2453
2454        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2455        SystemConfig systemConfig = SystemConfig.getInstance();
2456        mGlobalGids = systemConfig.getGlobalGids();
2457        mSystemPermissions = systemConfig.getSystemPermissions();
2458        mAvailableFeatures = systemConfig.getAvailableFeatures();
2459        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2460
2461        mProtectedPackages = new ProtectedPackages(mContext);
2462
2463        synchronized (mInstallLock) {
2464        // writer
2465        synchronized (mPackages) {
2466            mHandlerThread = new ServiceThread(TAG,
2467                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2468            mHandlerThread.start();
2469            mHandler = new PackageHandler(mHandlerThread.getLooper());
2470            mProcessLoggingHandler = new ProcessLoggingHandler();
2471            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2472
2473            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2474            mInstantAppRegistry = new InstantAppRegistry(this);
2475
2476            File dataDir = Environment.getDataDirectory();
2477            mAppInstallDir = new File(dataDir, "app");
2478            mAppLib32InstallDir = new File(dataDir, "app-lib");
2479            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2480            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2481            sUserManager = new UserManagerService(context, this,
2482                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2483
2484            // Propagate permission configuration in to package manager.
2485            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2486                    = systemConfig.getPermissions();
2487            for (int i=0; i<permConfig.size(); i++) {
2488                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2489                BasePermission bp = mSettings.mPermissions.get(perm.name);
2490                if (bp == null) {
2491                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2492                    mSettings.mPermissions.put(perm.name, bp);
2493                }
2494                if (perm.gids != null) {
2495                    bp.setGids(perm.gids, perm.perUser);
2496                }
2497            }
2498
2499            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2500            final int builtInLibCount = libConfig.size();
2501            for (int i = 0; i < builtInLibCount; i++) {
2502                String name = libConfig.keyAt(i);
2503                String path = libConfig.valueAt(i);
2504                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2505                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2506            }
2507
2508            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2509
2510            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2511            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2512            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2513
2514            // Clean up orphaned packages for which the code path doesn't exist
2515            // and they are an update to a system app - caused by bug/32321269
2516            final int packageSettingCount = mSettings.mPackages.size();
2517            for (int i = packageSettingCount - 1; i >= 0; i--) {
2518                PackageSetting ps = mSettings.mPackages.valueAt(i);
2519                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2520                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2521                    mSettings.mPackages.removeAt(i);
2522                    mSettings.enableSystemPackageLPw(ps.name);
2523                }
2524            }
2525
2526            if (mFirstBoot) {
2527                requestCopyPreoptedFiles();
2528            }
2529
2530            String customResolverActivity = Resources.getSystem().getString(
2531                    R.string.config_customResolverActivity);
2532            if (TextUtils.isEmpty(customResolverActivity)) {
2533                customResolverActivity = null;
2534            } else {
2535                mCustomResolverComponentName = ComponentName.unflattenFromString(
2536                        customResolverActivity);
2537            }
2538
2539            long startTime = SystemClock.uptimeMillis();
2540
2541            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2542                    startTime);
2543
2544            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2545            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2546
2547            if (bootClassPath == null) {
2548                Slog.w(TAG, "No BOOTCLASSPATH found!");
2549            }
2550
2551            if (systemServerClassPath == null) {
2552                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2553            }
2554
2555            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2556
2557            final VersionInfo ver = mSettings.getInternalVersion();
2558            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2559            if (mIsUpgrade) {
2560                logCriticalInfo(Log.INFO,
2561                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2562            }
2563
2564            // when upgrading from pre-M, promote system app permissions from install to runtime
2565            mPromoteSystemApps =
2566                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2567
2568            // When upgrading from pre-N, we need to handle package extraction like first boot,
2569            // as there is no profiling data available.
2570            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2571
2572            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2573
2574            // save off the names of pre-existing system packages prior to scanning; we don't
2575            // want to automatically grant runtime permissions for new system apps
2576            if (mPromoteSystemApps) {
2577                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2578                while (pkgSettingIter.hasNext()) {
2579                    PackageSetting ps = pkgSettingIter.next();
2580                    if (isSystemApp(ps)) {
2581                        mExistingSystemPackages.add(ps.name);
2582                    }
2583                }
2584            }
2585
2586            mCacheDir = preparePackageParserCache(mIsUpgrade);
2587
2588            // Set flag to monitor and not change apk file paths when
2589            // scanning install directories.
2590            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2591
2592            if (mIsUpgrade || mFirstBoot) {
2593                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2594            }
2595
2596            // Collect vendor overlay packages. (Do this before scanning any apps.)
2597            // For security and version matching reason, only consider
2598            // overlay packages if they reside in the right directory.
2599            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2600                    | PackageParser.PARSE_IS_SYSTEM
2601                    | PackageParser.PARSE_IS_SYSTEM_DIR
2602                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2603
2604            mParallelPackageParserCallback.findStaticOverlayPackages();
2605
2606            // Find base frameworks (resource packages without code).
2607            scanDirTracedLI(frameworkDir, mDefParseFlags
2608                    | PackageParser.PARSE_IS_SYSTEM
2609                    | PackageParser.PARSE_IS_SYSTEM_DIR
2610                    | PackageParser.PARSE_IS_PRIVILEGED,
2611                    scanFlags | SCAN_NO_DEX, 0);
2612
2613            // Collected privileged system packages.
2614            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2615            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2616                    | PackageParser.PARSE_IS_SYSTEM
2617                    | PackageParser.PARSE_IS_SYSTEM_DIR
2618                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2619
2620            // Collect ordinary system packages.
2621            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2622            scanDirTracedLI(systemAppDir, mDefParseFlags
2623                    | PackageParser.PARSE_IS_SYSTEM
2624                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2625
2626            // Collect all vendor packages.
2627            File vendorAppDir = new File("/vendor/app");
2628            try {
2629                vendorAppDir = vendorAppDir.getCanonicalFile();
2630            } catch (IOException e) {
2631                // failed to look up canonical path, continue with original one
2632            }
2633            scanDirTracedLI(vendorAppDir, mDefParseFlags
2634                    | PackageParser.PARSE_IS_SYSTEM
2635                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2636
2637            // Collect all OEM packages.
2638            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2639            scanDirTracedLI(oemAppDir, mDefParseFlags
2640                    | PackageParser.PARSE_IS_SYSTEM
2641                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2642
2643            // Prune any system packages that no longer exist.
2644            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2645            // Stub packages must either be replaced with full versions in the /data
2646            // partition or be disabled.
2647            final List<String> stubSystemApps = new ArrayList<>();
2648            if (!mOnlyCore) {
2649                // do this first before mucking with mPackages for the "expecting better" case
2650                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2651                while (pkgIterator.hasNext()) {
2652                    final PackageParser.Package pkg = pkgIterator.next();
2653                    if (pkg.isStub) {
2654                        stubSystemApps.add(pkg.packageName);
2655                    }
2656                }
2657
2658                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2659                while (psit.hasNext()) {
2660                    PackageSetting ps = psit.next();
2661
2662                    /*
2663                     * If this is not a system app, it can't be a
2664                     * disable system app.
2665                     */
2666                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2667                        continue;
2668                    }
2669
2670                    /*
2671                     * If the package is scanned, it's not erased.
2672                     */
2673                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2674                    if (scannedPkg != null) {
2675                        /*
2676                         * If the system app is both scanned and in the
2677                         * disabled packages list, then it must have been
2678                         * added via OTA. Remove it from the currently
2679                         * scanned package so the previously user-installed
2680                         * application can be scanned.
2681                         */
2682                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2683                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2684                                    + ps.name + "; removing system app.  Last known codePath="
2685                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2686                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2687                                    + scannedPkg.mVersionCode);
2688                            removePackageLI(scannedPkg, true);
2689                            mExpectingBetter.put(ps.name, ps.codePath);
2690                        }
2691
2692                        continue;
2693                    }
2694
2695                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2696                        psit.remove();
2697                        logCriticalInfo(Log.WARN, "System package " + ps.name
2698                                + " no longer exists; it's data will be wiped");
2699                        // Actual deletion of code and data will be handled by later
2700                        // reconciliation step
2701                    } else {
2702                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2703                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2704                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2705                        }
2706                    }
2707                }
2708            }
2709
2710            //look for any incomplete package installations
2711            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2712            for (int i = 0; i < deletePkgsList.size(); i++) {
2713                // Actual deletion of code and data will be handled by later
2714                // reconciliation step
2715                final String packageName = deletePkgsList.get(i).name;
2716                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2717                synchronized (mPackages) {
2718                    mSettings.removePackageLPw(packageName);
2719                }
2720            }
2721
2722            //delete tmp files
2723            deleteTempPackageFiles();
2724
2725            // Remove any shared userIDs that have no associated packages
2726            mSettings.pruneSharedUsersLPw();
2727            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2728            final int systemPackagesCount = mPackages.size();
2729            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2730                    + " ms, packageCount: " + systemPackagesCount
2731                    + " ms, timePerPackage: "
2732                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount));
2733            if (mIsUpgrade && systemPackagesCount > 0) {
2734                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2735                        ((int) systemScanTime) / systemPackagesCount);
2736            }
2737            if (!mOnlyCore) {
2738                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2739                        SystemClock.uptimeMillis());
2740                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2741
2742                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2743                        | PackageParser.PARSE_FORWARD_LOCK,
2744                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2745
2746                // Remove disable package settings for updated system apps that were
2747                // removed via an OTA. If the update is no longer present, remove the
2748                // app completely. Otherwise, revoke their system privileges.
2749                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2750                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2751                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2752
2753                    final String msg;
2754                    if (deletedPkg == null) {
2755                        // should have found an update, but, we didn't; remove everything
2756                        msg = "Updated system package " + deletedAppName
2757                                + " no longer exists; removing its data";
2758                        // Actual deletion of code and data will be handled by later
2759                        // reconciliation step
2760                    } else {
2761                        // found an update; revoke system privileges
2762                        msg = "Updated system package + " + deletedAppName
2763                                + " no longer exists; revoking system privileges";
2764
2765                        // Don't do anything if a stub is removed from the system image. If
2766                        // we were to remove the uncompressed version from the /data partition,
2767                        // this is where it'd be done.
2768
2769                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2770                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2771                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2772                    }
2773                    logCriticalInfo(Log.WARN, msg);
2774                }
2775
2776                /*
2777                 * Make sure all system apps that we expected to appear on
2778                 * the userdata partition actually showed up. If they never
2779                 * appeared, crawl back and revive the system version.
2780                 */
2781                for (int i = 0; i < mExpectingBetter.size(); i++) {
2782                    final String packageName = mExpectingBetter.keyAt(i);
2783                    if (!mPackages.containsKey(packageName)) {
2784                        final File scanFile = mExpectingBetter.valueAt(i);
2785
2786                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2787                                + " but never showed up; reverting to system");
2788
2789                        int reparseFlags = mDefParseFlags;
2790                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2791                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2792                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2793                                    | PackageParser.PARSE_IS_PRIVILEGED;
2794                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2795                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2796                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2797                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2798                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2799                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2800                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2801                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2802                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2803                        } else {
2804                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2805                            continue;
2806                        }
2807
2808                        mSettings.enableSystemPackageLPw(packageName);
2809
2810                        try {
2811                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2812                        } catch (PackageManagerException e) {
2813                            Slog.e(TAG, "Failed to parse original system package: "
2814                                    + e.getMessage());
2815                        }
2816                    }
2817                }
2818
2819                // Uncompress and install any stubbed system applications.
2820                // This must be done last to ensure all stubs are replaced or disabled.
2821                decompressSystemApplications(stubSystemApps, scanFlags);
2822
2823                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2824                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2825                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2826                        + " ms, packageCount: " + dataPackagesCount
2827                        + " ms, timePerPackage: "
2828                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount));
2829                if (mIsUpgrade && dataPackagesCount > 0) {
2830                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2831                            ((int) dataScanTime) / dataPackagesCount);
2832                }
2833            }
2834            mExpectingBetter.clear();
2835
2836            // Resolve the storage manager.
2837            mStorageManagerPackage = getStorageManagerPackageName();
2838
2839            // Resolve protected action filters. Only the setup wizard is allowed to
2840            // have a high priority filter for these actions.
2841            mSetupWizardPackage = getSetupWizardPackageName();
2842            if (mProtectedFilters.size() > 0) {
2843                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2844                    Slog.i(TAG, "No setup wizard;"
2845                        + " All protected intents capped to priority 0");
2846                }
2847                for (ActivityIntentInfo filter : mProtectedFilters) {
2848                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2849                        if (DEBUG_FILTERS) {
2850                            Slog.i(TAG, "Found setup wizard;"
2851                                + " allow priority " + filter.getPriority() + ";"
2852                                + " package: " + filter.activity.info.packageName
2853                                + " activity: " + filter.activity.className
2854                                + " priority: " + filter.getPriority());
2855                        }
2856                        // skip setup wizard; allow it to keep the high priority filter
2857                        continue;
2858                    }
2859                    if (DEBUG_FILTERS) {
2860                        Slog.i(TAG, "Protected action; cap priority to 0;"
2861                                + " package: " + filter.activity.info.packageName
2862                                + " activity: " + filter.activity.className
2863                                + " origPrio: " + filter.getPriority());
2864                    }
2865                    filter.setPriority(0);
2866                }
2867            }
2868            mDeferProtectedFilters = false;
2869            mProtectedFilters.clear();
2870
2871            // Now that we know all of the shared libraries, update all clients to have
2872            // the correct library paths.
2873            updateAllSharedLibrariesLPw(null);
2874
2875            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2876                // NOTE: We ignore potential failures here during a system scan (like
2877                // the rest of the commands above) because there's precious little we
2878                // can do about it. A settings error is reported, though.
2879                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2880            }
2881
2882            // Now that we know all the packages we are keeping,
2883            // read and update their last usage times.
2884            mPackageUsage.read(mPackages);
2885            mCompilerStats.read();
2886
2887            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2888                    SystemClock.uptimeMillis());
2889            Slog.i(TAG, "Time to scan packages: "
2890                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2891                    + " seconds");
2892
2893            // If the platform SDK has changed since the last time we booted,
2894            // we need to re-grant app permission to catch any new ones that
2895            // appear.  This is really a hack, and means that apps can in some
2896            // cases get permissions that the user didn't initially explicitly
2897            // allow...  it would be nice to have some better way to handle
2898            // this situation.
2899            int updateFlags = UPDATE_PERMISSIONS_ALL;
2900            if (ver.sdkVersion != mSdkVersion) {
2901                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2902                        + mSdkVersion + "; regranting permissions for internal storage");
2903                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2904            }
2905            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2906            ver.sdkVersion = mSdkVersion;
2907
2908            // If this is the first boot or an update from pre-M, and it is a normal
2909            // boot, then we need to initialize the default preferred apps across
2910            // all defined users.
2911            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2912                for (UserInfo user : sUserManager.getUsers(true)) {
2913                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2914                    applyFactoryDefaultBrowserLPw(user.id);
2915                    primeDomainVerificationsLPw(user.id);
2916                }
2917            }
2918
2919            // Prepare storage for system user really early during boot,
2920            // since core system apps like SettingsProvider and SystemUI
2921            // can't wait for user to start
2922            final int storageFlags;
2923            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2924                storageFlags = StorageManager.FLAG_STORAGE_DE;
2925            } else {
2926                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2927            }
2928            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2929                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2930                    true /* onlyCoreApps */);
2931            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2932                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2933                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2934                traceLog.traceBegin("AppDataFixup");
2935                try {
2936                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2937                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2938                } catch (InstallerException e) {
2939                    Slog.w(TAG, "Trouble fixing GIDs", e);
2940                }
2941                traceLog.traceEnd();
2942
2943                traceLog.traceBegin("AppDataPrepare");
2944                if (deferPackages == null || deferPackages.isEmpty()) {
2945                    return;
2946                }
2947                int count = 0;
2948                for (String pkgName : deferPackages) {
2949                    PackageParser.Package pkg = null;
2950                    synchronized (mPackages) {
2951                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2952                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2953                            pkg = ps.pkg;
2954                        }
2955                    }
2956                    if (pkg != null) {
2957                        synchronized (mInstallLock) {
2958                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2959                                    true /* maybeMigrateAppData */);
2960                        }
2961                        count++;
2962                    }
2963                }
2964                traceLog.traceEnd();
2965                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2966            }, "prepareAppData");
2967
2968            // If this is first boot after an OTA, and a normal boot, then
2969            // we need to clear code cache directories.
2970            // Note that we do *not* clear the application profiles. These remain valid
2971            // across OTAs and are used to drive profile verification (post OTA) and
2972            // profile compilation (without waiting to collect a fresh set of profiles).
2973            if (mIsUpgrade && !onlyCore) {
2974                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2975                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2976                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2977                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2978                        // No apps are running this early, so no need to freeze
2979                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2980                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2981                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2982                    }
2983                }
2984                ver.fingerprint = Build.FINGERPRINT;
2985            }
2986
2987            checkDefaultBrowser();
2988
2989            // clear only after permissions and other defaults have been updated
2990            mExistingSystemPackages.clear();
2991            mPromoteSystemApps = false;
2992
2993            // All the changes are done during package scanning.
2994            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2995
2996            // can downgrade to reader
2997            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2998            mSettings.writeLPr();
2999            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3000            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3001                    SystemClock.uptimeMillis());
3002
3003            if (!mOnlyCore) {
3004                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3005                mRequiredInstallerPackage = getRequiredInstallerLPr();
3006                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3007                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3008                if (mIntentFilterVerifierComponent != null) {
3009                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3010                            mIntentFilterVerifierComponent);
3011                } else {
3012                    mIntentFilterVerifier = null;
3013                }
3014                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3015                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3016                        SharedLibraryInfo.VERSION_UNDEFINED);
3017                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3018                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3019                        SharedLibraryInfo.VERSION_UNDEFINED);
3020            } else {
3021                mRequiredVerifierPackage = null;
3022                mRequiredInstallerPackage = null;
3023                mRequiredUninstallerPackage = null;
3024                mIntentFilterVerifierComponent = null;
3025                mIntentFilterVerifier = null;
3026                mServicesSystemSharedLibraryPackageName = null;
3027                mSharedSystemSharedLibraryPackageName = null;
3028            }
3029
3030            mInstallerService = new PackageInstallerService(context, this);
3031            final Pair<ComponentName, String> instantAppResolverComponent =
3032                    getInstantAppResolverLPr();
3033            if (instantAppResolverComponent != null) {
3034                if (DEBUG_EPHEMERAL) {
3035                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3036                }
3037                mInstantAppResolverConnection = new EphemeralResolverConnection(
3038                        mContext, instantAppResolverComponent.first,
3039                        instantAppResolverComponent.second);
3040                mInstantAppResolverSettingsComponent =
3041                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3042            } else {
3043                mInstantAppResolverConnection = null;
3044                mInstantAppResolverSettingsComponent = null;
3045            }
3046            updateInstantAppInstallerLocked(null);
3047
3048            // Read and update the usage of dex files.
3049            // Do this at the end of PM init so that all the packages have their
3050            // data directory reconciled.
3051            // At this point we know the code paths of the packages, so we can validate
3052            // the disk file and build the internal cache.
3053            // The usage file is expected to be small so loading and verifying it
3054            // should take a fairly small time compare to the other activities (e.g. package
3055            // scanning).
3056            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3057            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3058            for (int userId : currentUserIds) {
3059                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3060            }
3061            mDexManager.load(userPackages);
3062            if (mIsUpgrade) {
3063                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3064                        (int) (SystemClock.uptimeMillis() - startTime));
3065            }
3066        } // synchronized (mPackages)
3067        } // synchronized (mInstallLock)
3068
3069        // Now after opening every single application zip, make sure they
3070        // are all flushed.  Not really needed, but keeps things nice and
3071        // tidy.
3072        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3073        Runtime.getRuntime().gc();
3074        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3075
3076        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3077        FallbackCategoryProvider.loadFallbacks();
3078        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3079
3080        // The initial scanning above does many calls into installd while
3081        // holding the mPackages lock, but we're mostly interested in yelling
3082        // once we have a booted system.
3083        mInstaller.setWarnIfHeld(mPackages);
3084
3085        // Expose private service for system components to use.
3086        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3087        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3088    }
3089
3090    /**
3091     * Uncompress and install stub applications.
3092     * <p>In order to save space on the system partition, some applications are shipped in a
3093     * compressed form. In addition the compressed bits for the full application, the
3094     * system image contains a tiny stub comprised of only the Android manifest.
3095     * <p>During the first boot, attempt to uncompress and install the full application. If
3096     * the application can't be installed for any reason, disable the stub and prevent
3097     * uncompressing the full application during future boots.
3098     * <p>In order to forcefully attempt an installation of a full application, go to app
3099     * settings and enable the application.
3100     */
3101    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3102        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3103            final String pkgName = stubSystemApps.get(i);
3104            // skip if the system package is already disabled
3105            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3106                stubSystemApps.remove(i);
3107                continue;
3108            }
3109            // skip if the package isn't installed (?!); this should never happen
3110            final PackageParser.Package pkg = mPackages.get(pkgName);
3111            if (pkg == null) {
3112                stubSystemApps.remove(i);
3113                continue;
3114            }
3115            // skip if the package has been disabled by the user
3116            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3117            if (ps != null) {
3118                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3119                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3120                    stubSystemApps.remove(i);
3121                    continue;
3122                }
3123            }
3124
3125            if (DEBUG_COMPRESSION) {
3126                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3127            }
3128
3129            // uncompress the binary to its eventual destination on /data
3130            final File scanFile = decompressPackage(pkg);
3131            if (scanFile == null) {
3132                continue;
3133            }
3134
3135            // install the package to replace the stub on /system
3136            try {
3137                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3138                removePackageLI(pkg, true /*chatty*/);
3139                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3140                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3141                        UserHandle.USER_SYSTEM, "android");
3142                stubSystemApps.remove(i);
3143                continue;
3144            } catch (PackageManagerException e) {
3145                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3146            }
3147
3148            // any failed attempt to install the package will be cleaned up later
3149        }
3150
3151        // disable any stub still left; these failed to install the full application
3152        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3153            final String pkgName = stubSystemApps.get(i);
3154            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3155            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3156                    UserHandle.USER_SYSTEM, "android");
3157            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3158        }
3159    }
3160
3161    private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3162        if (DEBUG_COMPRESSION) {
3163            Slog.i(TAG, "Decompress file"
3164                    + "; src: " + srcFile.getAbsolutePath()
3165                    + ", dst: " + dstFile.getAbsolutePath());
3166        }
3167        try (
3168                InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3169                OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3170        ) {
3171            Streams.copy(fileIn, fileOut);
3172            Os.chmod(dstFile.getAbsolutePath(), 0644);
3173            return PackageManager.INSTALL_SUCCEEDED;
3174        } catch (IOException e) {
3175            logCriticalInfo(Log.ERROR, "Failed to decompress file"
3176                    + "; src: " + srcFile.getAbsolutePath()
3177                    + ", dst: " + dstFile.getAbsolutePath());
3178        }
3179        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3180    }
3181
3182    private File[] getCompressedFiles(String codePath) {
3183        return new File(codePath).listFiles(new FilenameFilter() {
3184            @Override
3185            public boolean accept(File dir, String name) {
3186                return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3187            }
3188        });
3189    }
3190
3191    private boolean compressedFileExists(String codePath) {
3192        final File[] compressedFiles = getCompressedFiles(codePath);
3193        return compressedFiles != null && compressedFiles.length > 0;
3194    }
3195
3196    /**
3197     * Decompresses the given package on the system image onto
3198     * the /data partition.
3199     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3200     */
3201    private File decompressPackage(PackageParser.Package pkg) {
3202        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3203        if (compressedFiles == null || compressedFiles.length == 0) {
3204            if (DEBUG_COMPRESSION) {
3205                Slog.i(TAG, "No files to decompress");
3206            }
3207            return null;
3208        }
3209        final File dstCodePath =
3210                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3211        int ret = PackageManager.INSTALL_SUCCEEDED;
3212        try {
3213            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3214            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3215            for (File srcFile : compressedFiles) {
3216                final String srcFileName = srcFile.getName();
3217                final String dstFileName = srcFileName.substring(
3218                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3219                final File dstFile = new File(dstCodePath, dstFileName);
3220                ret = decompressFile(srcFile, dstFile);
3221                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3222                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3223                            + "; pkg: " + pkg.packageName
3224                            + ", file: " + dstFileName);
3225                    break;
3226                }
3227            }
3228        } catch (ErrnoException e) {
3229            logCriticalInfo(Log.ERROR, "Failed to decompress"
3230                    + "; pkg: " + pkg.packageName
3231                    + ", err: " + e.errno);
3232        }
3233        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3234            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3235            NativeLibraryHelper.Handle handle = null;
3236            try {
3237                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3238                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3239                        null /*abiOverride*/);
3240            } catch (IOException e) {
3241                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3242                        + "; pkg: " + pkg.packageName);
3243                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3244            } finally {
3245                IoUtils.closeQuietly(handle);
3246            }
3247        }
3248        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3249            if (dstCodePath == null || !dstCodePath.exists()) {
3250                return null;
3251            }
3252            removeCodePathLI(dstCodePath);
3253            return null;
3254        }
3255        return dstCodePath;
3256    }
3257
3258    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3259        // we're only interested in updating the installer appliction when 1) it's not
3260        // already set or 2) the modified package is the installer
3261        if (mInstantAppInstallerActivity != null
3262                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3263                        .equals(modifiedPackage)) {
3264            return;
3265        }
3266        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3267    }
3268
3269    private static File preparePackageParserCache(boolean isUpgrade) {
3270        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3271            return null;
3272        }
3273
3274        // Disable package parsing on eng builds to allow for faster incremental development.
3275        if (Build.IS_ENG) {
3276            return null;
3277        }
3278
3279        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3280            Slog.i(TAG, "Disabling package parser cache due to system property.");
3281            return null;
3282        }
3283
3284        // The base directory for the package parser cache lives under /data/system/.
3285        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3286                "package_cache");
3287        if (cacheBaseDir == null) {
3288            return null;
3289        }
3290
3291        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3292        // This also serves to "GC" unused entries when the package cache version changes (which
3293        // can only happen during upgrades).
3294        if (isUpgrade) {
3295            FileUtils.deleteContents(cacheBaseDir);
3296        }
3297
3298
3299        // Return the versioned package cache directory. This is something like
3300        // "/data/system/package_cache/1"
3301        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3302
3303        // The following is a workaround to aid development on non-numbered userdebug
3304        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3305        // the system partition is newer.
3306        //
3307        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3308        // that starts with "eng." to signify that this is an engineering build and not
3309        // destined for release.
3310        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3311            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3312
3313            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3314            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3315            // in general and should not be used for production changes. In this specific case,
3316            // we know that they will work.
3317            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3318            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3319                FileUtils.deleteContents(cacheBaseDir);
3320                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3321            }
3322        }
3323
3324        return cacheDir;
3325    }
3326
3327    @Override
3328    public boolean isFirstBoot() {
3329        // allow instant applications
3330        return mFirstBoot;
3331    }
3332
3333    @Override
3334    public boolean isOnlyCoreApps() {
3335        // allow instant applications
3336        return mOnlyCore;
3337    }
3338
3339    @Override
3340    public boolean isUpgrade() {
3341        // allow instant applications
3342        return mIsUpgrade;
3343    }
3344
3345    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3346        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3347
3348        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3349                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3350                UserHandle.USER_SYSTEM);
3351        if (matches.size() == 1) {
3352            return matches.get(0).getComponentInfo().packageName;
3353        } else if (matches.size() == 0) {
3354            Log.e(TAG, "There should probably be a verifier, but, none were found");
3355            return null;
3356        }
3357        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3358    }
3359
3360    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3361        synchronized (mPackages) {
3362            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3363            if (libraryEntry == null) {
3364                throw new IllegalStateException("Missing required shared library:" + name);
3365            }
3366            return libraryEntry.apk;
3367        }
3368    }
3369
3370    private @NonNull String getRequiredInstallerLPr() {
3371        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3372        intent.addCategory(Intent.CATEGORY_DEFAULT);
3373        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3374
3375        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3376                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3377                UserHandle.USER_SYSTEM);
3378        if (matches.size() == 1) {
3379            ResolveInfo resolveInfo = matches.get(0);
3380            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3381                throw new RuntimeException("The installer must be a privileged app");
3382            }
3383            return matches.get(0).getComponentInfo().packageName;
3384        } else {
3385            throw new RuntimeException("There must be exactly one installer; found " + matches);
3386        }
3387    }
3388
3389    private @NonNull String getRequiredUninstallerLPr() {
3390        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3391        intent.addCategory(Intent.CATEGORY_DEFAULT);
3392        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3393
3394        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3395                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3396                UserHandle.USER_SYSTEM);
3397        if (resolveInfo == null ||
3398                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3399            throw new RuntimeException("There must be exactly one uninstaller; found "
3400                    + resolveInfo);
3401        }
3402        return resolveInfo.getComponentInfo().packageName;
3403    }
3404
3405    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3406        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3407
3408        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3409                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3410                UserHandle.USER_SYSTEM);
3411        ResolveInfo best = null;
3412        final int N = matches.size();
3413        for (int i = 0; i < N; i++) {
3414            final ResolveInfo cur = matches.get(i);
3415            final String packageName = cur.getComponentInfo().packageName;
3416            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3417                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3418                continue;
3419            }
3420
3421            if (best == null || cur.priority > best.priority) {
3422                best = cur;
3423            }
3424        }
3425
3426        if (best != null) {
3427            return best.getComponentInfo().getComponentName();
3428        }
3429        Slog.w(TAG, "Intent filter verifier not found");
3430        return null;
3431    }
3432
3433    @Override
3434    public @Nullable ComponentName getInstantAppResolverComponent() {
3435        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3436            return null;
3437        }
3438        synchronized (mPackages) {
3439            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3440            if (instantAppResolver == null) {
3441                return null;
3442            }
3443            return instantAppResolver.first;
3444        }
3445    }
3446
3447    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3448        final String[] packageArray =
3449                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3450        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3451            if (DEBUG_EPHEMERAL) {
3452                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3453            }
3454            return null;
3455        }
3456
3457        final int callingUid = Binder.getCallingUid();
3458        final int resolveFlags =
3459                MATCH_DIRECT_BOOT_AWARE
3460                | MATCH_DIRECT_BOOT_UNAWARE
3461                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3462        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3463        final Intent resolverIntent = new Intent(actionName);
3464        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3465                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3466        // temporarily look for the old action
3467        if (resolvers.size() == 0) {
3468            if (DEBUG_EPHEMERAL) {
3469                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3470            }
3471            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3472            resolverIntent.setAction(actionName);
3473            resolvers = queryIntentServicesInternal(resolverIntent, null,
3474                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3475        }
3476        final int N = resolvers.size();
3477        if (N == 0) {
3478            if (DEBUG_EPHEMERAL) {
3479                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3480            }
3481            return null;
3482        }
3483
3484        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3485        for (int i = 0; i < N; i++) {
3486            final ResolveInfo info = resolvers.get(i);
3487
3488            if (info.serviceInfo == null) {
3489                continue;
3490            }
3491
3492            final String packageName = info.serviceInfo.packageName;
3493            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3494                if (DEBUG_EPHEMERAL) {
3495                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3496                            + " pkg: " + packageName + ", info:" + info);
3497                }
3498                continue;
3499            }
3500
3501            if (DEBUG_EPHEMERAL) {
3502                Slog.v(TAG, "Ephemeral resolver found;"
3503                        + " pkg: " + packageName + ", info:" + info);
3504            }
3505            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3506        }
3507        if (DEBUG_EPHEMERAL) {
3508            Slog.v(TAG, "Ephemeral resolver NOT found");
3509        }
3510        return null;
3511    }
3512
3513    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3514        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3515        intent.addCategory(Intent.CATEGORY_DEFAULT);
3516        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3517
3518        final int resolveFlags =
3519                MATCH_DIRECT_BOOT_AWARE
3520                | MATCH_DIRECT_BOOT_UNAWARE
3521                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3522        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3523                resolveFlags, UserHandle.USER_SYSTEM);
3524        // temporarily look for the old action
3525        if (matches.isEmpty()) {
3526            if (DEBUG_EPHEMERAL) {
3527                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3528            }
3529            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3530            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3531                    resolveFlags, UserHandle.USER_SYSTEM);
3532        }
3533        Iterator<ResolveInfo> iter = matches.iterator();
3534        while (iter.hasNext()) {
3535            final ResolveInfo rInfo = iter.next();
3536            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3537            if (ps != null) {
3538                final PermissionsState permissionsState = ps.getPermissionsState();
3539                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3540                    continue;
3541                }
3542            }
3543            iter.remove();
3544        }
3545        if (matches.size() == 0) {
3546            return null;
3547        } else if (matches.size() == 1) {
3548            return (ActivityInfo) matches.get(0).getComponentInfo();
3549        } else {
3550            throw new RuntimeException(
3551                    "There must be at most one ephemeral installer; found " + matches);
3552        }
3553    }
3554
3555    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3556            @NonNull ComponentName resolver) {
3557        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3558                .addCategory(Intent.CATEGORY_DEFAULT)
3559                .setPackage(resolver.getPackageName());
3560        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3561        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3562                UserHandle.USER_SYSTEM);
3563        // temporarily look for the old action
3564        if (matches.isEmpty()) {
3565            if (DEBUG_EPHEMERAL) {
3566                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3567            }
3568            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3569            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3570                    UserHandle.USER_SYSTEM);
3571        }
3572        if (matches.isEmpty()) {
3573            return null;
3574        }
3575        return matches.get(0).getComponentInfo().getComponentName();
3576    }
3577
3578    private void primeDomainVerificationsLPw(int userId) {
3579        if (DEBUG_DOMAIN_VERIFICATION) {
3580            Slog.d(TAG, "Priming domain verifications in user " + userId);
3581        }
3582
3583        SystemConfig systemConfig = SystemConfig.getInstance();
3584        ArraySet<String> packages = systemConfig.getLinkedApps();
3585
3586        for (String packageName : packages) {
3587            PackageParser.Package pkg = mPackages.get(packageName);
3588            if (pkg != null) {
3589                if (!pkg.isSystemApp()) {
3590                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3591                    continue;
3592                }
3593
3594                ArraySet<String> domains = null;
3595                for (PackageParser.Activity a : pkg.activities) {
3596                    for (ActivityIntentInfo filter : a.intents) {
3597                        if (hasValidDomains(filter)) {
3598                            if (domains == null) {
3599                                domains = new ArraySet<String>();
3600                            }
3601                            domains.addAll(filter.getHostsList());
3602                        }
3603                    }
3604                }
3605
3606                if (domains != null && domains.size() > 0) {
3607                    if (DEBUG_DOMAIN_VERIFICATION) {
3608                        Slog.v(TAG, "      + " + packageName);
3609                    }
3610                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3611                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3612                    // and then 'always' in the per-user state actually used for intent resolution.
3613                    final IntentFilterVerificationInfo ivi;
3614                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3615                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3616                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3617                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3618                } else {
3619                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3620                            + "' does not handle web links");
3621                }
3622            } else {
3623                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3624            }
3625        }
3626
3627        scheduleWritePackageRestrictionsLocked(userId);
3628        scheduleWriteSettingsLocked();
3629    }
3630
3631    private void applyFactoryDefaultBrowserLPw(int userId) {
3632        // The default browser app's package name is stored in a string resource,
3633        // with a product-specific overlay used for vendor customization.
3634        String browserPkg = mContext.getResources().getString(
3635                com.android.internal.R.string.default_browser);
3636        if (!TextUtils.isEmpty(browserPkg)) {
3637            // non-empty string => required to be a known package
3638            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3639            if (ps == null) {
3640                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3641                browserPkg = null;
3642            } else {
3643                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3644            }
3645        }
3646
3647        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3648        // default.  If there's more than one, just leave everything alone.
3649        if (browserPkg == null) {
3650            calculateDefaultBrowserLPw(userId);
3651        }
3652    }
3653
3654    private void calculateDefaultBrowserLPw(int userId) {
3655        List<String> allBrowsers = resolveAllBrowserApps(userId);
3656        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3657        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3658    }
3659
3660    private List<String> resolveAllBrowserApps(int userId) {
3661        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3662        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3663                PackageManager.MATCH_ALL, userId);
3664
3665        final int count = list.size();
3666        List<String> result = new ArrayList<String>(count);
3667        for (int i=0; i<count; i++) {
3668            ResolveInfo info = list.get(i);
3669            if (info.activityInfo == null
3670                    || !info.handleAllWebDataURI
3671                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3672                    || result.contains(info.activityInfo.packageName)) {
3673                continue;
3674            }
3675            result.add(info.activityInfo.packageName);
3676        }
3677
3678        return result;
3679    }
3680
3681    private boolean packageIsBrowser(String packageName, int userId) {
3682        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3683                PackageManager.MATCH_ALL, userId);
3684        final int N = list.size();
3685        for (int i = 0; i < N; i++) {
3686            ResolveInfo info = list.get(i);
3687            if (packageName.equals(info.activityInfo.packageName)) {
3688                return true;
3689            }
3690        }
3691        return false;
3692    }
3693
3694    private void checkDefaultBrowser() {
3695        final int myUserId = UserHandle.myUserId();
3696        final String packageName = getDefaultBrowserPackageName(myUserId);
3697        if (packageName != null) {
3698            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3699            if (info == null) {
3700                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3701                synchronized (mPackages) {
3702                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3703                }
3704            }
3705        }
3706    }
3707
3708    @Override
3709    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3710            throws RemoteException {
3711        try {
3712            return super.onTransact(code, data, reply, flags);
3713        } catch (RuntimeException e) {
3714            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3715                Slog.wtf(TAG, "Package Manager Crash", e);
3716            }
3717            throw e;
3718        }
3719    }
3720
3721    static int[] appendInts(int[] cur, int[] add) {
3722        if (add == null) return cur;
3723        if (cur == null) return add;
3724        final int N = add.length;
3725        for (int i=0; i<N; i++) {
3726            cur = appendInt(cur, add[i]);
3727        }
3728        return cur;
3729    }
3730
3731    /**
3732     * Returns whether or not a full application can see an instant application.
3733     * <p>
3734     * Currently, there are three cases in which this can occur:
3735     * <ol>
3736     * <li>The calling application is a "special" process. The special
3737     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3738     *     and {@code 0}</li>
3739     * <li>The calling application has the permission
3740     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3741     * <li>The calling application is the default launcher on the
3742     *     system partition.</li>
3743     * </ol>
3744     */
3745    private boolean canViewInstantApps(int callingUid, int userId) {
3746        if (callingUid == Process.SYSTEM_UID
3747                || callingUid == Process.SHELL_UID
3748                || callingUid == Process.ROOT_UID) {
3749            return true;
3750        }
3751        if (mContext.checkCallingOrSelfPermission(
3752                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3753            return true;
3754        }
3755        if (mContext.checkCallingOrSelfPermission(
3756                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3757            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3758            if (homeComponent != null
3759                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3760                return true;
3761            }
3762        }
3763        return false;
3764    }
3765
3766    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3767        if (!sUserManager.exists(userId)) return null;
3768        if (ps == null) {
3769            return null;
3770        }
3771        PackageParser.Package p = ps.pkg;
3772        if (p == null) {
3773            return null;
3774        }
3775        final int callingUid = Binder.getCallingUid();
3776        // Filter out ephemeral app metadata:
3777        //   * The system/shell/root can see metadata for any app
3778        //   * An installed app can see metadata for 1) other installed apps
3779        //     and 2) ephemeral apps that have explicitly interacted with it
3780        //   * Ephemeral apps can only see their own data and exposed installed apps
3781        //   * Holding a signature permission allows seeing instant apps
3782        if (filterAppAccessLPr(ps, callingUid, userId)) {
3783            return null;
3784        }
3785
3786        final PermissionsState permissionsState = ps.getPermissionsState();
3787
3788        // Compute GIDs only if requested
3789        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3790                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3791        // Compute granted permissions only if package has requested permissions
3792        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3793                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3794        final PackageUserState state = ps.readUserState(userId);
3795
3796        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3797                && ps.isSystem()) {
3798            flags |= MATCH_ANY_USER;
3799        }
3800
3801        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3802                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3803
3804        if (packageInfo == null) {
3805            return null;
3806        }
3807
3808        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3809                resolveExternalPackageNameLPr(p);
3810
3811        return packageInfo;
3812    }
3813
3814    @Override
3815    public void checkPackageStartable(String packageName, int userId) {
3816        final int callingUid = Binder.getCallingUid();
3817        if (getInstantAppPackageName(callingUid) != null) {
3818            throw new SecurityException("Instant applications don't have access to this method");
3819        }
3820        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3821        synchronized (mPackages) {
3822            final PackageSetting ps = mSettings.mPackages.get(packageName);
3823            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3824                throw new SecurityException("Package " + packageName + " was not found!");
3825            }
3826
3827            if (!ps.getInstalled(userId)) {
3828                throw new SecurityException(
3829                        "Package " + packageName + " was not installed for user " + userId + "!");
3830            }
3831
3832            if (mSafeMode && !ps.isSystem()) {
3833                throw new SecurityException("Package " + packageName + " not a system app!");
3834            }
3835
3836            if (mFrozenPackages.contains(packageName)) {
3837                throw new SecurityException("Package " + packageName + " is currently frozen!");
3838            }
3839
3840            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3841                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3842                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3843            }
3844        }
3845    }
3846
3847    @Override
3848    public boolean isPackageAvailable(String packageName, int userId) {
3849        if (!sUserManager.exists(userId)) return false;
3850        final int callingUid = Binder.getCallingUid();
3851        enforceCrossUserPermission(callingUid, userId,
3852                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3853        synchronized (mPackages) {
3854            PackageParser.Package p = mPackages.get(packageName);
3855            if (p != null) {
3856                final PackageSetting ps = (PackageSetting) p.mExtras;
3857                if (filterAppAccessLPr(ps, callingUid, userId)) {
3858                    return false;
3859                }
3860                if (ps != null) {
3861                    final PackageUserState state = ps.readUserState(userId);
3862                    if (state != null) {
3863                        return PackageParser.isAvailable(state);
3864                    }
3865                }
3866            }
3867        }
3868        return false;
3869    }
3870
3871    @Override
3872    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3873        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3874                flags, Binder.getCallingUid(), userId);
3875    }
3876
3877    @Override
3878    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3879            int flags, int userId) {
3880        return getPackageInfoInternal(versionedPackage.getPackageName(),
3881                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3882    }
3883
3884    /**
3885     * Important: The provided filterCallingUid is used exclusively to filter out packages
3886     * that can be seen based on user state. It's typically the original caller uid prior
3887     * to clearing. Because it can only be provided by trusted code, it's value can be
3888     * trusted and will be used as-is; unlike userId which will be validated by this method.
3889     */
3890    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3891            int flags, int filterCallingUid, int userId) {
3892        if (!sUserManager.exists(userId)) return null;
3893        flags = updateFlagsForPackage(flags, userId, packageName);
3894        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3895                false /* requireFullPermission */, false /* checkShell */, "get package info");
3896
3897        // reader
3898        synchronized (mPackages) {
3899            // Normalize package name to handle renamed packages and static libs
3900            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3901
3902            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3903            if (matchFactoryOnly) {
3904                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3905                if (ps != null) {
3906                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3907                        return null;
3908                    }
3909                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3910                        return null;
3911                    }
3912                    return generatePackageInfo(ps, flags, userId);
3913                }
3914            }
3915
3916            PackageParser.Package p = mPackages.get(packageName);
3917            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3918                return null;
3919            }
3920            if (DEBUG_PACKAGE_INFO)
3921                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3922            if (p != null) {
3923                final PackageSetting ps = (PackageSetting) p.mExtras;
3924                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3925                    return null;
3926                }
3927                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3928                    return null;
3929                }
3930                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3931            }
3932            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3933                final PackageSetting ps = mSettings.mPackages.get(packageName);
3934                if (ps == null) return null;
3935                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3936                    return null;
3937                }
3938                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3939                    return null;
3940                }
3941                return generatePackageInfo(ps, flags, userId);
3942            }
3943        }
3944        return null;
3945    }
3946
3947    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3948        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3949            return true;
3950        }
3951        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3952            return true;
3953        }
3954        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3955            return true;
3956        }
3957        return false;
3958    }
3959
3960    private boolean isComponentVisibleToInstantApp(
3961            @Nullable ComponentName component, @ComponentType int type) {
3962        if (type == TYPE_ACTIVITY) {
3963            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3964            return activity != null
3965                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3966                    : false;
3967        } else if (type == TYPE_RECEIVER) {
3968            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3969            return activity != null
3970                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3971                    : false;
3972        } else if (type == TYPE_SERVICE) {
3973            final PackageParser.Service service = mServices.mServices.get(component);
3974            return service != null
3975                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3976                    : false;
3977        } else if (type == TYPE_PROVIDER) {
3978            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3979            return provider != null
3980                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3981                    : false;
3982        } else if (type == TYPE_UNKNOWN) {
3983            return isComponentVisibleToInstantApp(component);
3984        }
3985        return false;
3986    }
3987
3988    /**
3989     * Returns whether or not access to the application should be filtered.
3990     * <p>
3991     * Access may be limited based upon whether the calling or target applications
3992     * are instant applications.
3993     *
3994     * @see #canAccessInstantApps(int)
3995     */
3996    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3997            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3998        // if we're in an isolated process, get the real calling UID
3999        if (Process.isIsolated(callingUid)) {
4000            callingUid = mIsolatedOwners.get(callingUid);
4001        }
4002        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4003        final boolean callerIsInstantApp = instantAppPkgName != null;
4004        if (ps == null) {
4005            if (callerIsInstantApp) {
4006                // pretend the application exists, but, needs to be filtered
4007                return true;
4008            }
4009            return false;
4010        }
4011        // if the target and caller are the same application, don't filter
4012        if (isCallerSameApp(ps.name, callingUid)) {
4013            return false;
4014        }
4015        if (callerIsInstantApp) {
4016            // request for a specific component; if it hasn't been explicitly exposed, filter
4017            if (component != null) {
4018                return !isComponentVisibleToInstantApp(component, componentType);
4019            }
4020            // request for application; if no components have been explicitly exposed, filter
4021            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4022        }
4023        if (ps.getInstantApp(userId)) {
4024            // caller can see all components of all instant applications, don't filter
4025            if (canViewInstantApps(callingUid, userId)) {
4026                return false;
4027            }
4028            // request for a specific instant application component, filter
4029            if (component != null) {
4030                return true;
4031            }
4032            // request for an instant application; if the caller hasn't been granted access, filter
4033            return !mInstantAppRegistry.isInstantAccessGranted(
4034                    userId, UserHandle.getAppId(callingUid), ps.appId);
4035        }
4036        return false;
4037    }
4038
4039    /**
4040     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4041     */
4042    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4043        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4044    }
4045
4046    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4047            int flags) {
4048        // Callers can access only the libs they depend on, otherwise they need to explicitly
4049        // ask for the shared libraries given the caller is allowed to access all static libs.
4050        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4051            // System/shell/root get to see all static libs
4052            final int appId = UserHandle.getAppId(uid);
4053            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4054                    || appId == Process.ROOT_UID) {
4055                return false;
4056            }
4057        }
4058
4059        // No package means no static lib as it is always on internal storage
4060        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4061            return false;
4062        }
4063
4064        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4065                ps.pkg.staticSharedLibVersion);
4066        if (libEntry == null) {
4067            return false;
4068        }
4069
4070        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4071        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4072        if (uidPackageNames == null) {
4073            return true;
4074        }
4075
4076        for (String uidPackageName : uidPackageNames) {
4077            if (ps.name.equals(uidPackageName)) {
4078                return false;
4079            }
4080            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4081            if (uidPs != null) {
4082                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4083                        libEntry.info.getName());
4084                if (index < 0) {
4085                    continue;
4086                }
4087                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4088                    return false;
4089                }
4090            }
4091        }
4092        return true;
4093    }
4094
4095    @Override
4096    public String[] currentToCanonicalPackageNames(String[] names) {
4097        final int callingUid = Binder.getCallingUid();
4098        if (getInstantAppPackageName(callingUid) != null) {
4099            return names;
4100        }
4101        final String[] out = new String[names.length];
4102        // reader
4103        synchronized (mPackages) {
4104            final int callingUserId = UserHandle.getUserId(callingUid);
4105            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4106            for (int i=names.length-1; i>=0; i--) {
4107                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4108                boolean translateName = false;
4109                if (ps != null && ps.realName != null) {
4110                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4111                    translateName = !targetIsInstantApp
4112                            || canViewInstantApps
4113                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4114                                    UserHandle.getAppId(callingUid), ps.appId);
4115                }
4116                out[i] = translateName ? ps.realName : names[i];
4117            }
4118        }
4119        return out;
4120    }
4121
4122    @Override
4123    public String[] canonicalToCurrentPackageNames(String[] names) {
4124        final int callingUid = Binder.getCallingUid();
4125        if (getInstantAppPackageName(callingUid) != null) {
4126            return names;
4127        }
4128        final String[] out = new String[names.length];
4129        // reader
4130        synchronized (mPackages) {
4131            final int callingUserId = UserHandle.getUserId(callingUid);
4132            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4133            for (int i=names.length-1; i>=0; i--) {
4134                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4135                boolean translateName = false;
4136                if (cur != null) {
4137                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4138                    final boolean targetIsInstantApp =
4139                            ps != null && ps.getInstantApp(callingUserId);
4140                    translateName = !targetIsInstantApp
4141                            || canViewInstantApps
4142                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4143                                    UserHandle.getAppId(callingUid), ps.appId);
4144                }
4145                out[i] = translateName ? cur : names[i];
4146            }
4147        }
4148        return out;
4149    }
4150
4151    @Override
4152    public int getPackageUid(String packageName, int flags, int userId) {
4153        if (!sUserManager.exists(userId)) return -1;
4154        final int callingUid = Binder.getCallingUid();
4155        flags = updateFlagsForPackage(flags, userId, packageName);
4156        enforceCrossUserPermission(callingUid, userId,
4157                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4158
4159        // reader
4160        synchronized (mPackages) {
4161            final PackageParser.Package p = mPackages.get(packageName);
4162            if (p != null && p.isMatch(flags)) {
4163                PackageSetting ps = (PackageSetting) p.mExtras;
4164                if (filterAppAccessLPr(ps, callingUid, userId)) {
4165                    return -1;
4166                }
4167                return UserHandle.getUid(userId, p.applicationInfo.uid);
4168            }
4169            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4170                final PackageSetting ps = mSettings.mPackages.get(packageName);
4171                if (ps != null && ps.isMatch(flags)
4172                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4173                    return UserHandle.getUid(userId, ps.appId);
4174                }
4175            }
4176        }
4177
4178        return -1;
4179    }
4180
4181    @Override
4182    public int[] getPackageGids(String packageName, int flags, int userId) {
4183        if (!sUserManager.exists(userId)) return null;
4184        final int callingUid = Binder.getCallingUid();
4185        flags = updateFlagsForPackage(flags, userId, packageName);
4186        enforceCrossUserPermission(callingUid, userId,
4187                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4188
4189        // reader
4190        synchronized (mPackages) {
4191            final PackageParser.Package p = mPackages.get(packageName);
4192            if (p != null && p.isMatch(flags)) {
4193                PackageSetting ps = (PackageSetting) p.mExtras;
4194                if (filterAppAccessLPr(ps, callingUid, userId)) {
4195                    return null;
4196                }
4197                // TODO: Shouldn't this be checking for package installed state for userId and
4198                // return null?
4199                return ps.getPermissionsState().computeGids(userId);
4200            }
4201            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4202                final PackageSetting ps = mSettings.mPackages.get(packageName);
4203                if (ps != null && ps.isMatch(flags)
4204                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4205                    return ps.getPermissionsState().computeGids(userId);
4206                }
4207            }
4208        }
4209
4210        return null;
4211    }
4212
4213    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4214        if (bp.perm != null) {
4215            return PackageParser.generatePermissionInfo(bp.perm, flags);
4216        }
4217        PermissionInfo pi = new PermissionInfo();
4218        pi.name = bp.name;
4219        pi.packageName = bp.sourcePackage;
4220        pi.nonLocalizedLabel = bp.name;
4221        pi.protectionLevel = bp.protectionLevel;
4222        return pi;
4223    }
4224
4225    @Override
4226    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4227        final int callingUid = Binder.getCallingUid();
4228        if (getInstantAppPackageName(callingUid) != null) {
4229            return null;
4230        }
4231        // reader
4232        synchronized (mPackages) {
4233            final BasePermission p = mSettings.mPermissions.get(name);
4234            if (p == null) {
4235                return null;
4236            }
4237            // If the caller is an app that targets pre 26 SDK drop protection flags.
4238            final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4239            if (permissionInfo != null) {
4240                permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
4241                        permissionInfo.protectionLevel, packageName, callingUid);
4242            }
4243            return permissionInfo;
4244        }
4245    }
4246
4247    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4248            String packageName, int uid) {
4249        // Signature permission flags area always reported
4250        final int protectionLevelMasked = protectionLevel
4251                & (PermissionInfo.PROTECTION_NORMAL
4252                | PermissionInfo.PROTECTION_DANGEROUS
4253                | PermissionInfo.PROTECTION_SIGNATURE);
4254        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4255            return protectionLevel;
4256        }
4257
4258        // System sees all flags.
4259        final int appId = UserHandle.getAppId(uid);
4260        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4261                || appId == Process.SHELL_UID) {
4262            return protectionLevel;
4263        }
4264
4265        // Normalize package name to handle renamed packages and static libs
4266        packageName = resolveInternalPackageNameLPr(packageName,
4267                PackageManager.VERSION_CODE_HIGHEST);
4268
4269        // Apps that target O see flags for all protection levels.
4270        final PackageSetting ps = mSettings.mPackages.get(packageName);
4271        if (ps == null) {
4272            return protectionLevel;
4273        }
4274        if (ps.appId != appId) {
4275            return protectionLevel;
4276        }
4277
4278        final PackageParser.Package pkg = mPackages.get(packageName);
4279        if (pkg == null) {
4280            return protectionLevel;
4281        }
4282        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4283            return protectionLevelMasked;
4284        }
4285
4286        return protectionLevel;
4287    }
4288
4289    @Override
4290    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4291            int flags) {
4292        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4293            return null;
4294        }
4295        // reader
4296        synchronized (mPackages) {
4297            if (group != null && !mPermissionGroups.containsKey(group)) {
4298                // This is thrown as NameNotFoundException
4299                return null;
4300            }
4301
4302            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4303            for (BasePermission p : mSettings.mPermissions.values()) {
4304                if (group == null) {
4305                    if (p.perm == null || p.perm.info.group == null) {
4306                        out.add(generatePermissionInfo(p, flags));
4307                    }
4308                } else {
4309                    if (p.perm != null && group.equals(p.perm.info.group)) {
4310                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4311                    }
4312                }
4313            }
4314            return new ParceledListSlice<>(out);
4315        }
4316    }
4317
4318    @Override
4319    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4320        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4321            return null;
4322        }
4323        // reader
4324        synchronized (mPackages) {
4325            return PackageParser.generatePermissionGroupInfo(
4326                    mPermissionGroups.get(name), flags);
4327        }
4328    }
4329
4330    @Override
4331    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4332        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4333            return ParceledListSlice.emptyList();
4334        }
4335        // reader
4336        synchronized (mPackages) {
4337            final int N = mPermissionGroups.size();
4338            ArrayList<PermissionGroupInfo> out
4339                    = new ArrayList<PermissionGroupInfo>(N);
4340            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4341                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4342            }
4343            return new ParceledListSlice<>(out);
4344        }
4345    }
4346
4347    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4348            int filterCallingUid, int userId) {
4349        if (!sUserManager.exists(userId)) return null;
4350        PackageSetting ps = mSettings.mPackages.get(packageName);
4351        if (ps != null) {
4352            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4353                return null;
4354            }
4355            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4356                return null;
4357            }
4358            if (ps.pkg == null) {
4359                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4360                if (pInfo != null) {
4361                    return pInfo.applicationInfo;
4362                }
4363                return null;
4364            }
4365            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4366                    ps.readUserState(userId), userId);
4367            if (ai != null) {
4368                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4369            }
4370            return ai;
4371        }
4372        return null;
4373    }
4374
4375    @Override
4376    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4377        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4378    }
4379
4380    /**
4381     * Important: The provided filterCallingUid is used exclusively to filter out applications
4382     * that can be seen based on user state. It's typically the original caller uid prior
4383     * to clearing. Because it can only be provided by trusted code, it's value can be
4384     * trusted and will be used as-is; unlike userId which will be validated by this method.
4385     */
4386    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4387            int filterCallingUid, int userId) {
4388        if (!sUserManager.exists(userId)) return null;
4389        flags = updateFlagsForApplication(flags, userId, packageName);
4390        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4391                false /* requireFullPermission */, false /* checkShell */, "get application info");
4392
4393        // writer
4394        synchronized (mPackages) {
4395            // Normalize package name to handle renamed packages and static libs
4396            packageName = resolveInternalPackageNameLPr(packageName,
4397                    PackageManager.VERSION_CODE_HIGHEST);
4398
4399            PackageParser.Package p = mPackages.get(packageName);
4400            if (DEBUG_PACKAGE_INFO) Log.v(
4401                    TAG, "getApplicationInfo " + packageName
4402                    + ": " + p);
4403            if (p != null) {
4404                PackageSetting ps = mSettings.mPackages.get(packageName);
4405                if (ps == null) return null;
4406                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4407                    return null;
4408                }
4409                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4410                    return null;
4411                }
4412                // Note: isEnabledLP() does not apply here - always return info
4413                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4414                        p, flags, ps.readUserState(userId), userId);
4415                if (ai != null) {
4416                    ai.packageName = resolveExternalPackageNameLPr(p);
4417                }
4418                return ai;
4419            }
4420            if ("android".equals(packageName)||"system".equals(packageName)) {
4421                return mAndroidApplication;
4422            }
4423            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4424                // Already generates the external package name
4425                return generateApplicationInfoFromSettingsLPw(packageName,
4426                        flags, filterCallingUid, userId);
4427            }
4428        }
4429        return null;
4430    }
4431
4432    private String normalizePackageNameLPr(String packageName) {
4433        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4434        return normalizedPackageName != null ? normalizedPackageName : packageName;
4435    }
4436
4437    @Override
4438    public void deletePreloadsFileCache() {
4439        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4440            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4441        }
4442        File dir = Environment.getDataPreloadsFileCacheDirectory();
4443        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4444        FileUtils.deleteContents(dir);
4445    }
4446
4447    @Override
4448    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4449            final int storageFlags, final IPackageDataObserver observer) {
4450        mContext.enforceCallingOrSelfPermission(
4451                android.Manifest.permission.CLEAR_APP_CACHE, null);
4452        mHandler.post(() -> {
4453            boolean success = false;
4454            try {
4455                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4456                success = true;
4457            } catch (IOException e) {
4458                Slog.w(TAG, e);
4459            }
4460            if (observer != null) {
4461                try {
4462                    observer.onRemoveCompleted(null, success);
4463                } catch (RemoteException e) {
4464                    Slog.w(TAG, e);
4465                }
4466            }
4467        });
4468    }
4469
4470    @Override
4471    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4472            final int storageFlags, final IntentSender pi) {
4473        mContext.enforceCallingOrSelfPermission(
4474                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4475        mHandler.post(() -> {
4476            boolean success = false;
4477            try {
4478                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4479                success = true;
4480            } catch (IOException e) {
4481                Slog.w(TAG, e);
4482            }
4483            if (pi != null) {
4484                try {
4485                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4486                } catch (SendIntentException e) {
4487                    Slog.w(TAG, e);
4488                }
4489            }
4490        });
4491    }
4492
4493    /**
4494     * Blocking call to clear various types of cached data across the system
4495     * until the requested bytes are available.
4496     */
4497    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4498        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4499        final File file = storage.findPathForUuid(volumeUuid);
4500        if (file.getUsableSpace() >= bytes) return;
4501
4502        if (ENABLE_FREE_CACHE_V2) {
4503            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4504                    volumeUuid);
4505            final boolean aggressive = (storageFlags
4506                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4507            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4508
4509            // 1. Pre-flight to determine if we have any chance to succeed
4510            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4511            if (internalVolume && (aggressive || SystemProperties
4512                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4513                deletePreloadsFileCache();
4514                if (file.getUsableSpace() >= bytes) return;
4515            }
4516
4517            // 3. Consider parsed APK data (aggressive only)
4518            if (internalVolume && aggressive) {
4519                FileUtils.deleteContents(mCacheDir);
4520                if (file.getUsableSpace() >= bytes) return;
4521            }
4522
4523            // 4. Consider cached app data (above quotas)
4524            try {
4525                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4526                        Installer.FLAG_FREE_CACHE_V2);
4527            } catch (InstallerException ignored) {
4528            }
4529            if (file.getUsableSpace() >= bytes) return;
4530
4531            // 5. Consider shared libraries with refcount=0 and age>min cache period
4532            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4533                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4534                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4535                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4536                return;
4537            }
4538
4539            // 6. Consider dexopt output (aggressive only)
4540            // TODO: Implement
4541
4542            // 7. Consider installed instant apps unused longer than min cache period
4543            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4544                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4545                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4546                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4547                return;
4548            }
4549
4550            // 8. Consider cached app data (below quotas)
4551            try {
4552                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4553                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4554            } catch (InstallerException ignored) {
4555            }
4556            if (file.getUsableSpace() >= bytes) return;
4557
4558            // 9. Consider DropBox entries
4559            // TODO: Implement
4560
4561            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4562            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4563                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4564                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4565                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4566                return;
4567            }
4568        } else {
4569            try {
4570                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4571            } catch (InstallerException ignored) {
4572            }
4573            if (file.getUsableSpace() >= bytes) return;
4574        }
4575
4576        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4577    }
4578
4579    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4580            throws IOException {
4581        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4582        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4583
4584        List<VersionedPackage> packagesToDelete = null;
4585        final long now = System.currentTimeMillis();
4586
4587        synchronized (mPackages) {
4588            final int[] allUsers = sUserManager.getUserIds();
4589            final int libCount = mSharedLibraries.size();
4590            for (int i = 0; i < libCount; i++) {
4591                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4592                if (versionedLib == null) {
4593                    continue;
4594                }
4595                final int versionCount = versionedLib.size();
4596                for (int j = 0; j < versionCount; j++) {
4597                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4598                    // Skip packages that are not static shared libs.
4599                    if (!libInfo.isStatic()) {
4600                        break;
4601                    }
4602                    // Important: We skip static shared libs used for some user since
4603                    // in such a case we need to keep the APK on the device. The check for
4604                    // a lib being used for any user is performed by the uninstall call.
4605                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4606                    // Resolve the package name - we use synthetic package names internally
4607                    final String internalPackageName = resolveInternalPackageNameLPr(
4608                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4609                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4610                    // Skip unused static shared libs cached less than the min period
4611                    // to prevent pruning a lib needed by a subsequently installed package.
4612                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4613                        continue;
4614                    }
4615                    if (packagesToDelete == null) {
4616                        packagesToDelete = new ArrayList<>();
4617                    }
4618                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4619                            declaringPackage.getVersionCode()));
4620                }
4621            }
4622        }
4623
4624        if (packagesToDelete != null) {
4625            final int packageCount = packagesToDelete.size();
4626            for (int i = 0; i < packageCount; i++) {
4627                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4628                // Delete the package synchronously (will fail of the lib used for any user).
4629                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4630                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4631                                == PackageManager.DELETE_SUCCEEDED) {
4632                    if (volume.getUsableSpace() >= neededSpace) {
4633                        return true;
4634                    }
4635                }
4636            }
4637        }
4638
4639        return false;
4640    }
4641
4642    /**
4643     * Update given flags based on encryption status of current user.
4644     */
4645    private int updateFlags(int flags, int userId) {
4646        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4647                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4648            // Caller expressed an explicit opinion about what encryption
4649            // aware/unaware components they want to see, so fall through and
4650            // give them what they want
4651        } else {
4652            // Caller expressed no opinion, so match based on user state
4653            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4654                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4655            } else {
4656                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4657            }
4658        }
4659        return flags;
4660    }
4661
4662    private UserManagerInternal getUserManagerInternal() {
4663        if (mUserManagerInternal == null) {
4664            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4665        }
4666        return mUserManagerInternal;
4667    }
4668
4669    private DeviceIdleController.LocalService getDeviceIdleController() {
4670        if (mDeviceIdleController == null) {
4671            mDeviceIdleController =
4672                    LocalServices.getService(DeviceIdleController.LocalService.class);
4673        }
4674        return mDeviceIdleController;
4675    }
4676
4677    /**
4678     * Update given flags when being used to request {@link PackageInfo}.
4679     */
4680    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4681        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4682        boolean triaged = true;
4683        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4684                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4685            // Caller is asking for component details, so they'd better be
4686            // asking for specific encryption matching behavior, or be triaged
4687            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4688                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4689                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4690                triaged = false;
4691            }
4692        }
4693        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4694                | PackageManager.MATCH_SYSTEM_ONLY
4695                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4696            triaged = false;
4697        }
4698        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4699            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4700                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4701                    + Debug.getCallers(5));
4702        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4703                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4704            // If the caller wants all packages and has a restricted profile associated with it,
4705            // then match all users. This is to make sure that launchers that need to access work
4706            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4707            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4708            flags |= PackageManager.MATCH_ANY_USER;
4709        }
4710        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4711            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4712                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4713        }
4714        return updateFlags(flags, userId);
4715    }
4716
4717    /**
4718     * Update given flags when being used to request {@link ApplicationInfo}.
4719     */
4720    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4721        return updateFlagsForPackage(flags, userId, cookie);
4722    }
4723
4724    /**
4725     * Update given flags when being used to request {@link ComponentInfo}.
4726     */
4727    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4728        if (cookie instanceof Intent) {
4729            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4730                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4731            }
4732        }
4733
4734        boolean triaged = true;
4735        // Caller is asking for component details, so they'd better be
4736        // asking for specific encryption matching behavior, or be triaged
4737        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4738                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4739                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4740            triaged = false;
4741        }
4742        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4743            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4744                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4745        }
4746
4747        return updateFlags(flags, userId);
4748    }
4749
4750    /**
4751     * Update given intent when being used to request {@link ResolveInfo}.
4752     */
4753    private Intent updateIntentForResolve(Intent intent) {
4754        if (intent.getSelector() != null) {
4755            intent = intent.getSelector();
4756        }
4757        if (DEBUG_PREFERRED) {
4758            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4759        }
4760        return intent;
4761    }
4762
4763    /**
4764     * Update given flags when being used to request {@link ResolveInfo}.
4765     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4766     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4767     * flag set. However, this flag is only honoured in three circumstances:
4768     * <ul>
4769     * <li>when called from a system process</li>
4770     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4771     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4772     * action and a {@code android.intent.category.BROWSABLE} category</li>
4773     * </ul>
4774     */
4775    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4776        return updateFlagsForResolve(flags, userId, intent, callingUid,
4777                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4778    }
4779    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4780            boolean wantInstantApps) {
4781        return updateFlagsForResolve(flags, userId, intent, callingUid,
4782                wantInstantApps, false /*onlyExposedExplicitly*/);
4783    }
4784    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4785            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4786        // Safe mode means we shouldn't match any third-party components
4787        if (mSafeMode) {
4788            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4789        }
4790        if (getInstantAppPackageName(callingUid) != null) {
4791            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4792            if (onlyExposedExplicitly) {
4793                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4794            }
4795            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4796            flags |= PackageManager.MATCH_INSTANT;
4797        } else {
4798            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4799            final boolean allowMatchInstant =
4800                    (wantInstantApps
4801                            && Intent.ACTION_VIEW.equals(intent.getAction())
4802                            && hasWebURI(intent))
4803                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4804            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4805                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4806            if (!allowMatchInstant) {
4807                flags &= ~PackageManager.MATCH_INSTANT;
4808            }
4809        }
4810        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4811    }
4812
4813    @Override
4814    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4815        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4816    }
4817
4818    /**
4819     * Important: The provided filterCallingUid is used exclusively to filter out activities
4820     * that can be seen based on user state. It's typically the original caller uid prior
4821     * to clearing. Because it can only be provided by trusted code, it's value can be
4822     * trusted and will be used as-is; unlike userId which will be validated by this method.
4823     */
4824    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4825            int filterCallingUid, int userId) {
4826        if (!sUserManager.exists(userId)) return null;
4827        flags = updateFlagsForComponent(flags, userId, component);
4828        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4829                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4830        synchronized (mPackages) {
4831            PackageParser.Activity a = mActivities.mActivities.get(component);
4832
4833            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4834            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4835                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4836                if (ps == null) return null;
4837                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4838                    return null;
4839                }
4840                return PackageParser.generateActivityInfo(
4841                        a, flags, ps.readUserState(userId), userId);
4842            }
4843            if (mResolveComponentName.equals(component)) {
4844                return PackageParser.generateActivityInfo(
4845                        mResolveActivity, flags, new PackageUserState(), userId);
4846            }
4847        }
4848        return null;
4849    }
4850
4851    @Override
4852    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4853            String resolvedType) {
4854        synchronized (mPackages) {
4855            if (component.equals(mResolveComponentName)) {
4856                // The resolver supports EVERYTHING!
4857                return true;
4858            }
4859            final int callingUid = Binder.getCallingUid();
4860            final int callingUserId = UserHandle.getUserId(callingUid);
4861            PackageParser.Activity a = mActivities.mActivities.get(component);
4862            if (a == null) {
4863                return false;
4864            }
4865            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4866            if (ps == null) {
4867                return false;
4868            }
4869            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4870                return false;
4871            }
4872            for (int i=0; i<a.intents.size(); i++) {
4873                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4874                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4875                    return true;
4876                }
4877            }
4878            return false;
4879        }
4880    }
4881
4882    @Override
4883    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4884        if (!sUserManager.exists(userId)) return null;
4885        final int callingUid = Binder.getCallingUid();
4886        flags = updateFlagsForComponent(flags, userId, component);
4887        enforceCrossUserPermission(callingUid, userId,
4888                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4889        synchronized (mPackages) {
4890            PackageParser.Activity a = mReceivers.mActivities.get(component);
4891            if (DEBUG_PACKAGE_INFO) Log.v(
4892                TAG, "getReceiverInfo " + component + ": " + a);
4893            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4894                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4895                if (ps == null) return null;
4896                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4897                    return null;
4898                }
4899                return PackageParser.generateActivityInfo(
4900                        a, flags, ps.readUserState(userId), userId);
4901            }
4902        }
4903        return null;
4904    }
4905
4906    @Override
4907    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4908            int flags, int userId) {
4909        if (!sUserManager.exists(userId)) return null;
4910        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4911        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4912            return null;
4913        }
4914
4915        flags = updateFlagsForPackage(flags, userId, null);
4916
4917        final boolean canSeeStaticLibraries =
4918                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4919                        == PERMISSION_GRANTED
4920                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4921                        == PERMISSION_GRANTED
4922                || canRequestPackageInstallsInternal(packageName,
4923                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4924                        false  /* throwIfPermNotDeclared*/)
4925                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4926                        == PERMISSION_GRANTED;
4927
4928        synchronized (mPackages) {
4929            List<SharedLibraryInfo> result = null;
4930
4931            final int libCount = mSharedLibraries.size();
4932            for (int i = 0; i < libCount; i++) {
4933                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4934                if (versionedLib == null) {
4935                    continue;
4936                }
4937
4938                final int versionCount = versionedLib.size();
4939                for (int j = 0; j < versionCount; j++) {
4940                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4941                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4942                        break;
4943                    }
4944                    final long identity = Binder.clearCallingIdentity();
4945                    try {
4946                        PackageInfo packageInfo = getPackageInfoVersioned(
4947                                libInfo.getDeclaringPackage(), flags
4948                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4949                        if (packageInfo == null) {
4950                            continue;
4951                        }
4952                    } finally {
4953                        Binder.restoreCallingIdentity(identity);
4954                    }
4955
4956                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4957                            libInfo.getVersion(), libInfo.getType(),
4958                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4959                            flags, userId));
4960
4961                    if (result == null) {
4962                        result = new ArrayList<>();
4963                    }
4964                    result.add(resLibInfo);
4965                }
4966            }
4967
4968            return result != null ? new ParceledListSlice<>(result) : null;
4969        }
4970    }
4971
4972    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4973            SharedLibraryInfo libInfo, int flags, int userId) {
4974        List<VersionedPackage> versionedPackages = null;
4975        final int packageCount = mSettings.mPackages.size();
4976        for (int i = 0; i < packageCount; i++) {
4977            PackageSetting ps = mSettings.mPackages.valueAt(i);
4978
4979            if (ps == null) {
4980                continue;
4981            }
4982
4983            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4984                continue;
4985            }
4986
4987            final String libName = libInfo.getName();
4988            if (libInfo.isStatic()) {
4989                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4990                if (libIdx < 0) {
4991                    continue;
4992                }
4993                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4994                    continue;
4995                }
4996                if (versionedPackages == null) {
4997                    versionedPackages = new ArrayList<>();
4998                }
4999                // If the dependent is a static shared lib, use the public package name
5000                String dependentPackageName = ps.name;
5001                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5002                    dependentPackageName = ps.pkg.manifestPackageName;
5003                }
5004                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5005            } else if (ps.pkg != null) {
5006                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5007                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5008                    if (versionedPackages == null) {
5009                        versionedPackages = new ArrayList<>();
5010                    }
5011                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5012                }
5013            }
5014        }
5015
5016        return versionedPackages;
5017    }
5018
5019    @Override
5020    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5021        if (!sUserManager.exists(userId)) return null;
5022        final int callingUid = Binder.getCallingUid();
5023        flags = updateFlagsForComponent(flags, userId, component);
5024        enforceCrossUserPermission(callingUid, userId,
5025                false /* requireFullPermission */, false /* checkShell */, "get service info");
5026        synchronized (mPackages) {
5027            PackageParser.Service s = mServices.mServices.get(component);
5028            if (DEBUG_PACKAGE_INFO) Log.v(
5029                TAG, "getServiceInfo " + component + ": " + s);
5030            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5031                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5032                if (ps == null) return null;
5033                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5034                    return null;
5035                }
5036                return PackageParser.generateServiceInfo(
5037                        s, flags, ps.readUserState(userId), userId);
5038            }
5039        }
5040        return null;
5041    }
5042
5043    @Override
5044    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5045        if (!sUserManager.exists(userId)) return null;
5046        final int callingUid = Binder.getCallingUid();
5047        flags = updateFlagsForComponent(flags, userId, component);
5048        enforceCrossUserPermission(callingUid, userId,
5049                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5050        synchronized (mPackages) {
5051            PackageParser.Provider p = mProviders.mProviders.get(component);
5052            if (DEBUG_PACKAGE_INFO) Log.v(
5053                TAG, "getProviderInfo " + component + ": " + p);
5054            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5055                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5056                if (ps == null) return null;
5057                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5058                    return null;
5059                }
5060                return PackageParser.generateProviderInfo(
5061                        p, flags, ps.readUserState(userId), userId);
5062            }
5063        }
5064        return null;
5065    }
5066
5067    @Override
5068    public String[] getSystemSharedLibraryNames() {
5069        // allow instant applications
5070        synchronized (mPackages) {
5071            Set<String> libs = null;
5072            final int libCount = mSharedLibraries.size();
5073            for (int i = 0; i < libCount; i++) {
5074                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5075                if (versionedLib == null) {
5076                    continue;
5077                }
5078                final int versionCount = versionedLib.size();
5079                for (int j = 0; j < versionCount; j++) {
5080                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5081                    if (!libEntry.info.isStatic()) {
5082                        if (libs == null) {
5083                            libs = new ArraySet<>();
5084                        }
5085                        libs.add(libEntry.info.getName());
5086                        break;
5087                    }
5088                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5089                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5090                            UserHandle.getUserId(Binder.getCallingUid()),
5091                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5092                        if (libs == null) {
5093                            libs = new ArraySet<>();
5094                        }
5095                        libs.add(libEntry.info.getName());
5096                        break;
5097                    }
5098                }
5099            }
5100
5101            if (libs != null) {
5102                String[] libsArray = new String[libs.size()];
5103                libs.toArray(libsArray);
5104                return libsArray;
5105            }
5106
5107            return null;
5108        }
5109    }
5110
5111    @Override
5112    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5113        // allow instant applications
5114        synchronized (mPackages) {
5115            return mServicesSystemSharedLibraryPackageName;
5116        }
5117    }
5118
5119    @Override
5120    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5121        // allow instant applications
5122        synchronized (mPackages) {
5123            return mSharedSystemSharedLibraryPackageName;
5124        }
5125    }
5126
5127    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5128        for (int i = userList.length - 1; i >= 0; --i) {
5129            final int userId = userList[i];
5130            // don't add instant app to the list of updates
5131            if (pkgSetting.getInstantApp(userId)) {
5132                continue;
5133            }
5134            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5135            if (changedPackages == null) {
5136                changedPackages = new SparseArray<>();
5137                mChangedPackages.put(userId, changedPackages);
5138            }
5139            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5140            if (sequenceNumbers == null) {
5141                sequenceNumbers = new HashMap<>();
5142                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5143            }
5144            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5145            if (sequenceNumber != null) {
5146                changedPackages.remove(sequenceNumber);
5147            }
5148            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5149            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5150        }
5151        mChangedPackagesSequenceNumber++;
5152    }
5153
5154    @Override
5155    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5156        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5157            return null;
5158        }
5159        synchronized (mPackages) {
5160            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5161                return null;
5162            }
5163            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5164            if (changedPackages == null) {
5165                return null;
5166            }
5167            final List<String> packageNames =
5168                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5169            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5170                final String packageName = changedPackages.get(i);
5171                if (packageName != null) {
5172                    packageNames.add(packageName);
5173                }
5174            }
5175            return packageNames.isEmpty()
5176                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5177        }
5178    }
5179
5180    @Override
5181    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5182        // allow instant applications
5183        ArrayList<FeatureInfo> res;
5184        synchronized (mAvailableFeatures) {
5185            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5186            res.addAll(mAvailableFeatures.values());
5187        }
5188        final FeatureInfo fi = new FeatureInfo();
5189        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5190                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5191        res.add(fi);
5192
5193        return new ParceledListSlice<>(res);
5194    }
5195
5196    @Override
5197    public boolean hasSystemFeature(String name, int version) {
5198        // allow instant applications
5199        synchronized (mAvailableFeatures) {
5200            final FeatureInfo feat = mAvailableFeatures.get(name);
5201            if (feat == null) {
5202                return false;
5203            } else {
5204                return feat.version >= version;
5205            }
5206        }
5207    }
5208
5209    @Override
5210    public int checkPermission(String permName, String pkgName, int userId) {
5211        if (!sUserManager.exists(userId)) {
5212            return PackageManager.PERMISSION_DENIED;
5213        }
5214        final int callingUid = Binder.getCallingUid();
5215
5216        synchronized (mPackages) {
5217            final PackageParser.Package p = mPackages.get(pkgName);
5218            if (p != null && p.mExtras != null) {
5219                final PackageSetting ps = (PackageSetting) p.mExtras;
5220                if (filterAppAccessLPr(ps, callingUid, userId)) {
5221                    return PackageManager.PERMISSION_DENIED;
5222                }
5223                final boolean instantApp = ps.getInstantApp(userId);
5224                final PermissionsState permissionsState = ps.getPermissionsState();
5225                if (permissionsState.hasPermission(permName, userId)) {
5226                    if (instantApp) {
5227                        BasePermission bp = mSettings.mPermissions.get(permName);
5228                        if (bp != null && bp.isInstant()) {
5229                            return PackageManager.PERMISSION_GRANTED;
5230                        }
5231                    } else {
5232                        return PackageManager.PERMISSION_GRANTED;
5233                    }
5234                }
5235                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5236                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5237                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5238                    return PackageManager.PERMISSION_GRANTED;
5239                }
5240            }
5241        }
5242
5243        return PackageManager.PERMISSION_DENIED;
5244    }
5245
5246    @Override
5247    public int checkUidPermission(String permName, int uid) {
5248        final int callingUid = Binder.getCallingUid();
5249        final int callingUserId = UserHandle.getUserId(callingUid);
5250        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5251        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5252        final int userId = UserHandle.getUserId(uid);
5253        if (!sUserManager.exists(userId)) {
5254            return PackageManager.PERMISSION_DENIED;
5255        }
5256
5257        synchronized (mPackages) {
5258            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5259            if (obj != null) {
5260                if (obj instanceof SharedUserSetting) {
5261                    if (isCallerInstantApp) {
5262                        return PackageManager.PERMISSION_DENIED;
5263                    }
5264                } else if (obj instanceof PackageSetting) {
5265                    final PackageSetting ps = (PackageSetting) obj;
5266                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5267                        return PackageManager.PERMISSION_DENIED;
5268                    }
5269                }
5270                final SettingBase settingBase = (SettingBase) obj;
5271                final PermissionsState permissionsState = settingBase.getPermissionsState();
5272                if (permissionsState.hasPermission(permName, userId)) {
5273                    if (isUidInstantApp) {
5274                        BasePermission bp = mSettings.mPermissions.get(permName);
5275                        if (bp != null && bp.isInstant()) {
5276                            return PackageManager.PERMISSION_GRANTED;
5277                        }
5278                    } else {
5279                        return PackageManager.PERMISSION_GRANTED;
5280                    }
5281                }
5282                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5283                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5284                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5285                    return PackageManager.PERMISSION_GRANTED;
5286                }
5287            } else {
5288                ArraySet<String> perms = mSystemPermissions.get(uid);
5289                if (perms != null) {
5290                    if (perms.contains(permName)) {
5291                        return PackageManager.PERMISSION_GRANTED;
5292                    }
5293                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5294                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5295                        return PackageManager.PERMISSION_GRANTED;
5296                    }
5297                }
5298            }
5299        }
5300
5301        return PackageManager.PERMISSION_DENIED;
5302    }
5303
5304    @Override
5305    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5306        if (UserHandle.getCallingUserId() != userId) {
5307            mContext.enforceCallingPermission(
5308                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5309                    "isPermissionRevokedByPolicy for user " + userId);
5310        }
5311
5312        if (checkPermission(permission, packageName, userId)
5313                == PackageManager.PERMISSION_GRANTED) {
5314            return false;
5315        }
5316
5317        final int callingUid = Binder.getCallingUid();
5318        if (getInstantAppPackageName(callingUid) != null) {
5319            if (!isCallerSameApp(packageName, callingUid)) {
5320                return false;
5321            }
5322        } else {
5323            if (isInstantApp(packageName, userId)) {
5324                return false;
5325            }
5326        }
5327
5328        final long identity = Binder.clearCallingIdentity();
5329        try {
5330            final int flags = getPermissionFlags(permission, packageName, userId);
5331            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5332        } finally {
5333            Binder.restoreCallingIdentity(identity);
5334        }
5335    }
5336
5337    @Override
5338    public String getPermissionControllerPackageName() {
5339        synchronized (mPackages) {
5340            return mRequiredInstallerPackage;
5341        }
5342    }
5343
5344    /**
5345     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5346     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5347     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5348     * @param message the message to log on security exception
5349     */
5350    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5351            boolean checkShell, String message) {
5352        if (userId < 0) {
5353            throw new IllegalArgumentException("Invalid userId " + userId);
5354        }
5355        if (checkShell) {
5356            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5357        }
5358        if (userId == UserHandle.getUserId(callingUid)) return;
5359        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5360            if (requireFullPermission) {
5361                mContext.enforceCallingOrSelfPermission(
5362                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5363            } else {
5364                try {
5365                    mContext.enforceCallingOrSelfPermission(
5366                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5367                } catch (SecurityException se) {
5368                    mContext.enforceCallingOrSelfPermission(
5369                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5370                }
5371            }
5372        }
5373    }
5374
5375    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5376        if (callingUid == Process.SHELL_UID) {
5377            if (userHandle >= 0
5378                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5379                throw new SecurityException("Shell does not have permission to access user "
5380                        + userHandle);
5381            } else if (userHandle < 0) {
5382                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5383                        + Debug.getCallers(3));
5384            }
5385        }
5386    }
5387
5388    private BasePermission findPermissionTreeLP(String permName) {
5389        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5390            if (permName.startsWith(bp.name) &&
5391                    permName.length() > bp.name.length() &&
5392                    permName.charAt(bp.name.length()) == '.') {
5393                return bp;
5394            }
5395        }
5396        return null;
5397    }
5398
5399    private BasePermission checkPermissionTreeLP(String permName) {
5400        if (permName != null) {
5401            BasePermission bp = findPermissionTreeLP(permName);
5402            if (bp != null) {
5403                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5404                    return bp;
5405                }
5406                throw new SecurityException("Calling uid "
5407                        + Binder.getCallingUid()
5408                        + " is not allowed to add to permission tree "
5409                        + bp.name + " owned by uid " + bp.uid);
5410            }
5411        }
5412        throw new SecurityException("No permission tree found for " + permName);
5413    }
5414
5415    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5416        if (s1 == null) {
5417            return s2 == null;
5418        }
5419        if (s2 == null) {
5420            return false;
5421        }
5422        if (s1.getClass() != s2.getClass()) {
5423            return false;
5424        }
5425        return s1.equals(s2);
5426    }
5427
5428    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5429        if (pi1.icon != pi2.icon) return false;
5430        if (pi1.logo != pi2.logo) return false;
5431        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5432        if (!compareStrings(pi1.name, pi2.name)) return false;
5433        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5434        // We'll take care of setting this one.
5435        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5436        // These are not currently stored in settings.
5437        //if (!compareStrings(pi1.group, pi2.group)) return false;
5438        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5439        //if (pi1.labelRes != pi2.labelRes) return false;
5440        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5441        return true;
5442    }
5443
5444    int permissionInfoFootprint(PermissionInfo info) {
5445        int size = info.name.length();
5446        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5447        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5448        return size;
5449    }
5450
5451    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5452        int size = 0;
5453        for (BasePermission perm : mSettings.mPermissions.values()) {
5454            if (perm.uid == tree.uid) {
5455                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5456            }
5457        }
5458        return size;
5459    }
5460
5461    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5462        // We calculate the max size of permissions defined by this uid and throw
5463        // if that plus the size of 'info' would exceed our stated maximum.
5464        if (tree.uid != Process.SYSTEM_UID) {
5465            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5466            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5467                throw new SecurityException("Permission tree size cap exceeded");
5468            }
5469        }
5470    }
5471
5472    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5473        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5474            throw new SecurityException("Instant apps can't add permissions");
5475        }
5476        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5477            throw new SecurityException("Label must be specified in permission");
5478        }
5479        BasePermission tree = checkPermissionTreeLP(info.name);
5480        BasePermission bp = mSettings.mPermissions.get(info.name);
5481        boolean added = bp == null;
5482        boolean changed = true;
5483        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5484        if (added) {
5485            enforcePermissionCapLocked(info, tree);
5486            bp = new BasePermission(info.name, tree.sourcePackage,
5487                    BasePermission.TYPE_DYNAMIC);
5488        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5489            throw new SecurityException(
5490                    "Not allowed to modify non-dynamic permission "
5491                    + info.name);
5492        } else {
5493            if (bp.protectionLevel == fixedLevel
5494                    && bp.perm.owner.equals(tree.perm.owner)
5495                    && bp.uid == tree.uid
5496                    && comparePermissionInfos(bp.perm.info, info)) {
5497                changed = false;
5498            }
5499        }
5500        bp.protectionLevel = fixedLevel;
5501        info = new PermissionInfo(info);
5502        info.protectionLevel = fixedLevel;
5503        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5504        bp.perm.info.packageName = tree.perm.info.packageName;
5505        bp.uid = tree.uid;
5506        if (added) {
5507            mSettings.mPermissions.put(info.name, bp);
5508        }
5509        if (changed) {
5510            if (!async) {
5511                mSettings.writeLPr();
5512            } else {
5513                scheduleWriteSettingsLocked();
5514            }
5515        }
5516        return added;
5517    }
5518
5519    @Override
5520    public boolean addPermission(PermissionInfo info) {
5521        synchronized (mPackages) {
5522            return addPermissionLocked(info, false);
5523        }
5524    }
5525
5526    @Override
5527    public boolean addPermissionAsync(PermissionInfo info) {
5528        synchronized (mPackages) {
5529            return addPermissionLocked(info, true);
5530        }
5531    }
5532
5533    @Override
5534    public void removePermission(String name) {
5535        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5536            throw new SecurityException("Instant applications don't have access to this method");
5537        }
5538        synchronized (mPackages) {
5539            checkPermissionTreeLP(name);
5540            BasePermission bp = mSettings.mPermissions.get(name);
5541            if (bp != null) {
5542                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5543                    throw new SecurityException(
5544                            "Not allowed to modify non-dynamic permission "
5545                            + name);
5546                }
5547                mSettings.mPermissions.remove(name);
5548                mSettings.writeLPr();
5549            }
5550        }
5551    }
5552
5553    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5554            PackageParser.Package pkg, BasePermission bp) {
5555        int index = pkg.requestedPermissions.indexOf(bp.name);
5556        if (index == -1) {
5557            throw new SecurityException("Package " + pkg.packageName
5558                    + " has not requested permission " + bp.name);
5559        }
5560        if (!bp.isRuntime() && !bp.isDevelopment()) {
5561            throw new SecurityException("Permission " + bp.name
5562                    + " is not a changeable permission type");
5563        }
5564    }
5565
5566    @Override
5567    public void grantRuntimePermission(String packageName, String name, final int userId) {
5568        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5569    }
5570
5571    private void grantRuntimePermission(String packageName, String name, final int userId,
5572            boolean overridePolicy) {
5573        if (!sUserManager.exists(userId)) {
5574            Log.e(TAG, "No such user:" + userId);
5575            return;
5576        }
5577        final int callingUid = Binder.getCallingUid();
5578
5579        mContext.enforceCallingOrSelfPermission(
5580                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5581                "grantRuntimePermission");
5582
5583        enforceCrossUserPermission(callingUid, userId,
5584                true /* requireFullPermission */, true /* checkShell */,
5585                "grantRuntimePermission");
5586
5587        final int uid;
5588        final PackageSetting ps;
5589
5590        synchronized (mPackages) {
5591            final PackageParser.Package pkg = mPackages.get(packageName);
5592            if (pkg == null) {
5593                throw new IllegalArgumentException("Unknown package: " + packageName);
5594            }
5595            final BasePermission bp = mSettings.mPermissions.get(name);
5596            if (bp == null) {
5597                throw new IllegalArgumentException("Unknown permission: " + name);
5598            }
5599            ps = (PackageSetting) pkg.mExtras;
5600            if (ps == null
5601                    || filterAppAccessLPr(ps, callingUid, userId)) {
5602                throw new IllegalArgumentException("Unknown package: " + packageName);
5603            }
5604
5605            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5606
5607            // If a permission review is required for legacy apps we represent
5608            // their permissions as always granted runtime ones since we need
5609            // to keep the review required permission flag per user while an
5610            // install permission's state is shared across all users.
5611            if (mPermissionReviewRequired
5612                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5613                    && bp.isRuntime()) {
5614                return;
5615            }
5616
5617            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5618
5619            final PermissionsState permissionsState = ps.getPermissionsState();
5620
5621            final int flags = permissionsState.getPermissionFlags(name, userId);
5622            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5623                throw new SecurityException("Cannot grant system fixed permission "
5624                        + name + " for package " + packageName);
5625            }
5626            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5627                throw new SecurityException("Cannot grant policy fixed permission "
5628                        + name + " for package " + packageName);
5629            }
5630
5631            if (bp.isDevelopment()) {
5632                // Development permissions must be handled specially, since they are not
5633                // normal runtime permissions.  For now they apply to all users.
5634                if (permissionsState.grantInstallPermission(bp) !=
5635                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5636                    scheduleWriteSettingsLocked();
5637                }
5638                return;
5639            }
5640
5641            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5642                throw new SecurityException("Cannot grant non-ephemeral permission"
5643                        + name + " for package " + packageName);
5644            }
5645
5646            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5647                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5648                return;
5649            }
5650
5651            final int result = permissionsState.grantRuntimePermission(bp, userId);
5652            switch (result) {
5653                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5654                    return;
5655                }
5656
5657                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5658                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5659                    mHandler.post(new Runnable() {
5660                        @Override
5661                        public void run() {
5662                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5663                        }
5664                    });
5665                }
5666                break;
5667            }
5668
5669            if (bp.isRuntime()) {
5670                logPermissionGranted(mContext, name, packageName);
5671            }
5672
5673            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5674
5675            // Not critical if that is lost - app has to request again.
5676            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5677        }
5678
5679        // Only need to do this if user is initialized. Otherwise it's a new user
5680        // and there are no processes running as the user yet and there's no need
5681        // to make an expensive call to remount processes for the changed permissions.
5682        if (READ_EXTERNAL_STORAGE.equals(name)
5683                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5684            final long token = Binder.clearCallingIdentity();
5685            try {
5686                if (sUserManager.isInitialized(userId)) {
5687                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5688                            StorageManagerInternal.class);
5689                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5690                }
5691            } finally {
5692                Binder.restoreCallingIdentity(token);
5693            }
5694        }
5695    }
5696
5697    @Override
5698    public void revokeRuntimePermission(String packageName, String name, int userId) {
5699        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5700    }
5701
5702    private void revokeRuntimePermission(String packageName, String name, int userId,
5703            boolean overridePolicy) {
5704        if (!sUserManager.exists(userId)) {
5705            Log.e(TAG, "No such user:" + userId);
5706            return;
5707        }
5708
5709        mContext.enforceCallingOrSelfPermission(
5710                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5711                "revokeRuntimePermission");
5712
5713        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5714                true /* requireFullPermission */, true /* checkShell */,
5715                "revokeRuntimePermission");
5716
5717        final int appId;
5718
5719        synchronized (mPackages) {
5720            final PackageParser.Package pkg = mPackages.get(packageName);
5721            if (pkg == null) {
5722                throw new IllegalArgumentException("Unknown package: " + packageName);
5723            }
5724            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5725            if (ps == null
5726                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5727                throw new IllegalArgumentException("Unknown package: " + packageName);
5728            }
5729            final BasePermission bp = mSettings.mPermissions.get(name);
5730            if (bp == null) {
5731                throw new IllegalArgumentException("Unknown permission: " + name);
5732            }
5733
5734            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5735
5736            // If a permission review is required for legacy apps we represent
5737            // their permissions as always granted runtime ones since we need
5738            // to keep the review required permission flag per user while an
5739            // install permission's state is shared across all users.
5740            if (mPermissionReviewRequired
5741                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5742                    && bp.isRuntime()) {
5743                return;
5744            }
5745
5746            final PermissionsState permissionsState = ps.getPermissionsState();
5747
5748            final int flags = permissionsState.getPermissionFlags(name, userId);
5749            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5750                throw new SecurityException("Cannot revoke system fixed permission "
5751                        + name + " for package " + packageName);
5752            }
5753            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5754                throw new SecurityException("Cannot revoke policy fixed permission "
5755                        + name + " for package " + packageName);
5756            }
5757
5758            if (bp.isDevelopment()) {
5759                // Development permissions must be handled specially, since they are not
5760                // normal runtime permissions.  For now they apply to all users.
5761                if (permissionsState.revokeInstallPermission(bp) !=
5762                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5763                    scheduleWriteSettingsLocked();
5764                }
5765                return;
5766            }
5767
5768            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5769                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5770                return;
5771            }
5772
5773            if (bp.isRuntime()) {
5774                logPermissionRevoked(mContext, name, packageName);
5775            }
5776
5777            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5778
5779            // Critical, after this call app should never have the permission.
5780            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5781
5782            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5783        }
5784
5785        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5786    }
5787
5788    /**
5789     * Get the first event id for the permission.
5790     *
5791     * <p>There are four events for each permission: <ul>
5792     *     <li>Request permission: first id + 0</li>
5793     *     <li>Grant permission: first id + 1</li>
5794     *     <li>Request for permission denied: first id + 2</li>
5795     *     <li>Revoke permission: first id + 3</li>
5796     * </ul></p>
5797     *
5798     * @param name name of the permission
5799     *
5800     * @return The first event id for the permission
5801     */
5802    private static int getBaseEventId(@NonNull String name) {
5803        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5804
5805        if (eventIdIndex == -1) {
5806            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5807                    || Build.IS_USER) {
5808                Log.i(TAG, "Unknown permission " + name);
5809
5810                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5811            } else {
5812                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5813                //
5814                // Also update
5815                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5816                // - metrics_constants.proto
5817                throw new IllegalStateException("Unknown permission " + name);
5818            }
5819        }
5820
5821        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5822    }
5823
5824    /**
5825     * Log that a permission was revoked.
5826     *
5827     * @param context Context of the caller
5828     * @param name name of the permission
5829     * @param packageName package permission if for
5830     */
5831    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5832            @NonNull String packageName) {
5833        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5834    }
5835
5836    /**
5837     * Log that a permission request was granted.
5838     *
5839     * @param context Context of the caller
5840     * @param name name of the permission
5841     * @param packageName package permission if for
5842     */
5843    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5844            @NonNull String packageName) {
5845        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5846    }
5847
5848    @Override
5849    public void resetRuntimePermissions() {
5850        mContext.enforceCallingOrSelfPermission(
5851                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5852                "revokeRuntimePermission");
5853
5854        int callingUid = Binder.getCallingUid();
5855        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5856            mContext.enforceCallingOrSelfPermission(
5857                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5858                    "resetRuntimePermissions");
5859        }
5860
5861        synchronized (mPackages) {
5862            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5863            for (int userId : UserManagerService.getInstance().getUserIds()) {
5864                final int packageCount = mPackages.size();
5865                for (int i = 0; i < packageCount; i++) {
5866                    PackageParser.Package pkg = mPackages.valueAt(i);
5867                    if (!(pkg.mExtras instanceof PackageSetting)) {
5868                        continue;
5869                    }
5870                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5871                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5872                }
5873            }
5874        }
5875    }
5876
5877    @Override
5878    public int getPermissionFlags(String name, String packageName, int userId) {
5879        if (!sUserManager.exists(userId)) {
5880            return 0;
5881        }
5882
5883        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5884
5885        final int callingUid = Binder.getCallingUid();
5886        enforceCrossUserPermission(callingUid, userId,
5887                true /* requireFullPermission */, false /* checkShell */,
5888                "getPermissionFlags");
5889
5890        synchronized (mPackages) {
5891            final PackageParser.Package pkg = mPackages.get(packageName);
5892            if (pkg == null) {
5893                return 0;
5894            }
5895            final BasePermission bp = mSettings.mPermissions.get(name);
5896            if (bp == null) {
5897                return 0;
5898            }
5899            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5900            if (ps == null
5901                    || filterAppAccessLPr(ps, callingUid, userId)) {
5902                return 0;
5903            }
5904            PermissionsState permissionsState = ps.getPermissionsState();
5905            return permissionsState.getPermissionFlags(name, userId);
5906        }
5907    }
5908
5909    @Override
5910    public void updatePermissionFlags(String name, String packageName, int flagMask,
5911            int flagValues, int userId) {
5912        if (!sUserManager.exists(userId)) {
5913            return;
5914        }
5915
5916        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5917
5918        final int callingUid = Binder.getCallingUid();
5919        enforceCrossUserPermission(callingUid, userId,
5920                true /* requireFullPermission */, true /* checkShell */,
5921                "updatePermissionFlags");
5922
5923        // Only the system can change these flags and nothing else.
5924        if (getCallingUid() != Process.SYSTEM_UID) {
5925            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5926            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5927            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5928            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5929            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5930        }
5931
5932        synchronized (mPackages) {
5933            final PackageParser.Package pkg = mPackages.get(packageName);
5934            if (pkg == null) {
5935                throw new IllegalArgumentException("Unknown package: " + packageName);
5936            }
5937            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5938            if (ps == null
5939                    || filterAppAccessLPr(ps, callingUid, userId)) {
5940                throw new IllegalArgumentException("Unknown package: " + packageName);
5941            }
5942
5943            final BasePermission bp = mSettings.mPermissions.get(name);
5944            if (bp == null) {
5945                throw new IllegalArgumentException("Unknown permission: " + name);
5946            }
5947
5948            PermissionsState permissionsState = ps.getPermissionsState();
5949
5950            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5951
5952            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5953                // Install and runtime permissions are stored in different places,
5954                // so figure out what permission changed and persist the change.
5955                if (permissionsState.getInstallPermissionState(name) != null) {
5956                    scheduleWriteSettingsLocked();
5957                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5958                        || hadState) {
5959                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5960                }
5961            }
5962        }
5963    }
5964
5965    /**
5966     * Update the permission flags for all packages and runtime permissions of a user in order
5967     * to allow device or profile owner to remove POLICY_FIXED.
5968     */
5969    @Override
5970    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5971        if (!sUserManager.exists(userId)) {
5972            return;
5973        }
5974
5975        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5976
5977        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5978                true /* requireFullPermission */, true /* checkShell */,
5979                "updatePermissionFlagsForAllApps");
5980
5981        // Only the system can change system fixed flags.
5982        if (getCallingUid() != Process.SYSTEM_UID) {
5983            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5984            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5985        }
5986
5987        synchronized (mPackages) {
5988            boolean changed = false;
5989            final int packageCount = mPackages.size();
5990            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5991                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5992                final PackageSetting ps = (PackageSetting) pkg.mExtras;
5993                if (ps == null) {
5994                    continue;
5995                }
5996                PermissionsState permissionsState = ps.getPermissionsState();
5997                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5998                        userId, flagMask, flagValues);
5999            }
6000            if (changed) {
6001                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6002            }
6003        }
6004    }
6005
6006    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6007        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6008                != PackageManager.PERMISSION_GRANTED
6009            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6010                != PackageManager.PERMISSION_GRANTED) {
6011            throw new SecurityException(message + " requires "
6012                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6013                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6014        }
6015    }
6016
6017    @Override
6018    public boolean shouldShowRequestPermissionRationale(String permissionName,
6019            String packageName, int userId) {
6020        if (UserHandle.getCallingUserId() != userId) {
6021            mContext.enforceCallingPermission(
6022                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6023                    "canShowRequestPermissionRationale for user " + userId);
6024        }
6025
6026        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6027        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6028            return false;
6029        }
6030
6031        if (checkPermission(permissionName, packageName, userId)
6032                == PackageManager.PERMISSION_GRANTED) {
6033            return false;
6034        }
6035
6036        final int flags;
6037
6038        final long identity = Binder.clearCallingIdentity();
6039        try {
6040            flags = getPermissionFlags(permissionName,
6041                    packageName, userId);
6042        } finally {
6043            Binder.restoreCallingIdentity(identity);
6044        }
6045
6046        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6047                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6048                | PackageManager.FLAG_PERMISSION_USER_FIXED;
6049
6050        if ((flags & fixedFlags) != 0) {
6051            return false;
6052        }
6053
6054        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6055    }
6056
6057    @Override
6058    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6059        mContext.enforceCallingOrSelfPermission(
6060                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6061                "addOnPermissionsChangeListener");
6062
6063        synchronized (mPackages) {
6064            mOnPermissionChangeListeners.addListenerLocked(listener);
6065        }
6066    }
6067
6068    @Override
6069    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6070        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6071            throw new SecurityException("Instant applications don't have access to this method");
6072        }
6073        synchronized (mPackages) {
6074            mOnPermissionChangeListeners.removeListenerLocked(listener);
6075        }
6076    }
6077
6078    @Override
6079    public boolean isProtectedBroadcast(String actionName) {
6080        // allow instant applications
6081        synchronized (mProtectedBroadcasts) {
6082            if (mProtectedBroadcasts.contains(actionName)) {
6083                return true;
6084            } else if (actionName != null) {
6085                // TODO: remove these terrible hacks
6086                if (actionName.startsWith("android.net.netmon.lingerExpired")
6087                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6088                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6089                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6090                    return true;
6091                }
6092            }
6093        }
6094        return false;
6095    }
6096
6097    @Override
6098    public int checkSignatures(String pkg1, String pkg2) {
6099        synchronized (mPackages) {
6100            final PackageParser.Package p1 = mPackages.get(pkg1);
6101            final PackageParser.Package p2 = mPackages.get(pkg2);
6102            if (p1 == null || p1.mExtras == null
6103                    || p2 == null || p2.mExtras == null) {
6104                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6105            }
6106            final int callingUid = Binder.getCallingUid();
6107            final int callingUserId = UserHandle.getUserId(callingUid);
6108            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6109            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6110            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6111                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6112                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6113            }
6114            return compareSignatures(p1.mSignatures, p2.mSignatures);
6115        }
6116    }
6117
6118    @Override
6119    public int checkUidSignatures(int uid1, int uid2) {
6120        final int callingUid = Binder.getCallingUid();
6121        final int callingUserId = UserHandle.getUserId(callingUid);
6122        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6123        // Map to base uids.
6124        uid1 = UserHandle.getAppId(uid1);
6125        uid2 = UserHandle.getAppId(uid2);
6126        // reader
6127        synchronized (mPackages) {
6128            Signature[] s1;
6129            Signature[] s2;
6130            Object obj = mSettings.getUserIdLPr(uid1);
6131            if (obj != null) {
6132                if (obj instanceof SharedUserSetting) {
6133                    if (isCallerInstantApp) {
6134                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6135                    }
6136                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6137                } else if (obj instanceof PackageSetting) {
6138                    final PackageSetting ps = (PackageSetting) obj;
6139                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6140                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6141                    }
6142                    s1 = ps.signatures.mSignatures;
6143                } else {
6144                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6145                }
6146            } else {
6147                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6148            }
6149            obj = mSettings.getUserIdLPr(uid2);
6150            if (obj != null) {
6151                if (obj instanceof SharedUserSetting) {
6152                    if (isCallerInstantApp) {
6153                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6154                    }
6155                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6156                } else if (obj instanceof PackageSetting) {
6157                    final PackageSetting ps = (PackageSetting) obj;
6158                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6159                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6160                    }
6161                    s2 = ps.signatures.mSignatures;
6162                } else {
6163                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6164                }
6165            } else {
6166                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6167            }
6168            return compareSignatures(s1, s2);
6169        }
6170    }
6171
6172    /**
6173     * This method should typically only be used when granting or revoking
6174     * permissions, since the app may immediately restart after this call.
6175     * <p>
6176     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6177     * guard your work against the app being relaunched.
6178     */
6179    private void killUid(int appId, int userId, String reason) {
6180        final long identity = Binder.clearCallingIdentity();
6181        try {
6182            IActivityManager am = ActivityManager.getService();
6183            if (am != null) {
6184                try {
6185                    am.killUid(appId, userId, reason);
6186                } catch (RemoteException e) {
6187                    /* ignore - same process */
6188                }
6189            }
6190        } finally {
6191            Binder.restoreCallingIdentity(identity);
6192        }
6193    }
6194
6195    /**
6196     * Compares two sets of signatures. Returns:
6197     * <br />
6198     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6199     * <br />
6200     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6201     * <br />
6202     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6203     * <br />
6204     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6205     * <br />
6206     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6207     */
6208    static int compareSignatures(Signature[] s1, Signature[] s2) {
6209        if (s1 == null) {
6210            return s2 == null
6211                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
6212                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6213        }
6214
6215        if (s2 == null) {
6216            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6217        }
6218
6219        if (s1.length != s2.length) {
6220            return PackageManager.SIGNATURE_NO_MATCH;
6221        }
6222
6223        // Since both signature sets are of size 1, we can compare without HashSets.
6224        if (s1.length == 1) {
6225            return s1[0].equals(s2[0]) ?
6226                    PackageManager.SIGNATURE_MATCH :
6227                    PackageManager.SIGNATURE_NO_MATCH;
6228        }
6229
6230        ArraySet<Signature> set1 = new ArraySet<Signature>();
6231        for (Signature sig : s1) {
6232            set1.add(sig);
6233        }
6234        ArraySet<Signature> set2 = new ArraySet<Signature>();
6235        for (Signature sig : s2) {
6236            set2.add(sig);
6237        }
6238        // Make sure s2 contains all signatures in s1.
6239        if (set1.equals(set2)) {
6240            return PackageManager.SIGNATURE_MATCH;
6241        }
6242        return PackageManager.SIGNATURE_NO_MATCH;
6243    }
6244
6245    /**
6246     * If the database version for this type of package (internal storage or
6247     * external storage) is less than the version where package signatures
6248     * were updated, return true.
6249     */
6250    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6251        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6252        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6253    }
6254
6255    /**
6256     * Used for backward compatibility to make sure any packages with
6257     * certificate chains get upgraded to the new style. {@code existingSigs}
6258     * will be in the old format (since they were stored on disk from before the
6259     * system upgrade) and {@code scannedSigs} will be in the newer format.
6260     */
6261    private int compareSignaturesCompat(PackageSignatures existingSigs,
6262            PackageParser.Package scannedPkg) {
6263        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6264            return PackageManager.SIGNATURE_NO_MATCH;
6265        }
6266
6267        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6268        for (Signature sig : existingSigs.mSignatures) {
6269            existingSet.add(sig);
6270        }
6271        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6272        for (Signature sig : scannedPkg.mSignatures) {
6273            try {
6274                Signature[] chainSignatures = sig.getChainSignatures();
6275                for (Signature chainSig : chainSignatures) {
6276                    scannedCompatSet.add(chainSig);
6277                }
6278            } catch (CertificateEncodingException e) {
6279                scannedCompatSet.add(sig);
6280            }
6281        }
6282        /*
6283         * Make sure the expanded scanned set contains all signatures in the
6284         * existing one.
6285         */
6286        if (scannedCompatSet.equals(existingSet)) {
6287            // Migrate the old signatures to the new scheme.
6288            existingSigs.assignSignatures(scannedPkg.mSignatures);
6289            // The new KeySets will be re-added later in the scanning process.
6290            synchronized (mPackages) {
6291                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6292            }
6293            return PackageManager.SIGNATURE_MATCH;
6294        }
6295        return PackageManager.SIGNATURE_NO_MATCH;
6296    }
6297
6298    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6299        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6300        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6301    }
6302
6303    private int compareSignaturesRecover(PackageSignatures existingSigs,
6304            PackageParser.Package scannedPkg) {
6305        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6306            return PackageManager.SIGNATURE_NO_MATCH;
6307        }
6308
6309        String msg = null;
6310        try {
6311            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6312                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6313                        + scannedPkg.packageName);
6314                return PackageManager.SIGNATURE_MATCH;
6315            }
6316        } catch (CertificateException e) {
6317            msg = e.getMessage();
6318        }
6319
6320        logCriticalInfo(Log.INFO,
6321                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6322        return PackageManager.SIGNATURE_NO_MATCH;
6323    }
6324
6325    @Override
6326    public List<String> getAllPackages() {
6327        final int callingUid = Binder.getCallingUid();
6328        final int callingUserId = UserHandle.getUserId(callingUid);
6329        synchronized (mPackages) {
6330            if (canViewInstantApps(callingUid, callingUserId)) {
6331                return new ArrayList<String>(mPackages.keySet());
6332            }
6333            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6334            final List<String> result = new ArrayList<>();
6335            if (instantAppPkgName != null) {
6336                // caller is an instant application; filter unexposed applications
6337                for (PackageParser.Package pkg : mPackages.values()) {
6338                    if (!pkg.visibleToInstantApps) {
6339                        continue;
6340                    }
6341                    result.add(pkg.packageName);
6342                }
6343            } else {
6344                // caller is a normal application; filter instant applications
6345                for (PackageParser.Package pkg : mPackages.values()) {
6346                    final PackageSetting ps =
6347                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6348                    if (ps != null
6349                            && ps.getInstantApp(callingUserId)
6350                            && !mInstantAppRegistry.isInstantAccessGranted(
6351                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6352                        continue;
6353                    }
6354                    result.add(pkg.packageName);
6355                }
6356            }
6357            return result;
6358        }
6359    }
6360
6361    @Override
6362    public String[] getPackagesForUid(int uid) {
6363        final int callingUid = Binder.getCallingUid();
6364        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6365        final int userId = UserHandle.getUserId(uid);
6366        uid = UserHandle.getAppId(uid);
6367        // reader
6368        synchronized (mPackages) {
6369            Object obj = mSettings.getUserIdLPr(uid);
6370            if (obj instanceof SharedUserSetting) {
6371                if (isCallerInstantApp) {
6372                    return null;
6373                }
6374                final SharedUserSetting sus = (SharedUserSetting) obj;
6375                final int N = sus.packages.size();
6376                String[] res = new String[N];
6377                final Iterator<PackageSetting> it = sus.packages.iterator();
6378                int i = 0;
6379                while (it.hasNext()) {
6380                    PackageSetting ps = it.next();
6381                    if (ps.getInstalled(userId)) {
6382                        res[i++] = ps.name;
6383                    } else {
6384                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6385                    }
6386                }
6387                return res;
6388            } else if (obj instanceof PackageSetting) {
6389                final PackageSetting ps = (PackageSetting) obj;
6390                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6391                    return new String[]{ps.name};
6392                }
6393            }
6394        }
6395        return null;
6396    }
6397
6398    @Override
6399    public String getNameForUid(int uid) {
6400        final int callingUid = Binder.getCallingUid();
6401        if (getInstantAppPackageName(callingUid) != null) {
6402            return null;
6403        }
6404        synchronized (mPackages) {
6405            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6406            if (obj instanceof SharedUserSetting) {
6407                final SharedUserSetting sus = (SharedUserSetting) obj;
6408                return sus.name + ":" + sus.userId;
6409            } else if (obj instanceof PackageSetting) {
6410                final PackageSetting ps = (PackageSetting) obj;
6411                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6412                    return null;
6413                }
6414                return ps.name;
6415            }
6416        }
6417        return null;
6418    }
6419
6420    @Override
6421    public int getUidForSharedUser(String sharedUserName) {
6422        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6423            return -1;
6424        }
6425        if (sharedUserName == null) {
6426            return -1;
6427        }
6428        // reader
6429        synchronized (mPackages) {
6430            SharedUserSetting suid;
6431            try {
6432                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6433                if (suid != null) {
6434                    return suid.userId;
6435                }
6436            } catch (PackageManagerException ignore) {
6437                // can't happen, but, still need to catch it
6438            }
6439            return -1;
6440        }
6441    }
6442
6443    @Override
6444    public int getFlagsForUid(int uid) {
6445        final int callingUid = Binder.getCallingUid();
6446        if (getInstantAppPackageName(callingUid) != null) {
6447            return 0;
6448        }
6449        synchronized (mPackages) {
6450            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6451            if (obj instanceof SharedUserSetting) {
6452                final SharedUserSetting sus = (SharedUserSetting) obj;
6453                return sus.pkgFlags;
6454            } else if (obj instanceof PackageSetting) {
6455                final PackageSetting ps = (PackageSetting) obj;
6456                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6457                    return 0;
6458                }
6459                return ps.pkgFlags;
6460            }
6461        }
6462        return 0;
6463    }
6464
6465    @Override
6466    public int getPrivateFlagsForUid(int uid) {
6467        final int callingUid = Binder.getCallingUid();
6468        if (getInstantAppPackageName(callingUid) != null) {
6469            return 0;
6470        }
6471        synchronized (mPackages) {
6472            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6473            if (obj instanceof SharedUserSetting) {
6474                final SharedUserSetting sus = (SharedUserSetting) obj;
6475                return sus.pkgPrivateFlags;
6476            } else if (obj instanceof PackageSetting) {
6477                final PackageSetting ps = (PackageSetting) obj;
6478                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6479                    return 0;
6480                }
6481                return ps.pkgPrivateFlags;
6482            }
6483        }
6484        return 0;
6485    }
6486
6487    @Override
6488    public boolean isUidPrivileged(int uid) {
6489        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6490            return false;
6491        }
6492        uid = UserHandle.getAppId(uid);
6493        // reader
6494        synchronized (mPackages) {
6495            Object obj = mSettings.getUserIdLPr(uid);
6496            if (obj instanceof SharedUserSetting) {
6497                final SharedUserSetting sus = (SharedUserSetting) obj;
6498                final Iterator<PackageSetting> it = sus.packages.iterator();
6499                while (it.hasNext()) {
6500                    if (it.next().isPrivileged()) {
6501                        return true;
6502                    }
6503                }
6504            } else if (obj instanceof PackageSetting) {
6505                final PackageSetting ps = (PackageSetting) obj;
6506                return ps.isPrivileged();
6507            }
6508        }
6509        return false;
6510    }
6511
6512    @Override
6513    public String[] getAppOpPermissionPackages(String permissionName) {
6514        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6515            return null;
6516        }
6517        synchronized (mPackages) {
6518            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6519            if (pkgs == null) {
6520                return null;
6521            }
6522            return pkgs.toArray(new String[pkgs.size()]);
6523        }
6524    }
6525
6526    @Override
6527    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6528            int flags, int userId) {
6529        return resolveIntentInternal(
6530                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6531    }
6532
6533    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6534            int flags, int userId, boolean resolveForStart) {
6535        try {
6536            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6537
6538            if (!sUserManager.exists(userId)) return null;
6539            final int callingUid = Binder.getCallingUid();
6540            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6541            enforceCrossUserPermission(callingUid, userId,
6542                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6543
6544            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6545            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6546                    flags, callingUid, userId, resolveForStart);
6547            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6548
6549            final ResolveInfo bestChoice =
6550                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6551            return bestChoice;
6552        } finally {
6553            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6554        }
6555    }
6556
6557    @Override
6558    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6559        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6560            throw new SecurityException(
6561                    "findPersistentPreferredActivity can only be run by the system");
6562        }
6563        if (!sUserManager.exists(userId)) {
6564            return null;
6565        }
6566        final int callingUid = Binder.getCallingUid();
6567        intent = updateIntentForResolve(intent);
6568        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6569        final int flags = updateFlagsForResolve(
6570                0, userId, intent, callingUid, false /*includeInstantApps*/);
6571        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6572                userId);
6573        synchronized (mPackages) {
6574            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6575                    userId);
6576        }
6577    }
6578
6579    @Override
6580    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6581            IntentFilter filter, int match, ComponentName activity) {
6582        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6583            return;
6584        }
6585        final int userId = UserHandle.getCallingUserId();
6586        if (DEBUG_PREFERRED) {
6587            Log.v(TAG, "setLastChosenActivity intent=" + intent
6588                + " resolvedType=" + resolvedType
6589                + " flags=" + flags
6590                + " filter=" + filter
6591                + " match=" + match
6592                + " activity=" + activity);
6593            filter.dump(new PrintStreamPrinter(System.out), "    ");
6594        }
6595        intent.setComponent(null);
6596        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6597                userId);
6598        // Find any earlier preferred or last chosen entries and nuke them
6599        findPreferredActivity(intent, resolvedType,
6600                flags, query, 0, false, true, false, userId);
6601        // Add the new activity as the last chosen for this filter
6602        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6603                "Setting last chosen");
6604    }
6605
6606    @Override
6607    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6608        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6609            return null;
6610        }
6611        final int userId = UserHandle.getCallingUserId();
6612        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6613        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6614                userId);
6615        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6616                false, false, false, userId);
6617    }
6618
6619    /**
6620     * Returns whether or not instant apps have been disabled remotely.
6621     */
6622    private boolean isEphemeralDisabled() {
6623        return mEphemeralAppsDisabled;
6624    }
6625
6626    private boolean isInstantAppAllowed(
6627            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6628            boolean skipPackageCheck) {
6629        if (mInstantAppResolverConnection == null) {
6630            return false;
6631        }
6632        if (mInstantAppInstallerActivity == null) {
6633            return false;
6634        }
6635        if (intent.getComponent() != null) {
6636            return false;
6637        }
6638        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6639            return false;
6640        }
6641        if (!skipPackageCheck && intent.getPackage() != null) {
6642            return false;
6643        }
6644        final boolean isWebUri = hasWebURI(intent);
6645        if (!isWebUri || intent.getData().getHost() == null) {
6646            return false;
6647        }
6648        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6649        // Or if there's already an ephemeral app installed that handles the action
6650        synchronized (mPackages) {
6651            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6652            for (int n = 0; n < count; n++) {
6653                final ResolveInfo info = resolvedActivities.get(n);
6654                final String packageName = info.activityInfo.packageName;
6655                final PackageSetting ps = mSettings.mPackages.get(packageName);
6656                if (ps != null) {
6657                    // only check domain verification status if the app is not a browser
6658                    if (!info.handleAllWebDataURI) {
6659                        // Try to get the status from User settings first
6660                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6661                        final int status = (int) (packedStatus >> 32);
6662                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6663                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6664                            if (DEBUG_EPHEMERAL) {
6665                                Slog.v(TAG, "DENY instant app;"
6666                                    + " pkg: " + packageName + ", status: " + status);
6667                            }
6668                            return false;
6669                        }
6670                    }
6671                    if (ps.getInstantApp(userId)) {
6672                        if (DEBUG_EPHEMERAL) {
6673                            Slog.v(TAG, "DENY instant app installed;"
6674                                    + " pkg: " + packageName);
6675                        }
6676                        return false;
6677                    }
6678                }
6679            }
6680        }
6681        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6682        return true;
6683    }
6684
6685    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6686            Intent origIntent, String resolvedType, String callingPackage,
6687            Bundle verificationBundle, int userId) {
6688        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6689                new InstantAppRequest(responseObj, origIntent, resolvedType,
6690                        callingPackage, userId, verificationBundle));
6691        mHandler.sendMessage(msg);
6692    }
6693
6694    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6695            int flags, List<ResolveInfo> query, int userId) {
6696        if (query != null) {
6697            final int N = query.size();
6698            if (N == 1) {
6699                return query.get(0);
6700            } else if (N > 1) {
6701                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6702                // If there is more than one activity with the same priority,
6703                // then let the user decide between them.
6704                ResolveInfo r0 = query.get(0);
6705                ResolveInfo r1 = query.get(1);
6706                if (DEBUG_INTENT_MATCHING || debug) {
6707                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6708                            + r1.activityInfo.name + "=" + r1.priority);
6709                }
6710                // If the first activity has a higher priority, or a different
6711                // default, then it is always desirable to pick it.
6712                if (r0.priority != r1.priority
6713                        || r0.preferredOrder != r1.preferredOrder
6714                        || r0.isDefault != r1.isDefault) {
6715                    return query.get(0);
6716                }
6717                // If we have saved a preference for a preferred activity for
6718                // this Intent, use that.
6719                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6720                        flags, query, r0.priority, true, false, debug, userId);
6721                if (ri != null) {
6722                    return ri;
6723                }
6724                // If we have an ephemeral app, use it
6725                for (int i = 0; i < N; i++) {
6726                    ri = query.get(i);
6727                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6728                        final String packageName = ri.activityInfo.packageName;
6729                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6730                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6731                        final int status = (int)(packedStatus >> 32);
6732                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6733                            return ri;
6734                        }
6735                    }
6736                }
6737                ri = new ResolveInfo(mResolveInfo);
6738                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6739                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6740                // If all of the options come from the same package, show the application's
6741                // label and icon instead of the generic resolver's.
6742                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6743                // and then throw away the ResolveInfo itself, meaning that the caller loses
6744                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6745                // a fallback for this case; we only set the target package's resources on
6746                // the ResolveInfo, not the ActivityInfo.
6747                final String intentPackage = intent.getPackage();
6748                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6749                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6750                    ri.resolvePackageName = intentPackage;
6751                    if (userNeedsBadging(userId)) {
6752                        ri.noResourceId = true;
6753                    } else {
6754                        ri.icon = appi.icon;
6755                    }
6756                    ri.iconResourceId = appi.icon;
6757                    ri.labelRes = appi.labelRes;
6758                }
6759                ri.activityInfo.applicationInfo = new ApplicationInfo(
6760                        ri.activityInfo.applicationInfo);
6761                if (userId != 0) {
6762                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6763                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6764                }
6765                // Make sure that the resolver is displayable in car mode
6766                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6767                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6768                return ri;
6769            }
6770        }
6771        return null;
6772    }
6773
6774    /**
6775     * Return true if the given list is not empty and all of its contents have
6776     * an activityInfo with the given package name.
6777     */
6778    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6779        if (ArrayUtils.isEmpty(list)) {
6780            return false;
6781        }
6782        for (int i = 0, N = list.size(); i < N; i++) {
6783            final ResolveInfo ri = list.get(i);
6784            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6785            if (ai == null || !packageName.equals(ai.packageName)) {
6786                return false;
6787            }
6788        }
6789        return true;
6790    }
6791
6792    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6793            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6794        final int N = query.size();
6795        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6796                .get(userId);
6797        // Get the list of persistent preferred activities that handle the intent
6798        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6799        List<PersistentPreferredActivity> pprefs = ppir != null
6800                ? ppir.queryIntent(intent, resolvedType,
6801                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6802                        userId)
6803                : null;
6804        if (pprefs != null && pprefs.size() > 0) {
6805            final int M = pprefs.size();
6806            for (int i=0; i<M; i++) {
6807                final PersistentPreferredActivity ppa = pprefs.get(i);
6808                if (DEBUG_PREFERRED || debug) {
6809                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6810                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6811                            + "\n  component=" + ppa.mComponent);
6812                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6813                }
6814                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6815                        flags | MATCH_DISABLED_COMPONENTS, userId);
6816                if (DEBUG_PREFERRED || debug) {
6817                    Slog.v(TAG, "Found persistent preferred activity:");
6818                    if (ai != null) {
6819                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6820                    } else {
6821                        Slog.v(TAG, "  null");
6822                    }
6823                }
6824                if (ai == null) {
6825                    // This previously registered persistent preferred activity
6826                    // component is no longer known. Ignore it and do NOT remove it.
6827                    continue;
6828                }
6829                for (int j=0; j<N; j++) {
6830                    final ResolveInfo ri = query.get(j);
6831                    if (!ri.activityInfo.applicationInfo.packageName
6832                            .equals(ai.applicationInfo.packageName)) {
6833                        continue;
6834                    }
6835                    if (!ri.activityInfo.name.equals(ai.name)) {
6836                        continue;
6837                    }
6838                    //  Found a persistent preference that can handle the intent.
6839                    if (DEBUG_PREFERRED || debug) {
6840                        Slog.v(TAG, "Returning persistent preferred activity: " +
6841                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6842                    }
6843                    return ri;
6844                }
6845            }
6846        }
6847        return null;
6848    }
6849
6850    // TODO: handle preferred activities missing while user has amnesia
6851    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6852            List<ResolveInfo> query, int priority, boolean always,
6853            boolean removeMatches, boolean debug, int userId) {
6854        if (!sUserManager.exists(userId)) return null;
6855        final int callingUid = Binder.getCallingUid();
6856        flags = updateFlagsForResolve(
6857                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6858        intent = updateIntentForResolve(intent);
6859        // writer
6860        synchronized (mPackages) {
6861            // Try to find a matching persistent preferred activity.
6862            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6863                    debug, userId);
6864
6865            // If a persistent preferred activity matched, use it.
6866            if (pri != null) {
6867                return pri;
6868            }
6869
6870            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6871            // Get the list of preferred activities that handle the intent
6872            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6873            List<PreferredActivity> prefs = pir != null
6874                    ? pir.queryIntent(intent, resolvedType,
6875                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6876                            userId)
6877                    : null;
6878            if (prefs != null && prefs.size() > 0) {
6879                boolean changed = false;
6880                try {
6881                    // First figure out how good the original match set is.
6882                    // We will only allow preferred activities that came
6883                    // from the same match quality.
6884                    int match = 0;
6885
6886                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6887
6888                    final int N = query.size();
6889                    for (int j=0; j<N; j++) {
6890                        final ResolveInfo ri = query.get(j);
6891                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6892                                + ": 0x" + Integer.toHexString(match));
6893                        if (ri.match > match) {
6894                            match = ri.match;
6895                        }
6896                    }
6897
6898                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6899                            + Integer.toHexString(match));
6900
6901                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6902                    final int M = prefs.size();
6903                    for (int i=0; i<M; i++) {
6904                        final PreferredActivity pa = prefs.get(i);
6905                        if (DEBUG_PREFERRED || debug) {
6906                            Slog.v(TAG, "Checking PreferredActivity ds="
6907                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6908                                    + "\n  component=" + pa.mPref.mComponent);
6909                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6910                        }
6911                        if (pa.mPref.mMatch != match) {
6912                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6913                                    + Integer.toHexString(pa.mPref.mMatch));
6914                            continue;
6915                        }
6916                        // If it's not an "always" type preferred activity and that's what we're
6917                        // looking for, skip it.
6918                        if (always && !pa.mPref.mAlways) {
6919                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6920                            continue;
6921                        }
6922                        final ActivityInfo ai = getActivityInfo(
6923                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6924                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6925                                userId);
6926                        if (DEBUG_PREFERRED || debug) {
6927                            Slog.v(TAG, "Found preferred activity:");
6928                            if (ai != null) {
6929                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6930                            } else {
6931                                Slog.v(TAG, "  null");
6932                            }
6933                        }
6934                        if (ai == null) {
6935                            // This previously registered preferred activity
6936                            // component is no longer known.  Most likely an update
6937                            // to the app was installed and in the new version this
6938                            // component no longer exists.  Clean it up by removing
6939                            // it from the preferred activities list, and skip it.
6940                            Slog.w(TAG, "Removing dangling preferred activity: "
6941                                    + pa.mPref.mComponent);
6942                            pir.removeFilter(pa);
6943                            changed = true;
6944                            continue;
6945                        }
6946                        for (int j=0; j<N; j++) {
6947                            final ResolveInfo ri = query.get(j);
6948                            if (!ri.activityInfo.applicationInfo.packageName
6949                                    .equals(ai.applicationInfo.packageName)) {
6950                                continue;
6951                            }
6952                            if (!ri.activityInfo.name.equals(ai.name)) {
6953                                continue;
6954                            }
6955
6956                            if (removeMatches) {
6957                                pir.removeFilter(pa);
6958                                changed = true;
6959                                if (DEBUG_PREFERRED) {
6960                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6961                                }
6962                                break;
6963                            }
6964
6965                            // Okay we found a previously set preferred or last chosen app.
6966                            // If the result set is different from when this
6967                            // was created, and is not a subset of the preferred set, we need to
6968                            // clear it and re-ask the user their preference, if we're looking for
6969                            // an "always" type entry.
6970                            if (always && !pa.mPref.sameSet(query)) {
6971                                if (pa.mPref.isSuperset(query)) {
6972                                    // some components of the set are no longer present in
6973                                    // the query, but the preferred activity can still be reused
6974                                    if (DEBUG_PREFERRED) {
6975                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6976                                                + " still valid as only non-preferred components"
6977                                                + " were removed for " + intent + " type "
6978                                                + resolvedType);
6979                                    }
6980                                    // remove obsolete components and re-add the up-to-date filter
6981                                    PreferredActivity freshPa = new PreferredActivity(pa,
6982                                            pa.mPref.mMatch,
6983                                            pa.mPref.discardObsoleteComponents(query),
6984                                            pa.mPref.mComponent,
6985                                            pa.mPref.mAlways);
6986                                    pir.removeFilter(pa);
6987                                    pir.addFilter(freshPa);
6988                                    changed = true;
6989                                } else {
6990                                    Slog.i(TAG,
6991                                            "Result set changed, dropping preferred activity for "
6992                                                    + intent + " type " + resolvedType);
6993                                    if (DEBUG_PREFERRED) {
6994                                        Slog.v(TAG, "Removing preferred activity since set changed "
6995                                                + pa.mPref.mComponent);
6996                                    }
6997                                    pir.removeFilter(pa);
6998                                    // Re-add the filter as a "last chosen" entry (!always)
6999                                    PreferredActivity lastChosen = new PreferredActivity(
7000                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7001                                    pir.addFilter(lastChosen);
7002                                    changed = true;
7003                                    return null;
7004                                }
7005                            }
7006
7007                            // Yay! Either the set matched or we're looking for the last chosen
7008                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7009                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7010                            return ri;
7011                        }
7012                    }
7013                } finally {
7014                    if (changed) {
7015                        if (DEBUG_PREFERRED) {
7016                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7017                        }
7018                        scheduleWritePackageRestrictionsLocked(userId);
7019                    }
7020                }
7021            }
7022        }
7023        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7024        return null;
7025    }
7026
7027    /*
7028     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7029     */
7030    @Override
7031    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7032            int targetUserId) {
7033        mContext.enforceCallingOrSelfPermission(
7034                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7035        List<CrossProfileIntentFilter> matches =
7036                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7037        if (matches != null) {
7038            int size = matches.size();
7039            for (int i = 0; i < size; i++) {
7040                if (matches.get(i).getTargetUserId() == targetUserId) return true;
7041            }
7042        }
7043        if (hasWebURI(intent)) {
7044            // cross-profile app linking works only towards the parent.
7045            final int callingUid = Binder.getCallingUid();
7046            final UserInfo parent = getProfileParent(sourceUserId);
7047            synchronized(mPackages) {
7048                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7049                        false /*includeInstantApps*/);
7050                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7051                        intent, resolvedType, flags, sourceUserId, parent.id);
7052                return xpDomainInfo != null;
7053            }
7054        }
7055        return false;
7056    }
7057
7058    private UserInfo getProfileParent(int userId) {
7059        final long identity = Binder.clearCallingIdentity();
7060        try {
7061            return sUserManager.getProfileParent(userId);
7062        } finally {
7063            Binder.restoreCallingIdentity(identity);
7064        }
7065    }
7066
7067    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7068            String resolvedType, int userId) {
7069        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7070        if (resolver != null) {
7071            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7072        }
7073        return null;
7074    }
7075
7076    @Override
7077    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7078            String resolvedType, int flags, int userId) {
7079        try {
7080            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7081
7082            return new ParceledListSlice<>(
7083                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7084        } finally {
7085            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7086        }
7087    }
7088
7089    /**
7090     * Returns the package name of the calling Uid if it's an instant app. If it isn't
7091     * instant, returns {@code null}.
7092     */
7093    private String getInstantAppPackageName(int callingUid) {
7094        synchronized (mPackages) {
7095            // If the caller is an isolated app use the owner's uid for the lookup.
7096            if (Process.isIsolated(callingUid)) {
7097                callingUid = mIsolatedOwners.get(callingUid);
7098            }
7099            final int appId = UserHandle.getAppId(callingUid);
7100            final Object obj = mSettings.getUserIdLPr(appId);
7101            if (obj instanceof PackageSetting) {
7102                final PackageSetting ps = (PackageSetting) obj;
7103                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7104                return isInstantApp ? ps.pkg.packageName : null;
7105            }
7106        }
7107        return null;
7108    }
7109
7110    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7111            String resolvedType, int flags, int userId) {
7112        return queryIntentActivitiesInternal(
7113                intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
7114    }
7115
7116    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7117            String resolvedType, int flags, int filterCallingUid, int userId,
7118            boolean resolveForStart) {
7119        if (!sUserManager.exists(userId)) return Collections.emptyList();
7120        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7121        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7122                false /* requireFullPermission */, false /* checkShell */,
7123                "query intent activities");
7124        final String pkgName = intent.getPackage();
7125        ComponentName comp = intent.getComponent();
7126        if (comp == null) {
7127            if (intent.getSelector() != null) {
7128                intent = intent.getSelector();
7129                comp = intent.getComponent();
7130            }
7131        }
7132
7133        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7134                comp != null || pkgName != null /*onlyExposedExplicitly*/);
7135        if (comp != null) {
7136            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7137            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7138            if (ai != null) {
7139                // When specifying an explicit component, we prevent the activity from being
7140                // used when either 1) the calling package is normal and the activity is within
7141                // an ephemeral application or 2) the calling package is ephemeral and the
7142                // activity is not visible to ephemeral applications.
7143                final boolean matchInstantApp =
7144                        (flags & PackageManager.MATCH_INSTANT) != 0;
7145                final boolean matchVisibleToInstantAppOnly =
7146                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7147                final boolean matchExplicitlyVisibleOnly =
7148                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7149                final boolean isCallerInstantApp =
7150                        instantAppPkgName != null;
7151                final boolean isTargetSameInstantApp =
7152                        comp.getPackageName().equals(instantAppPkgName);
7153                final boolean isTargetInstantApp =
7154                        (ai.applicationInfo.privateFlags
7155                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7156                final boolean isTargetVisibleToInstantApp =
7157                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7158                final boolean isTargetExplicitlyVisibleToInstantApp =
7159                        isTargetVisibleToInstantApp
7160                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7161                final boolean isTargetHiddenFromInstantApp =
7162                        !isTargetVisibleToInstantApp
7163                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7164                final boolean blockResolution =
7165                        !isTargetSameInstantApp
7166                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7167                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7168                                        && isTargetHiddenFromInstantApp));
7169                if (!blockResolution) {
7170                    final ResolveInfo ri = new ResolveInfo();
7171                    ri.activityInfo = ai;
7172                    list.add(ri);
7173                }
7174            }
7175            return applyPostResolutionFilter(list, instantAppPkgName);
7176        }
7177
7178        // reader
7179        boolean sortResult = false;
7180        boolean addEphemeral = false;
7181        List<ResolveInfo> result;
7182        final boolean ephemeralDisabled = isEphemeralDisabled();
7183        synchronized (mPackages) {
7184            if (pkgName == null) {
7185                List<CrossProfileIntentFilter> matchingFilters =
7186                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7187                // Check for results that need to skip the current profile.
7188                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7189                        resolvedType, flags, userId);
7190                if (xpResolveInfo != null) {
7191                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7192                    xpResult.add(xpResolveInfo);
7193                    return applyPostResolutionFilter(
7194                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
7195                }
7196
7197                // Check for results in the current profile.
7198                result = filterIfNotSystemUser(mActivities.queryIntent(
7199                        intent, resolvedType, flags, userId), userId);
7200                addEphemeral = !ephemeralDisabled
7201                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7202                // Check for cross profile results.
7203                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7204                xpResolveInfo = queryCrossProfileIntents(
7205                        matchingFilters, intent, resolvedType, flags, userId,
7206                        hasNonNegativePriorityResult);
7207                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7208                    boolean isVisibleToUser = filterIfNotSystemUser(
7209                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
7210                    if (isVisibleToUser) {
7211                        result.add(xpResolveInfo);
7212                        sortResult = true;
7213                    }
7214                }
7215                if (hasWebURI(intent)) {
7216                    CrossProfileDomainInfo xpDomainInfo = null;
7217                    final UserInfo parent = getProfileParent(userId);
7218                    if (parent != null) {
7219                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7220                                flags, userId, parent.id);
7221                    }
7222                    if (xpDomainInfo != null) {
7223                        if (xpResolveInfo != null) {
7224                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
7225                            // in the result.
7226                            result.remove(xpResolveInfo);
7227                        }
7228                        if (result.size() == 0 && !addEphemeral) {
7229                            // No result in current profile, but found candidate in parent user.
7230                            // And we are not going to add emphemeral app, so we can return the
7231                            // result straight away.
7232                            result.add(xpDomainInfo.resolveInfo);
7233                            return applyPostResolutionFilter(result, instantAppPkgName);
7234                        }
7235                    } else if (result.size() <= 1 && !addEphemeral) {
7236                        // No result in parent user and <= 1 result in current profile, and we
7237                        // are not going to add emphemeral app, so we can return the result without
7238                        // further processing.
7239                        return applyPostResolutionFilter(result, instantAppPkgName);
7240                    }
7241                    // We have more than one candidate (combining results from current and parent
7242                    // profile), so we need filtering and sorting.
7243                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7244                            intent, flags, result, xpDomainInfo, userId);
7245                    sortResult = true;
7246                }
7247            } else {
7248                final PackageParser.Package pkg = mPackages.get(pkgName);
7249                result = null;
7250                if (pkg != null) {
7251                    result = filterIfNotSystemUser(
7252                            mActivities.queryIntentForPackage(
7253                                    intent, resolvedType, flags, pkg.activities, userId),
7254                            userId);
7255                }
7256                if (result == null || result.size() == 0) {
7257                    // the caller wants to resolve for a particular package; however, there
7258                    // were no installed results, so, try to find an ephemeral result
7259                    addEphemeral = !ephemeralDisabled
7260                            && isInstantAppAllowed(
7261                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7262                    if (result == null) {
7263                        result = new ArrayList<>();
7264                    }
7265                }
7266            }
7267        }
7268        if (addEphemeral) {
7269            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
7270        }
7271        if (sortResult) {
7272            Collections.sort(result, mResolvePrioritySorter);
7273        }
7274        return applyPostResolutionFilter(result, instantAppPkgName);
7275    }
7276
7277    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7278            String resolvedType, int flags, int userId) {
7279        // first, check to see if we've got an instant app already installed
7280        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7281        ResolveInfo localInstantApp = null;
7282        boolean blockResolution = false;
7283        if (!alreadyResolvedLocally) {
7284            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7285                    flags
7286                        | PackageManager.GET_RESOLVED_FILTER
7287                        | PackageManager.MATCH_INSTANT
7288                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7289                    userId);
7290            for (int i = instantApps.size() - 1; i >= 0; --i) {
7291                final ResolveInfo info = instantApps.get(i);
7292                final String packageName = info.activityInfo.packageName;
7293                final PackageSetting ps = mSettings.mPackages.get(packageName);
7294                if (ps.getInstantApp(userId)) {
7295                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7296                    final int status = (int)(packedStatus >> 32);
7297                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7298                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7299                        // there's a local instant application installed, but, the user has
7300                        // chosen to never use it; skip resolution and don't acknowledge
7301                        // an instant application is even available
7302                        if (DEBUG_EPHEMERAL) {
7303                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7304                        }
7305                        blockResolution = true;
7306                        break;
7307                    } else {
7308                        // we have a locally installed instant application; skip resolution
7309                        // but acknowledge there's an instant application available
7310                        if (DEBUG_EPHEMERAL) {
7311                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7312                        }
7313                        localInstantApp = info;
7314                        break;
7315                    }
7316                }
7317            }
7318        }
7319        // no app installed, let's see if one's available
7320        AuxiliaryResolveInfo auxiliaryResponse = null;
7321        if (!blockResolution) {
7322            if (localInstantApp == null) {
7323                // we don't have an instant app locally, resolve externally
7324                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7325                final InstantAppRequest requestObject = new InstantAppRequest(
7326                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7327                        null /*callingPackage*/, userId, null /*verificationBundle*/);
7328                auxiliaryResponse =
7329                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7330                                mContext, mInstantAppResolverConnection, requestObject);
7331                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7332            } else {
7333                // we have an instant application locally, but, we can't admit that since
7334                // callers shouldn't be able to determine prior browsing. create a dummy
7335                // auxiliary response so the downstream code behaves as if there's an
7336                // instant application available externally. when it comes time to start
7337                // the instant application, we'll do the right thing.
7338                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7339                auxiliaryResponse = new AuxiliaryResolveInfo(
7340                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
7341            }
7342        }
7343        if (auxiliaryResponse != null) {
7344            if (DEBUG_EPHEMERAL) {
7345                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7346            }
7347            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7348            final PackageSetting ps =
7349                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7350            if (ps != null) {
7351                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7352                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7353                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7354                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7355                // make sure this resolver is the default
7356                ephemeralInstaller.isDefault = true;
7357                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7358                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7359                // add a non-generic filter
7360                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7361                ephemeralInstaller.filter.addDataPath(
7362                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7363                ephemeralInstaller.isInstantAppAvailable = true;
7364                result.add(ephemeralInstaller);
7365            }
7366        }
7367        return result;
7368    }
7369
7370    private static class CrossProfileDomainInfo {
7371        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7372        ResolveInfo resolveInfo;
7373        /* Best domain verification status of the activities found in the other profile */
7374        int bestDomainVerificationStatus;
7375    }
7376
7377    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7378            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7379        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7380                sourceUserId)) {
7381            return null;
7382        }
7383        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7384                resolvedType, flags, parentUserId);
7385
7386        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7387            return null;
7388        }
7389        CrossProfileDomainInfo result = null;
7390        int size = resultTargetUser.size();
7391        for (int i = 0; i < size; i++) {
7392            ResolveInfo riTargetUser = resultTargetUser.get(i);
7393            // Intent filter verification is only for filters that specify a host. So don't return
7394            // those that handle all web uris.
7395            if (riTargetUser.handleAllWebDataURI) {
7396                continue;
7397            }
7398            String packageName = riTargetUser.activityInfo.packageName;
7399            PackageSetting ps = mSettings.mPackages.get(packageName);
7400            if (ps == null) {
7401                continue;
7402            }
7403            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7404            int status = (int)(verificationState >> 32);
7405            if (result == null) {
7406                result = new CrossProfileDomainInfo();
7407                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7408                        sourceUserId, parentUserId);
7409                result.bestDomainVerificationStatus = status;
7410            } else {
7411                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7412                        result.bestDomainVerificationStatus);
7413            }
7414        }
7415        // Don't consider matches with status NEVER across profiles.
7416        if (result != null && result.bestDomainVerificationStatus
7417                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7418            return null;
7419        }
7420        return result;
7421    }
7422
7423    /**
7424     * Verification statuses are ordered from the worse to the best, except for
7425     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7426     */
7427    private int bestDomainVerificationStatus(int status1, int status2) {
7428        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7429            return status2;
7430        }
7431        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7432            return status1;
7433        }
7434        return (int) MathUtils.max(status1, status2);
7435    }
7436
7437    private boolean isUserEnabled(int userId) {
7438        long callingId = Binder.clearCallingIdentity();
7439        try {
7440            UserInfo userInfo = sUserManager.getUserInfo(userId);
7441            return userInfo != null && userInfo.isEnabled();
7442        } finally {
7443            Binder.restoreCallingIdentity(callingId);
7444        }
7445    }
7446
7447    /**
7448     * Filter out activities with systemUserOnly flag set, when current user is not System.
7449     *
7450     * @return filtered list
7451     */
7452    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7453        if (userId == UserHandle.USER_SYSTEM) {
7454            return resolveInfos;
7455        }
7456        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7457            ResolveInfo info = resolveInfos.get(i);
7458            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7459                resolveInfos.remove(i);
7460            }
7461        }
7462        return resolveInfos;
7463    }
7464
7465    /**
7466     * Filters out ephemeral activities.
7467     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7468     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7469     *
7470     * @param resolveInfos The pre-filtered list of resolved activities
7471     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7472     *          is performed.
7473     * @return A filtered list of resolved activities.
7474     */
7475    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7476            String ephemeralPkgName) {
7477        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7478            final ResolveInfo info = resolveInfos.get(i);
7479            // TODO: When adding on-demand split support for non-instant apps, remove this check
7480            // and always apply post filtering
7481            // allow activities that are defined in the provided package
7482            if (info.activityInfo.splitName != null
7483                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7484                            info.activityInfo.splitName)) {
7485                // requested activity is defined in a split that hasn't been installed yet.
7486                // add the installer to the resolve list
7487                if (DEBUG_INSTALL) {
7488                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
7489                }
7490                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7491                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7492                        info.activityInfo.packageName, info.activityInfo.splitName,
7493                        info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
7494                // make sure this resolver is the default
7495                installerInfo.isDefault = true;
7496                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7497                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7498                // add a non-generic filter
7499                installerInfo.filter = new IntentFilter();
7500                // load resources from the correct package
7501                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7502                resolveInfos.set(i, installerInfo);
7503                continue;
7504            }
7505            // caller is a full app, don't need to apply any other filtering
7506            if (ephemeralPkgName == null) {
7507                continue;
7508            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7509                // caller is same app; don't need to apply any other filtering
7510                continue;
7511            }
7512            // allow activities that have been explicitly exposed to ephemeral apps
7513            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7514            if (!isEphemeralApp
7515                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7516                continue;
7517            }
7518            resolveInfos.remove(i);
7519        }
7520        return resolveInfos;
7521    }
7522
7523    /**
7524     * @param resolveInfos list of resolve infos in descending priority order
7525     * @return if the list contains a resolve info with non-negative priority
7526     */
7527    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7528        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7529    }
7530
7531    private static boolean hasWebURI(Intent intent) {
7532        if (intent.getData() == null) {
7533            return false;
7534        }
7535        final String scheme = intent.getScheme();
7536        if (TextUtils.isEmpty(scheme)) {
7537            return false;
7538        }
7539        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7540    }
7541
7542    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7543            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7544            int userId) {
7545        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7546
7547        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7548            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7549                    candidates.size());
7550        }
7551
7552        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7553        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7554        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7555        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7556        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7557        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7558
7559        synchronized (mPackages) {
7560            final int count = candidates.size();
7561            // First, try to use linked apps. Partition the candidates into four lists:
7562            // one for the final results, one for the "do not use ever", one for "undefined status"
7563            // and finally one for "browser app type".
7564            for (int n=0; n<count; n++) {
7565                ResolveInfo info = candidates.get(n);
7566                String packageName = info.activityInfo.packageName;
7567                PackageSetting ps = mSettings.mPackages.get(packageName);
7568                if (ps != null) {
7569                    // Add to the special match all list (Browser use case)
7570                    if (info.handleAllWebDataURI) {
7571                        matchAllList.add(info);
7572                        continue;
7573                    }
7574                    // Try to get the status from User settings first
7575                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7576                    int status = (int)(packedStatus >> 32);
7577                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7578                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7579                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7580                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7581                                    + " : linkgen=" + linkGeneration);
7582                        }
7583                        // Use link-enabled generation as preferredOrder, i.e.
7584                        // prefer newly-enabled over earlier-enabled.
7585                        info.preferredOrder = linkGeneration;
7586                        alwaysList.add(info);
7587                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7588                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7589                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7590                        }
7591                        neverList.add(info);
7592                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7593                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7594                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7595                        }
7596                        alwaysAskList.add(info);
7597                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7598                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7599                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7600                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7601                        }
7602                        undefinedList.add(info);
7603                    }
7604                }
7605            }
7606
7607            // We'll want to include browser possibilities in a few cases
7608            boolean includeBrowser = false;
7609
7610            // First try to add the "always" resolution(s) for the current user, if any
7611            if (alwaysList.size() > 0) {
7612                result.addAll(alwaysList);
7613            } else {
7614                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7615                result.addAll(undefinedList);
7616                // Maybe add one for the other profile.
7617                if (xpDomainInfo != null && (
7618                        xpDomainInfo.bestDomainVerificationStatus
7619                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7620                    result.add(xpDomainInfo.resolveInfo);
7621                }
7622                includeBrowser = true;
7623            }
7624
7625            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7626            // If there were 'always' entries their preferred order has been set, so we also
7627            // back that off to make the alternatives equivalent
7628            if (alwaysAskList.size() > 0) {
7629                for (ResolveInfo i : result) {
7630                    i.preferredOrder = 0;
7631                }
7632                result.addAll(alwaysAskList);
7633                includeBrowser = true;
7634            }
7635
7636            if (includeBrowser) {
7637                // Also add browsers (all of them or only the default one)
7638                if (DEBUG_DOMAIN_VERIFICATION) {
7639                    Slog.v(TAG, "   ...including browsers in candidate set");
7640                }
7641                if ((matchFlags & MATCH_ALL) != 0) {
7642                    result.addAll(matchAllList);
7643                } else {
7644                    // Browser/generic handling case.  If there's a default browser, go straight
7645                    // to that (but only if there is no other higher-priority match).
7646                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7647                    int maxMatchPrio = 0;
7648                    ResolveInfo defaultBrowserMatch = null;
7649                    final int numCandidates = matchAllList.size();
7650                    for (int n = 0; n < numCandidates; n++) {
7651                        ResolveInfo info = matchAllList.get(n);
7652                        // track the highest overall match priority...
7653                        if (info.priority > maxMatchPrio) {
7654                            maxMatchPrio = info.priority;
7655                        }
7656                        // ...and the highest-priority default browser match
7657                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7658                            if (defaultBrowserMatch == null
7659                                    || (defaultBrowserMatch.priority < info.priority)) {
7660                                if (debug) {
7661                                    Slog.v(TAG, "Considering default browser match " + info);
7662                                }
7663                                defaultBrowserMatch = info;
7664                            }
7665                        }
7666                    }
7667                    if (defaultBrowserMatch != null
7668                            && defaultBrowserMatch.priority >= maxMatchPrio
7669                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7670                    {
7671                        if (debug) {
7672                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7673                        }
7674                        result.add(defaultBrowserMatch);
7675                    } else {
7676                        result.addAll(matchAllList);
7677                    }
7678                }
7679
7680                // If there is nothing selected, add all candidates and remove the ones that the user
7681                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7682                if (result.size() == 0) {
7683                    result.addAll(candidates);
7684                    result.removeAll(neverList);
7685                }
7686            }
7687        }
7688        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7689            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7690                    result.size());
7691            for (ResolveInfo info : result) {
7692                Slog.v(TAG, "  + " + info.activityInfo);
7693            }
7694        }
7695        return result;
7696    }
7697
7698    // Returns a packed value as a long:
7699    //
7700    // high 'int'-sized word: link status: undefined/ask/never/always.
7701    // low 'int'-sized word: relative priority among 'always' results.
7702    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7703        long result = ps.getDomainVerificationStatusForUser(userId);
7704        // if none available, get the master status
7705        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7706            if (ps.getIntentFilterVerificationInfo() != null) {
7707                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7708            }
7709        }
7710        return result;
7711    }
7712
7713    private ResolveInfo querySkipCurrentProfileIntents(
7714            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7715            int flags, int sourceUserId) {
7716        if (matchingFilters != null) {
7717            int size = matchingFilters.size();
7718            for (int i = 0; i < size; i ++) {
7719                CrossProfileIntentFilter filter = matchingFilters.get(i);
7720                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7721                    // Checking if there are activities in the target user that can handle the
7722                    // intent.
7723                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7724                            resolvedType, flags, sourceUserId);
7725                    if (resolveInfo != null) {
7726                        return resolveInfo;
7727                    }
7728                }
7729            }
7730        }
7731        return null;
7732    }
7733
7734    // Return matching ResolveInfo in target user if any.
7735    private ResolveInfo queryCrossProfileIntents(
7736            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7737            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7738        if (matchingFilters != null) {
7739            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7740            // match the same intent. For performance reasons, it is better not to
7741            // run queryIntent twice for the same userId
7742            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7743            int size = matchingFilters.size();
7744            for (int i = 0; i < size; i++) {
7745                CrossProfileIntentFilter filter = matchingFilters.get(i);
7746                int targetUserId = filter.getTargetUserId();
7747                boolean skipCurrentProfile =
7748                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7749                boolean skipCurrentProfileIfNoMatchFound =
7750                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7751                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7752                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7753                    // Checking if there are activities in the target user that can handle the
7754                    // intent.
7755                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7756                            resolvedType, flags, sourceUserId);
7757                    if (resolveInfo != null) return resolveInfo;
7758                    alreadyTriedUserIds.put(targetUserId, true);
7759                }
7760            }
7761        }
7762        return null;
7763    }
7764
7765    /**
7766     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7767     * will forward the intent to the filter's target user.
7768     * Otherwise, returns null.
7769     */
7770    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7771            String resolvedType, int flags, int sourceUserId) {
7772        int targetUserId = filter.getTargetUserId();
7773        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7774                resolvedType, flags, targetUserId);
7775        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7776            // If all the matches in the target profile are suspended, return null.
7777            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7778                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7779                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7780                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7781                            targetUserId);
7782                }
7783            }
7784        }
7785        return null;
7786    }
7787
7788    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7789            int sourceUserId, int targetUserId) {
7790        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7791        long ident = Binder.clearCallingIdentity();
7792        boolean targetIsProfile;
7793        try {
7794            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7795        } finally {
7796            Binder.restoreCallingIdentity(ident);
7797        }
7798        String className;
7799        if (targetIsProfile) {
7800            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7801        } else {
7802            className = FORWARD_INTENT_TO_PARENT;
7803        }
7804        ComponentName forwardingActivityComponentName = new ComponentName(
7805                mAndroidApplication.packageName, className);
7806        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7807                sourceUserId);
7808        if (!targetIsProfile) {
7809            forwardingActivityInfo.showUserIcon = targetUserId;
7810            forwardingResolveInfo.noResourceId = true;
7811        }
7812        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7813        forwardingResolveInfo.priority = 0;
7814        forwardingResolveInfo.preferredOrder = 0;
7815        forwardingResolveInfo.match = 0;
7816        forwardingResolveInfo.isDefault = true;
7817        forwardingResolveInfo.filter = filter;
7818        forwardingResolveInfo.targetUserId = targetUserId;
7819        return forwardingResolveInfo;
7820    }
7821
7822    @Override
7823    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7824            Intent[] specifics, String[] specificTypes, Intent intent,
7825            String resolvedType, int flags, int userId) {
7826        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7827                specificTypes, intent, resolvedType, flags, userId));
7828    }
7829
7830    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7831            Intent[] specifics, String[] specificTypes, Intent intent,
7832            String resolvedType, int flags, int userId) {
7833        if (!sUserManager.exists(userId)) return Collections.emptyList();
7834        final int callingUid = Binder.getCallingUid();
7835        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7836                false /*includeInstantApps*/);
7837        enforceCrossUserPermission(callingUid, userId,
7838                false /*requireFullPermission*/, false /*checkShell*/,
7839                "query intent activity options");
7840        final String resultsAction = intent.getAction();
7841
7842        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7843                | PackageManager.GET_RESOLVED_FILTER, userId);
7844
7845        if (DEBUG_INTENT_MATCHING) {
7846            Log.v(TAG, "Query " + intent + ": " + results);
7847        }
7848
7849        int specificsPos = 0;
7850        int N;
7851
7852        // todo: note that the algorithm used here is O(N^2).  This
7853        // isn't a problem in our current environment, but if we start running
7854        // into situations where we have more than 5 or 10 matches then this
7855        // should probably be changed to something smarter...
7856
7857        // First we go through and resolve each of the specific items
7858        // that were supplied, taking care of removing any corresponding
7859        // duplicate items in the generic resolve list.
7860        if (specifics != null) {
7861            for (int i=0; i<specifics.length; i++) {
7862                final Intent sintent = specifics[i];
7863                if (sintent == null) {
7864                    continue;
7865                }
7866
7867                if (DEBUG_INTENT_MATCHING) {
7868                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7869                }
7870
7871                String action = sintent.getAction();
7872                if (resultsAction != null && resultsAction.equals(action)) {
7873                    // If this action was explicitly requested, then don't
7874                    // remove things that have it.
7875                    action = null;
7876                }
7877
7878                ResolveInfo ri = null;
7879                ActivityInfo ai = null;
7880
7881                ComponentName comp = sintent.getComponent();
7882                if (comp == null) {
7883                    ri = resolveIntent(
7884                        sintent,
7885                        specificTypes != null ? specificTypes[i] : null,
7886                            flags, userId);
7887                    if (ri == null) {
7888                        continue;
7889                    }
7890                    if (ri == mResolveInfo) {
7891                        // ACK!  Must do something better with this.
7892                    }
7893                    ai = ri.activityInfo;
7894                    comp = new ComponentName(ai.applicationInfo.packageName,
7895                            ai.name);
7896                } else {
7897                    ai = getActivityInfo(comp, flags, userId);
7898                    if (ai == null) {
7899                        continue;
7900                    }
7901                }
7902
7903                // Look for any generic query activities that are duplicates
7904                // of this specific one, and remove them from the results.
7905                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7906                N = results.size();
7907                int j;
7908                for (j=specificsPos; j<N; j++) {
7909                    ResolveInfo sri = results.get(j);
7910                    if ((sri.activityInfo.name.equals(comp.getClassName())
7911                            && sri.activityInfo.applicationInfo.packageName.equals(
7912                                    comp.getPackageName()))
7913                        || (action != null && sri.filter.matchAction(action))) {
7914                        results.remove(j);
7915                        if (DEBUG_INTENT_MATCHING) Log.v(
7916                            TAG, "Removing duplicate item from " + j
7917                            + " due to specific " + specificsPos);
7918                        if (ri == null) {
7919                            ri = sri;
7920                        }
7921                        j--;
7922                        N--;
7923                    }
7924                }
7925
7926                // Add this specific item to its proper place.
7927                if (ri == null) {
7928                    ri = new ResolveInfo();
7929                    ri.activityInfo = ai;
7930                }
7931                results.add(specificsPos, ri);
7932                ri.specificIndex = i;
7933                specificsPos++;
7934            }
7935        }
7936
7937        // Now we go through the remaining generic results and remove any
7938        // duplicate actions that are found here.
7939        N = results.size();
7940        for (int i=specificsPos; i<N-1; i++) {
7941            final ResolveInfo rii = results.get(i);
7942            if (rii.filter == null) {
7943                continue;
7944            }
7945
7946            // Iterate over all of the actions of this result's intent
7947            // filter...  typically this should be just one.
7948            final Iterator<String> it = rii.filter.actionsIterator();
7949            if (it == null) {
7950                continue;
7951            }
7952            while (it.hasNext()) {
7953                final String action = it.next();
7954                if (resultsAction != null && resultsAction.equals(action)) {
7955                    // If this action was explicitly requested, then don't
7956                    // remove things that have it.
7957                    continue;
7958                }
7959                for (int j=i+1; j<N; j++) {
7960                    final ResolveInfo rij = results.get(j);
7961                    if (rij.filter != null && rij.filter.hasAction(action)) {
7962                        results.remove(j);
7963                        if (DEBUG_INTENT_MATCHING) Log.v(
7964                            TAG, "Removing duplicate item from " + j
7965                            + " due to action " + action + " at " + i);
7966                        j--;
7967                        N--;
7968                    }
7969                }
7970            }
7971
7972            // If the caller didn't request filter information, drop it now
7973            // so we don't have to marshall/unmarshall it.
7974            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7975                rii.filter = null;
7976            }
7977        }
7978
7979        // Filter out the caller activity if so requested.
7980        if (caller != null) {
7981            N = results.size();
7982            for (int i=0; i<N; i++) {
7983                ActivityInfo ainfo = results.get(i).activityInfo;
7984                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7985                        && caller.getClassName().equals(ainfo.name)) {
7986                    results.remove(i);
7987                    break;
7988                }
7989            }
7990        }
7991
7992        // If the caller didn't request filter information,
7993        // drop them now so we don't have to
7994        // marshall/unmarshall it.
7995        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7996            N = results.size();
7997            for (int i=0; i<N; i++) {
7998                results.get(i).filter = null;
7999            }
8000        }
8001
8002        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8003        return results;
8004    }
8005
8006    @Override
8007    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8008            String resolvedType, int flags, int userId) {
8009        return new ParceledListSlice<>(
8010                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
8011    }
8012
8013    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8014            String resolvedType, int flags, int userId) {
8015        if (!sUserManager.exists(userId)) return Collections.emptyList();
8016        final int callingUid = Binder.getCallingUid();
8017        enforceCrossUserPermission(callingUid, userId,
8018                false /*requireFullPermission*/, false /*checkShell*/,
8019                "query intent receivers");
8020        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8021        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8022                false /*includeInstantApps*/);
8023        ComponentName comp = intent.getComponent();
8024        if (comp == null) {
8025            if (intent.getSelector() != null) {
8026                intent = intent.getSelector();
8027                comp = intent.getComponent();
8028            }
8029        }
8030        if (comp != null) {
8031            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8032            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8033            if (ai != null) {
8034                // When specifying an explicit component, we prevent the activity from being
8035                // used when either 1) the calling package is normal and the activity is within
8036                // an instant application or 2) the calling package is ephemeral and the
8037                // activity is not visible to instant applications.
8038                final boolean matchInstantApp =
8039                        (flags & PackageManager.MATCH_INSTANT) != 0;
8040                final boolean matchVisibleToInstantAppOnly =
8041                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8042                final boolean matchExplicitlyVisibleOnly =
8043                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8044                final boolean isCallerInstantApp =
8045                        instantAppPkgName != null;
8046                final boolean isTargetSameInstantApp =
8047                        comp.getPackageName().equals(instantAppPkgName);
8048                final boolean isTargetInstantApp =
8049                        (ai.applicationInfo.privateFlags
8050                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8051                final boolean isTargetVisibleToInstantApp =
8052                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8053                final boolean isTargetExplicitlyVisibleToInstantApp =
8054                        isTargetVisibleToInstantApp
8055                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8056                final boolean isTargetHiddenFromInstantApp =
8057                        !isTargetVisibleToInstantApp
8058                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8059                final boolean blockResolution =
8060                        !isTargetSameInstantApp
8061                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8062                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8063                                        && isTargetHiddenFromInstantApp));
8064                if (!blockResolution) {
8065                    ResolveInfo ri = new ResolveInfo();
8066                    ri.activityInfo = ai;
8067                    list.add(ri);
8068                }
8069            }
8070            return applyPostResolutionFilter(list, instantAppPkgName);
8071        }
8072
8073        // reader
8074        synchronized (mPackages) {
8075            String pkgName = intent.getPackage();
8076            if (pkgName == null) {
8077                final List<ResolveInfo> result =
8078                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
8079                return applyPostResolutionFilter(result, instantAppPkgName);
8080            }
8081            final PackageParser.Package pkg = mPackages.get(pkgName);
8082            if (pkg != null) {
8083                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8084                        intent, resolvedType, flags, pkg.receivers, userId);
8085                return applyPostResolutionFilter(result, instantAppPkgName);
8086            }
8087            return Collections.emptyList();
8088        }
8089    }
8090
8091    @Override
8092    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8093        final int callingUid = Binder.getCallingUid();
8094        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8095    }
8096
8097    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8098            int userId, int callingUid) {
8099        if (!sUserManager.exists(userId)) return null;
8100        flags = updateFlagsForResolve(
8101                flags, userId, intent, callingUid, false /*includeInstantApps*/);
8102        List<ResolveInfo> query = queryIntentServicesInternal(
8103                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8104        if (query != null) {
8105            if (query.size() >= 1) {
8106                // If there is more than one service with the same priority,
8107                // just arbitrarily pick the first one.
8108                return query.get(0);
8109            }
8110        }
8111        return null;
8112    }
8113
8114    @Override
8115    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8116            String resolvedType, int flags, int userId) {
8117        final int callingUid = Binder.getCallingUid();
8118        return new ParceledListSlice<>(queryIntentServicesInternal(
8119                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8120    }
8121
8122    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8123            String resolvedType, int flags, int userId, int callingUid,
8124            boolean includeInstantApps) {
8125        if (!sUserManager.exists(userId)) return Collections.emptyList();
8126        enforceCrossUserPermission(callingUid, userId,
8127                false /*requireFullPermission*/, false /*checkShell*/,
8128                "query intent receivers");
8129        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8130        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8131        ComponentName comp = intent.getComponent();
8132        if (comp == null) {
8133            if (intent.getSelector() != null) {
8134                intent = intent.getSelector();
8135                comp = intent.getComponent();
8136            }
8137        }
8138        if (comp != null) {
8139            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8140            final ServiceInfo si = getServiceInfo(comp, flags, userId);
8141            if (si != null) {
8142                // When specifying an explicit component, we prevent the service from being
8143                // used when either 1) the service is in an instant application and the
8144                // caller is not the same instant application or 2) the calling package is
8145                // ephemeral and the activity is not visible to ephemeral applications.
8146                final boolean matchInstantApp =
8147                        (flags & PackageManager.MATCH_INSTANT) != 0;
8148                final boolean matchVisibleToInstantAppOnly =
8149                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8150                final boolean isCallerInstantApp =
8151                        instantAppPkgName != null;
8152                final boolean isTargetSameInstantApp =
8153                        comp.getPackageName().equals(instantAppPkgName);
8154                final boolean isTargetInstantApp =
8155                        (si.applicationInfo.privateFlags
8156                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8157                final boolean isTargetHiddenFromInstantApp =
8158                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8159                final boolean blockResolution =
8160                        !isTargetSameInstantApp
8161                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8162                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8163                                        && isTargetHiddenFromInstantApp));
8164                if (!blockResolution) {
8165                    final ResolveInfo ri = new ResolveInfo();
8166                    ri.serviceInfo = si;
8167                    list.add(ri);
8168                }
8169            }
8170            return list;
8171        }
8172
8173        // reader
8174        synchronized (mPackages) {
8175            String pkgName = intent.getPackage();
8176            if (pkgName == null) {
8177                return applyPostServiceResolutionFilter(
8178                        mServices.queryIntent(intent, resolvedType, flags, userId),
8179                        instantAppPkgName);
8180            }
8181            final PackageParser.Package pkg = mPackages.get(pkgName);
8182            if (pkg != null) {
8183                return applyPostServiceResolutionFilter(
8184                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8185                                userId),
8186                        instantAppPkgName);
8187            }
8188            return Collections.emptyList();
8189        }
8190    }
8191
8192    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8193            String instantAppPkgName) {
8194        // TODO: When adding on-demand split support for non-instant apps, remove this check
8195        // and always apply post filtering
8196        if (instantAppPkgName == null) {
8197            return resolveInfos;
8198        }
8199        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8200            final ResolveInfo info = resolveInfos.get(i);
8201            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8202            // allow services that are defined in the provided package
8203            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8204                if (info.serviceInfo.splitName != null
8205                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8206                                info.serviceInfo.splitName)) {
8207                    // requested service is defined in a split that hasn't been installed yet.
8208                    // add the installer to the resolve list
8209                    if (DEBUG_EPHEMERAL) {
8210                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8211                    }
8212                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8213                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8214                            info.serviceInfo.packageName, info.serviceInfo.splitName,
8215                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
8216                    // make sure this resolver is the default
8217                    installerInfo.isDefault = true;
8218                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8219                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8220                    // add a non-generic filter
8221                    installerInfo.filter = new IntentFilter();
8222                    // load resources from the correct package
8223                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8224                    resolveInfos.set(i, installerInfo);
8225                }
8226                continue;
8227            }
8228            // allow services that have been explicitly exposed to ephemeral apps
8229            if (!isEphemeralApp
8230                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8231                continue;
8232            }
8233            resolveInfos.remove(i);
8234        }
8235        return resolveInfos;
8236    }
8237
8238    @Override
8239    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8240            String resolvedType, int flags, int userId) {
8241        return new ParceledListSlice<>(
8242                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8243    }
8244
8245    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8246            Intent intent, String resolvedType, int flags, int userId) {
8247        if (!sUserManager.exists(userId)) return Collections.emptyList();
8248        final int callingUid = Binder.getCallingUid();
8249        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8250        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8251                false /*includeInstantApps*/);
8252        ComponentName comp = intent.getComponent();
8253        if (comp == null) {
8254            if (intent.getSelector() != null) {
8255                intent = intent.getSelector();
8256                comp = intent.getComponent();
8257            }
8258        }
8259        if (comp != null) {
8260            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8261            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8262            if (pi != null) {
8263                // When specifying an explicit component, we prevent the provider from being
8264                // used when either 1) the provider is in an instant application and the
8265                // caller is not the same instant application or 2) the calling package is an
8266                // instant application and the provider is not visible to instant applications.
8267                final boolean matchInstantApp =
8268                        (flags & PackageManager.MATCH_INSTANT) != 0;
8269                final boolean matchVisibleToInstantAppOnly =
8270                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8271                final boolean isCallerInstantApp =
8272                        instantAppPkgName != null;
8273                final boolean isTargetSameInstantApp =
8274                        comp.getPackageName().equals(instantAppPkgName);
8275                final boolean isTargetInstantApp =
8276                        (pi.applicationInfo.privateFlags
8277                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8278                final boolean isTargetHiddenFromInstantApp =
8279                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8280                final boolean blockResolution =
8281                        !isTargetSameInstantApp
8282                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8283                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8284                                        && isTargetHiddenFromInstantApp));
8285                if (!blockResolution) {
8286                    final ResolveInfo ri = new ResolveInfo();
8287                    ri.providerInfo = pi;
8288                    list.add(ri);
8289                }
8290            }
8291            return list;
8292        }
8293
8294        // reader
8295        synchronized (mPackages) {
8296            String pkgName = intent.getPackage();
8297            if (pkgName == null) {
8298                return applyPostContentProviderResolutionFilter(
8299                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8300                        instantAppPkgName);
8301            }
8302            final PackageParser.Package pkg = mPackages.get(pkgName);
8303            if (pkg != null) {
8304                return applyPostContentProviderResolutionFilter(
8305                        mProviders.queryIntentForPackage(
8306                        intent, resolvedType, flags, pkg.providers, userId),
8307                        instantAppPkgName);
8308            }
8309            return Collections.emptyList();
8310        }
8311    }
8312
8313    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8314            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8315        // TODO: When adding on-demand split support for non-instant applications, remove
8316        // this check and always apply post filtering
8317        if (instantAppPkgName == null) {
8318            return resolveInfos;
8319        }
8320        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8321            final ResolveInfo info = resolveInfos.get(i);
8322            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8323            // allow providers that are defined in the provided package
8324            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8325                if (info.providerInfo.splitName != null
8326                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8327                                info.providerInfo.splitName)) {
8328                    // requested provider is defined in a split that hasn't been installed yet.
8329                    // add the installer to the resolve list
8330                    if (DEBUG_EPHEMERAL) {
8331                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8332                    }
8333                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8334                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8335                            info.providerInfo.packageName, info.providerInfo.splitName,
8336                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
8337                    // make sure this resolver is the default
8338                    installerInfo.isDefault = true;
8339                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8340                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8341                    // add a non-generic filter
8342                    installerInfo.filter = new IntentFilter();
8343                    // load resources from the correct package
8344                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8345                    resolveInfos.set(i, installerInfo);
8346                }
8347                continue;
8348            }
8349            // allow providers that have been explicitly exposed to instant applications
8350            if (!isEphemeralApp
8351                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8352                continue;
8353            }
8354            resolveInfos.remove(i);
8355        }
8356        return resolveInfos;
8357    }
8358
8359    @Override
8360    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8361        final int callingUid = Binder.getCallingUid();
8362        if (getInstantAppPackageName(callingUid) != null) {
8363            return ParceledListSlice.emptyList();
8364        }
8365        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8366        flags = updateFlagsForPackage(flags, userId, null);
8367        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8368        enforceCrossUserPermission(callingUid, userId,
8369                true /* requireFullPermission */, false /* checkShell */,
8370                "get installed packages");
8371
8372        // writer
8373        synchronized (mPackages) {
8374            ArrayList<PackageInfo> list;
8375            if (listUninstalled) {
8376                list = new ArrayList<>(mSettings.mPackages.size());
8377                for (PackageSetting ps : mSettings.mPackages.values()) {
8378                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8379                        continue;
8380                    }
8381                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8382                        return null;
8383                    }
8384                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8385                    if (pi != null) {
8386                        list.add(pi);
8387                    }
8388                }
8389            } else {
8390                list = new ArrayList<>(mPackages.size());
8391                for (PackageParser.Package p : mPackages.values()) {
8392                    final PackageSetting ps = (PackageSetting) p.mExtras;
8393                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8394                        continue;
8395                    }
8396                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8397                        return null;
8398                    }
8399                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8400                            p.mExtras, flags, userId);
8401                    if (pi != null) {
8402                        list.add(pi);
8403                    }
8404                }
8405            }
8406
8407            return new ParceledListSlice<>(list);
8408        }
8409    }
8410
8411    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8412            String[] permissions, boolean[] tmp, int flags, int userId) {
8413        int numMatch = 0;
8414        final PermissionsState permissionsState = ps.getPermissionsState();
8415        for (int i=0; i<permissions.length; i++) {
8416            final String permission = permissions[i];
8417            if (permissionsState.hasPermission(permission, userId)) {
8418                tmp[i] = true;
8419                numMatch++;
8420            } else {
8421                tmp[i] = false;
8422            }
8423        }
8424        if (numMatch == 0) {
8425            return;
8426        }
8427        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8428
8429        // The above might return null in cases of uninstalled apps or install-state
8430        // skew across users/profiles.
8431        if (pi != null) {
8432            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8433                if (numMatch == permissions.length) {
8434                    pi.requestedPermissions = permissions;
8435                } else {
8436                    pi.requestedPermissions = new String[numMatch];
8437                    numMatch = 0;
8438                    for (int i=0; i<permissions.length; i++) {
8439                        if (tmp[i]) {
8440                            pi.requestedPermissions[numMatch] = permissions[i];
8441                            numMatch++;
8442                        }
8443                    }
8444                }
8445            }
8446            list.add(pi);
8447        }
8448    }
8449
8450    @Override
8451    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8452            String[] permissions, int flags, int userId) {
8453        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8454        flags = updateFlagsForPackage(flags, userId, permissions);
8455        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8456                true /* requireFullPermission */, false /* checkShell */,
8457                "get packages holding permissions");
8458        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8459
8460        // writer
8461        synchronized (mPackages) {
8462            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8463            boolean[] tmpBools = new boolean[permissions.length];
8464            if (listUninstalled) {
8465                for (PackageSetting ps : mSettings.mPackages.values()) {
8466                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8467                            userId);
8468                }
8469            } else {
8470                for (PackageParser.Package pkg : mPackages.values()) {
8471                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8472                    if (ps != null) {
8473                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8474                                userId);
8475                    }
8476                }
8477            }
8478
8479            return new ParceledListSlice<PackageInfo>(list);
8480        }
8481    }
8482
8483    @Override
8484    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8485        final int callingUid = Binder.getCallingUid();
8486        if (getInstantAppPackageName(callingUid) != null) {
8487            return ParceledListSlice.emptyList();
8488        }
8489        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8490        flags = updateFlagsForApplication(flags, userId, null);
8491        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8492
8493        // writer
8494        synchronized (mPackages) {
8495            ArrayList<ApplicationInfo> list;
8496            if (listUninstalled) {
8497                list = new ArrayList<>(mSettings.mPackages.size());
8498                for (PackageSetting ps : mSettings.mPackages.values()) {
8499                    ApplicationInfo ai;
8500                    int effectiveFlags = flags;
8501                    if (ps.isSystem()) {
8502                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8503                    }
8504                    if (ps.pkg != null) {
8505                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8506                            continue;
8507                        }
8508                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8509                            return null;
8510                        }
8511                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8512                                ps.readUserState(userId), userId);
8513                        if (ai != null) {
8514                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8515                        }
8516                    } else {
8517                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8518                        // and already converts to externally visible package name
8519                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8520                                callingUid, effectiveFlags, userId);
8521                    }
8522                    if (ai != null) {
8523                        list.add(ai);
8524                    }
8525                }
8526            } else {
8527                list = new ArrayList<>(mPackages.size());
8528                for (PackageParser.Package p : mPackages.values()) {
8529                    if (p.mExtras != null) {
8530                        PackageSetting ps = (PackageSetting) p.mExtras;
8531                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8532                            continue;
8533                        }
8534                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8535                            return null;
8536                        }
8537                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8538                                ps.readUserState(userId), userId);
8539                        if (ai != null) {
8540                            ai.packageName = resolveExternalPackageNameLPr(p);
8541                            list.add(ai);
8542                        }
8543                    }
8544                }
8545            }
8546
8547            return new ParceledListSlice<>(list);
8548        }
8549    }
8550
8551    @Override
8552    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8553        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8554            return null;
8555        }
8556        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8557            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8558                    "getEphemeralApplications");
8559        }
8560        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8561                true /* requireFullPermission */, false /* checkShell */,
8562                "getEphemeralApplications");
8563        synchronized (mPackages) {
8564            List<InstantAppInfo> instantApps = mInstantAppRegistry
8565                    .getInstantAppsLPr(userId);
8566            if (instantApps != null) {
8567                return new ParceledListSlice<>(instantApps);
8568            }
8569        }
8570        return null;
8571    }
8572
8573    @Override
8574    public boolean isInstantApp(String packageName, int userId) {
8575        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8576                true /* requireFullPermission */, false /* checkShell */,
8577                "isInstantApp");
8578        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8579            return false;
8580        }
8581
8582        synchronized (mPackages) {
8583            int callingUid = Binder.getCallingUid();
8584            if (Process.isIsolated(callingUid)) {
8585                callingUid = mIsolatedOwners.get(callingUid);
8586            }
8587            final PackageSetting ps = mSettings.mPackages.get(packageName);
8588            PackageParser.Package pkg = mPackages.get(packageName);
8589            final boolean returnAllowed =
8590                    ps != null
8591                    && (isCallerSameApp(packageName, callingUid)
8592                            || canViewInstantApps(callingUid, userId)
8593                            || mInstantAppRegistry.isInstantAccessGranted(
8594                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8595            if (returnAllowed) {
8596                return ps.getInstantApp(userId);
8597            }
8598        }
8599        return false;
8600    }
8601
8602    @Override
8603    public byte[] getInstantAppCookie(String packageName, int userId) {
8604        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8605            return null;
8606        }
8607
8608        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8609                true /* requireFullPermission */, false /* checkShell */,
8610                "getInstantAppCookie");
8611        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8612            return null;
8613        }
8614        synchronized (mPackages) {
8615            return mInstantAppRegistry.getInstantAppCookieLPw(
8616                    packageName, userId);
8617        }
8618    }
8619
8620    @Override
8621    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8622        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8623            return true;
8624        }
8625
8626        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8627                true /* requireFullPermission */, true /* checkShell */,
8628                "setInstantAppCookie");
8629        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8630            return false;
8631        }
8632        synchronized (mPackages) {
8633            return mInstantAppRegistry.setInstantAppCookieLPw(
8634                    packageName, cookie, userId);
8635        }
8636    }
8637
8638    @Override
8639    public Bitmap getInstantAppIcon(String packageName, int userId) {
8640        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8641            return null;
8642        }
8643
8644        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8645            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8646                    "getInstantAppIcon");
8647        }
8648        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8649                true /* requireFullPermission */, false /* checkShell */,
8650                "getInstantAppIcon");
8651
8652        synchronized (mPackages) {
8653            return mInstantAppRegistry.getInstantAppIconLPw(
8654                    packageName, userId);
8655        }
8656    }
8657
8658    private boolean isCallerSameApp(String packageName, int uid) {
8659        PackageParser.Package pkg = mPackages.get(packageName);
8660        return pkg != null
8661                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8662    }
8663
8664    @Override
8665    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8666        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8667            return ParceledListSlice.emptyList();
8668        }
8669        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8670    }
8671
8672    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8673        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8674
8675        // reader
8676        synchronized (mPackages) {
8677            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8678            final int userId = UserHandle.getCallingUserId();
8679            while (i.hasNext()) {
8680                final PackageParser.Package p = i.next();
8681                if (p.applicationInfo == null) continue;
8682
8683                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8684                        && !p.applicationInfo.isDirectBootAware();
8685                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8686                        && p.applicationInfo.isDirectBootAware();
8687
8688                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8689                        && (!mSafeMode || isSystemApp(p))
8690                        && (matchesUnaware || matchesAware)) {
8691                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8692                    if (ps != null) {
8693                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8694                                ps.readUserState(userId), userId);
8695                        if (ai != null) {
8696                            finalList.add(ai);
8697                        }
8698                    }
8699                }
8700            }
8701        }
8702
8703        return finalList;
8704    }
8705
8706    @Override
8707    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8708        if (!sUserManager.exists(userId)) return null;
8709        flags = updateFlagsForComponent(flags, userId, name);
8710        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8711        // reader
8712        synchronized (mPackages) {
8713            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8714            PackageSetting ps = provider != null
8715                    ? mSettings.mPackages.get(provider.owner.packageName)
8716                    : null;
8717            if (ps != null) {
8718                final boolean isInstantApp = ps.getInstantApp(userId);
8719                // normal application; filter out instant application provider
8720                if (instantAppPkgName == null && isInstantApp) {
8721                    return null;
8722                }
8723                // instant application; filter out other instant applications
8724                if (instantAppPkgName != null
8725                        && isInstantApp
8726                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8727                    return null;
8728                }
8729                // instant application; filter out non-exposed provider
8730                if (instantAppPkgName != null
8731                        && !isInstantApp
8732                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8733                    return null;
8734                }
8735                // provider not enabled
8736                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8737                    return null;
8738                }
8739                return PackageParser.generateProviderInfo(
8740                        provider, flags, ps.readUserState(userId), userId);
8741            }
8742            return null;
8743        }
8744    }
8745
8746    /**
8747     * @deprecated
8748     */
8749    @Deprecated
8750    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8751        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8752            return;
8753        }
8754        // reader
8755        synchronized (mPackages) {
8756            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8757                    .entrySet().iterator();
8758            final int userId = UserHandle.getCallingUserId();
8759            while (i.hasNext()) {
8760                Map.Entry<String, PackageParser.Provider> entry = i.next();
8761                PackageParser.Provider p = entry.getValue();
8762                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8763
8764                if (ps != null && p.syncable
8765                        && (!mSafeMode || (p.info.applicationInfo.flags
8766                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8767                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8768                            ps.readUserState(userId), userId);
8769                    if (info != null) {
8770                        outNames.add(entry.getKey());
8771                        outInfo.add(info);
8772                    }
8773                }
8774            }
8775        }
8776    }
8777
8778    @Override
8779    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8780            int uid, int flags, String metaDataKey) {
8781        final int callingUid = Binder.getCallingUid();
8782        final int userId = processName != null ? UserHandle.getUserId(uid)
8783                : UserHandle.getCallingUserId();
8784        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8785        flags = updateFlagsForComponent(flags, userId, processName);
8786        ArrayList<ProviderInfo> finalList = null;
8787        // reader
8788        synchronized (mPackages) {
8789            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8790            while (i.hasNext()) {
8791                final PackageParser.Provider p = i.next();
8792                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8793                if (ps != null && p.info.authority != null
8794                        && (processName == null
8795                                || (p.info.processName.equals(processName)
8796                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8797                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8798
8799                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8800                    // parameter.
8801                    if (metaDataKey != null
8802                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8803                        continue;
8804                    }
8805                    final ComponentName component =
8806                            new ComponentName(p.info.packageName, p.info.name);
8807                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8808                        continue;
8809                    }
8810                    if (finalList == null) {
8811                        finalList = new ArrayList<ProviderInfo>(3);
8812                    }
8813                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8814                            ps.readUserState(userId), userId);
8815                    if (info != null) {
8816                        finalList.add(info);
8817                    }
8818                }
8819            }
8820        }
8821
8822        if (finalList != null) {
8823            Collections.sort(finalList, mProviderInitOrderSorter);
8824            return new ParceledListSlice<ProviderInfo>(finalList);
8825        }
8826
8827        return ParceledListSlice.emptyList();
8828    }
8829
8830    @Override
8831    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8832        // reader
8833        synchronized (mPackages) {
8834            final int callingUid = Binder.getCallingUid();
8835            final int callingUserId = UserHandle.getUserId(callingUid);
8836            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8837            if (ps == null) return null;
8838            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8839                return null;
8840            }
8841            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8842            return PackageParser.generateInstrumentationInfo(i, flags);
8843        }
8844    }
8845
8846    @Override
8847    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8848            String targetPackage, int flags) {
8849        final int callingUid = Binder.getCallingUid();
8850        final int callingUserId = UserHandle.getUserId(callingUid);
8851        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8852        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8853            return ParceledListSlice.emptyList();
8854        }
8855        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8856    }
8857
8858    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8859            int flags) {
8860        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8861
8862        // reader
8863        synchronized (mPackages) {
8864            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8865            while (i.hasNext()) {
8866                final PackageParser.Instrumentation p = i.next();
8867                if (targetPackage == null
8868                        || targetPackage.equals(p.info.targetPackage)) {
8869                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8870                            flags);
8871                    if (ii != null) {
8872                        finalList.add(ii);
8873                    }
8874                }
8875            }
8876        }
8877
8878        return finalList;
8879    }
8880
8881    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8882        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8883        try {
8884            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8885        } finally {
8886            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8887        }
8888    }
8889
8890    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8891        final File[] files = dir.listFiles();
8892        if (ArrayUtils.isEmpty(files)) {
8893            Log.d(TAG, "No files in app dir " + dir);
8894            return;
8895        }
8896
8897        if (DEBUG_PACKAGE_SCANNING) {
8898            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8899                    + " flags=0x" + Integer.toHexString(parseFlags));
8900        }
8901        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8902                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8903                mParallelPackageParserCallback);
8904
8905        // Submit files for parsing in parallel
8906        int fileCount = 0;
8907        for (File file : files) {
8908            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8909                    && !PackageInstallerService.isStageName(file.getName());
8910            if (!isPackage) {
8911                // Ignore entries which are not packages
8912                continue;
8913            }
8914            parallelPackageParser.submit(file, parseFlags);
8915            fileCount++;
8916        }
8917
8918        // Process results one by one
8919        for (; fileCount > 0; fileCount--) {
8920            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8921            Throwable throwable = parseResult.throwable;
8922            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8923
8924            if (throwable == null) {
8925                // Static shared libraries have synthetic package names
8926                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8927                    renameStaticSharedLibraryPackage(parseResult.pkg);
8928                }
8929                try {
8930                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8931                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8932                                currentTime, null);
8933                    }
8934                } catch (PackageManagerException e) {
8935                    errorCode = e.error;
8936                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8937                }
8938            } else if (throwable instanceof PackageParser.PackageParserException) {
8939                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8940                        throwable;
8941                errorCode = e.error;
8942                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8943            } else {
8944                throw new IllegalStateException("Unexpected exception occurred while parsing "
8945                        + parseResult.scanFile, throwable);
8946            }
8947
8948            // Delete invalid userdata apps
8949            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8950                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8951                logCriticalInfo(Log.WARN,
8952                        "Deleting invalid package at " + parseResult.scanFile);
8953                removeCodePathLI(parseResult.scanFile);
8954            }
8955        }
8956        parallelPackageParser.close();
8957    }
8958
8959    private static File getSettingsProblemFile() {
8960        File dataDir = Environment.getDataDirectory();
8961        File systemDir = new File(dataDir, "system");
8962        File fname = new File(systemDir, "uiderrors.txt");
8963        return fname;
8964    }
8965
8966    static void reportSettingsProblem(int priority, String msg) {
8967        logCriticalInfo(priority, msg);
8968    }
8969
8970    public static void logCriticalInfo(int priority, String msg) {
8971        Slog.println(priority, TAG, msg);
8972        EventLogTags.writePmCriticalInfo(msg);
8973        try {
8974            File fname = getSettingsProblemFile();
8975            FileOutputStream out = new FileOutputStream(fname, true);
8976            PrintWriter pw = new FastPrintWriter(out);
8977            SimpleDateFormat formatter = new SimpleDateFormat();
8978            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8979            pw.println(dateString + ": " + msg);
8980            pw.close();
8981            FileUtils.setPermissions(
8982                    fname.toString(),
8983                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8984                    -1, -1);
8985        } catch (java.io.IOException e) {
8986        }
8987    }
8988
8989    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8990        if (srcFile.isDirectory()) {
8991            final File baseFile = new File(pkg.baseCodePath);
8992            long maxModifiedTime = baseFile.lastModified();
8993            if (pkg.splitCodePaths != null) {
8994                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8995                    final File splitFile = new File(pkg.splitCodePaths[i]);
8996                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8997                }
8998            }
8999            return maxModifiedTime;
9000        }
9001        return srcFile.lastModified();
9002    }
9003
9004    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9005            final int policyFlags) throws PackageManagerException {
9006        // When upgrading from pre-N MR1, verify the package time stamp using the package
9007        // directory and not the APK file.
9008        final long lastModifiedTime = mIsPreNMR1Upgrade
9009                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9010        if (ps != null
9011                && ps.codePath.equals(srcFile)
9012                && ps.timeStamp == lastModifiedTime
9013                && !isCompatSignatureUpdateNeeded(pkg)
9014                && !isRecoverSignatureUpdateNeeded(pkg)) {
9015            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9016            KeySetManagerService ksms = mSettings.mKeySetManagerService;
9017            ArraySet<PublicKey> signingKs;
9018            synchronized (mPackages) {
9019                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9020            }
9021            if (ps.signatures.mSignatures != null
9022                    && ps.signatures.mSignatures.length != 0
9023                    && signingKs != null) {
9024                // Optimization: reuse the existing cached certificates
9025                // if the package appears to be unchanged.
9026                pkg.mSignatures = ps.signatures.mSignatures;
9027                pkg.mSigningKeys = signingKs;
9028                return;
9029            }
9030
9031            Slog.w(TAG, "PackageSetting for " + ps.name
9032                    + " is missing signatures.  Collecting certs again to recover them.");
9033        } else {
9034            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9035        }
9036
9037        try {
9038            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9039            PackageParser.collectCertificates(pkg, policyFlags);
9040        } catch (PackageParserException e) {
9041            throw PackageManagerException.from(e);
9042        } finally {
9043            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9044        }
9045    }
9046
9047    /**
9048     *  Traces a package scan.
9049     *  @see #scanPackageLI(File, int, int, long, UserHandle)
9050     */
9051    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9052            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9053        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9054        try {
9055            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9056        } finally {
9057            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9058        }
9059    }
9060
9061    /**
9062     *  Scans a package and returns the newly parsed package.
9063     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9064     */
9065    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9066            long currentTime, UserHandle user) throws PackageManagerException {
9067        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9068        PackageParser pp = new PackageParser();
9069        pp.setSeparateProcesses(mSeparateProcesses);
9070        pp.setOnlyCoreApps(mOnlyCore);
9071        pp.setDisplayMetrics(mMetrics);
9072        pp.setCallback(mPackageParserCallback);
9073
9074        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9075            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9076        }
9077
9078        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9079        final PackageParser.Package pkg;
9080        try {
9081            pkg = pp.parsePackage(scanFile, parseFlags);
9082        } catch (PackageParserException e) {
9083            throw PackageManagerException.from(e);
9084        } finally {
9085            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9086        }
9087
9088        // Static shared libraries have synthetic package names
9089        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9090            renameStaticSharedLibraryPackage(pkg);
9091        }
9092
9093        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9094    }
9095
9096    /**
9097     *  Scans a package and returns the newly parsed package.
9098     *  @throws PackageManagerException on a parse error.
9099     */
9100    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9101            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9102            throws PackageManagerException {
9103        // If the package has children and this is the first dive in the function
9104        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9105        // packages (parent and children) would be successfully scanned before the
9106        // actual scan since scanning mutates internal state and we want to atomically
9107        // install the package and its children.
9108        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9109            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9110                scanFlags |= SCAN_CHECK_ONLY;
9111            }
9112        } else {
9113            scanFlags &= ~SCAN_CHECK_ONLY;
9114        }
9115
9116        // Scan the parent
9117        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9118                scanFlags, currentTime, user);
9119
9120        // Scan the children
9121        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9122        for (int i = 0; i < childCount; i++) {
9123            PackageParser.Package childPackage = pkg.childPackages.get(i);
9124            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9125                    currentTime, user);
9126        }
9127
9128
9129        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9130            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9131        }
9132
9133        return scannedPkg;
9134    }
9135
9136    /**
9137     *  Scans a package and returns the newly parsed package.
9138     *  @throws PackageManagerException on a parse error.
9139     */
9140    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9141            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9142            throws PackageManagerException {
9143        PackageSetting ps = null;
9144        PackageSetting updatedPkg;
9145        // reader
9146        synchronized (mPackages) {
9147            // Look to see if we already know about this package.
9148            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9149            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9150                // This package has been renamed to its original name.  Let's
9151                // use that.
9152                ps = mSettings.getPackageLPr(oldName);
9153            }
9154            // If there was no original package, see one for the real package name.
9155            if (ps == null) {
9156                ps = mSettings.getPackageLPr(pkg.packageName);
9157            }
9158            // Check to see if this package could be hiding/updating a system
9159            // package.  Must look for it either under the original or real
9160            // package name depending on our state.
9161            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9162            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9163
9164            // If this is a package we don't know about on the system partition, we
9165            // may need to remove disabled child packages on the system partition
9166            // or may need to not add child packages if the parent apk is updated
9167            // on the data partition and no longer defines this child package.
9168            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9169                // If this is a parent package for an updated system app and this system
9170                // app got an OTA update which no longer defines some of the child packages
9171                // we have to prune them from the disabled system packages.
9172                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9173                if (disabledPs != null) {
9174                    final int scannedChildCount = (pkg.childPackages != null)
9175                            ? pkg.childPackages.size() : 0;
9176                    final int disabledChildCount = disabledPs.childPackageNames != null
9177                            ? disabledPs.childPackageNames.size() : 0;
9178                    for (int i = 0; i < disabledChildCount; i++) {
9179                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9180                        boolean disabledPackageAvailable = false;
9181                        for (int j = 0; j < scannedChildCount; j++) {
9182                            PackageParser.Package childPkg = pkg.childPackages.get(j);
9183                            if (childPkg.packageName.equals(disabledChildPackageName)) {
9184                                disabledPackageAvailable = true;
9185                                break;
9186                            }
9187                         }
9188                         if (!disabledPackageAvailable) {
9189                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9190                         }
9191                    }
9192                }
9193            }
9194        }
9195
9196        final boolean isUpdatedPkg = updatedPkg != null;
9197        final boolean isUpdatedSystemPkg = isUpdatedPkg
9198                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9199        boolean isUpdatedPkgBetter = false;
9200        // First check if this is a system package that may involve an update
9201        if (isUpdatedSystemPkg) {
9202            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9203            // it needs to drop FLAG_PRIVILEGED.
9204            if (locationIsPrivileged(scanFile)) {
9205                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9206            } else {
9207                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9208            }
9209
9210            if (ps != null && !ps.codePath.equals(scanFile)) {
9211                // The path has changed from what was last scanned...  check the
9212                // version of the new path against what we have stored to determine
9213                // what to do.
9214                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9215                if (pkg.mVersionCode <= ps.versionCode) {
9216                    // The system package has been updated and the code path does not match
9217                    // Ignore entry. Skip it.
9218                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9219                            + " ignored: updated version " + ps.versionCode
9220                            + " better than this " + pkg.mVersionCode);
9221                    if (!updatedPkg.codePath.equals(scanFile)) {
9222                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9223                                + ps.name + " changing from " + updatedPkg.codePathString
9224                                + " to " + scanFile);
9225                        updatedPkg.codePath = scanFile;
9226                        updatedPkg.codePathString = scanFile.toString();
9227                        updatedPkg.resourcePath = scanFile;
9228                        updatedPkg.resourcePathString = scanFile.toString();
9229                    }
9230                    updatedPkg.pkg = pkg;
9231                    updatedPkg.versionCode = pkg.mVersionCode;
9232
9233                    // Update the disabled system child packages to point to the package too.
9234                    final int childCount = updatedPkg.childPackageNames != null
9235                            ? updatedPkg.childPackageNames.size() : 0;
9236                    for (int i = 0; i < childCount; i++) {
9237                        String childPackageName = updatedPkg.childPackageNames.get(i);
9238                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9239                                childPackageName);
9240                        if (updatedChildPkg != null) {
9241                            updatedChildPkg.pkg = pkg;
9242                            updatedChildPkg.versionCode = pkg.mVersionCode;
9243                        }
9244                    }
9245                } else {
9246                    // The current app on the system partition is better than
9247                    // what we have updated to on the data partition; switch
9248                    // back to the system partition version.
9249                    // At this point, its safely assumed that package installation for
9250                    // apps in system partition will go through. If not there won't be a working
9251                    // version of the app
9252                    // writer
9253                    synchronized (mPackages) {
9254                        // Just remove the loaded entries from package lists.
9255                        mPackages.remove(ps.name);
9256                    }
9257
9258                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9259                            + " reverting from " + ps.codePathString
9260                            + ": new version " + pkg.mVersionCode
9261                            + " better than installed " + ps.versionCode);
9262
9263                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9264                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9265                    synchronized (mInstallLock) {
9266                        args.cleanUpResourcesLI();
9267                    }
9268                    synchronized (mPackages) {
9269                        mSettings.enableSystemPackageLPw(ps.name);
9270                    }
9271                    isUpdatedPkgBetter = true;
9272                }
9273            }
9274        }
9275
9276        String resourcePath = null;
9277        String baseResourcePath = null;
9278        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9279            if (ps != null && ps.resourcePathString != null) {
9280                resourcePath = ps.resourcePathString;
9281                baseResourcePath = ps.resourcePathString;
9282            } else {
9283                // Should not happen at all. Just log an error.
9284                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9285            }
9286        } else {
9287            resourcePath = pkg.codePath;
9288            baseResourcePath = pkg.baseCodePath;
9289        }
9290
9291        // Set application objects path explicitly.
9292        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9293        pkg.setApplicationInfoCodePath(pkg.codePath);
9294        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9295        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9296        pkg.setApplicationInfoResourcePath(resourcePath);
9297        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9298        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9299
9300        // throw an exception if we have an update to a system application, but, it's not more
9301        // recent than the package we've already scanned
9302        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9303            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9304                    + scanFile + " ignored: updated version " + ps.versionCode
9305                    + " better than this " + pkg.mVersionCode);
9306        }
9307
9308        if (isUpdatedPkg) {
9309            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9310            // initially
9311            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9312
9313            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9314            // flag set initially
9315            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9316                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9317            }
9318        }
9319
9320        // Verify certificates against what was last scanned
9321        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9322
9323        /*
9324         * A new system app appeared, but we already had a non-system one of the
9325         * same name installed earlier.
9326         */
9327        boolean shouldHideSystemApp = false;
9328        if (!isUpdatedPkg && ps != null
9329                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9330            /*
9331             * Check to make sure the signatures match first. If they don't,
9332             * wipe the installed application and its data.
9333             */
9334            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9335                    != PackageManager.SIGNATURE_MATCH) {
9336                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9337                        + " signatures don't match existing userdata copy; removing");
9338                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9339                        "scanPackageInternalLI")) {
9340                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9341                }
9342                ps = null;
9343            } else {
9344                /*
9345                 * If the newly-added system app is an older version than the
9346                 * already installed version, hide it. It will be scanned later
9347                 * and re-added like an update.
9348                 */
9349                if (pkg.mVersionCode <= ps.versionCode) {
9350                    shouldHideSystemApp = true;
9351                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9352                            + " but new version " + pkg.mVersionCode + " better than installed "
9353                            + ps.versionCode + "; hiding system");
9354                } else {
9355                    /*
9356                     * The newly found system app is a newer version that the
9357                     * one previously installed. Simply remove the
9358                     * already-installed application and replace it with our own
9359                     * while keeping the application data.
9360                     */
9361                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9362                            + " reverting from " + ps.codePathString + ": new version "
9363                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9364                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9365                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9366                    synchronized (mInstallLock) {
9367                        args.cleanUpResourcesLI();
9368                    }
9369                }
9370            }
9371        }
9372
9373        // The apk is forward locked (not public) if its code and resources
9374        // are kept in different files. (except for app in either system or
9375        // vendor path).
9376        // TODO grab this value from PackageSettings
9377        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9378            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9379                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9380            }
9381        }
9382
9383        final int userId = ((user == null) ? 0 : user.getIdentifier());
9384        if (ps != null && ps.getInstantApp(userId)) {
9385            scanFlags |= SCAN_AS_INSTANT_APP;
9386        }
9387
9388        // Note that we invoke the following method only if we are about to unpack an application
9389        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9390                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9391
9392        /*
9393         * If the system app should be overridden by a previously installed
9394         * data, hide the system app now and let the /data/app scan pick it up
9395         * again.
9396         */
9397        if (shouldHideSystemApp) {
9398            synchronized (mPackages) {
9399                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9400            }
9401        }
9402
9403        return scannedPkg;
9404    }
9405
9406    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9407        // Derive the new package synthetic package name
9408        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9409                + pkg.staticSharedLibVersion);
9410    }
9411
9412    private static String fixProcessName(String defProcessName,
9413            String processName) {
9414        if (processName == null) {
9415            return defProcessName;
9416        }
9417        return processName;
9418    }
9419
9420    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9421            throws PackageManagerException {
9422        if (pkgSetting.signatures.mSignatures != null) {
9423            // Already existing package. Make sure signatures match
9424            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9425                    == PackageManager.SIGNATURE_MATCH;
9426            if (!match) {
9427                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9428                        == PackageManager.SIGNATURE_MATCH;
9429            }
9430            if (!match) {
9431                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9432                        == PackageManager.SIGNATURE_MATCH;
9433            }
9434            if (!match) {
9435                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9436                        + pkg.packageName + " signatures do not match the "
9437                        + "previously installed version; ignoring!");
9438            }
9439        }
9440
9441        // Check for shared user signatures
9442        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9443            // Already existing package. Make sure signatures match
9444            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9445                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9446            if (!match) {
9447                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9448                        == PackageManager.SIGNATURE_MATCH;
9449            }
9450            if (!match) {
9451                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9452                        == PackageManager.SIGNATURE_MATCH;
9453            }
9454            if (!match) {
9455                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9456                        "Package " + pkg.packageName
9457                        + " has no signatures that match those in shared user "
9458                        + pkgSetting.sharedUser.name + "; ignoring!");
9459            }
9460        }
9461    }
9462
9463    /**
9464     * Enforces that only the system UID or root's UID can call a method exposed
9465     * via Binder.
9466     *
9467     * @param message used as message if SecurityException is thrown
9468     * @throws SecurityException if the caller is not system or root
9469     */
9470    private static final void enforceSystemOrRoot(String message) {
9471        final int uid = Binder.getCallingUid();
9472        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9473            throw new SecurityException(message);
9474        }
9475    }
9476
9477    @Override
9478    public void performFstrimIfNeeded() {
9479        enforceSystemOrRoot("Only the system can request fstrim");
9480
9481        // Before everything else, see whether we need to fstrim.
9482        try {
9483            IStorageManager sm = PackageHelper.getStorageManager();
9484            if (sm != null) {
9485                boolean doTrim = false;
9486                final long interval = android.provider.Settings.Global.getLong(
9487                        mContext.getContentResolver(),
9488                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9489                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9490                if (interval > 0) {
9491                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9492                    if (timeSinceLast > interval) {
9493                        doTrim = true;
9494                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9495                                + "; running immediately");
9496                    }
9497                }
9498                if (doTrim) {
9499                    final boolean dexOptDialogShown;
9500                    synchronized (mPackages) {
9501                        dexOptDialogShown = mDexOptDialogShown;
9502                    }
9503                    if (!isFirstBoot() && dexOptDialogShown) {
9504                        try {
9505                            ActivityManager.getService().showBootMessage(
9506                                    mContext.getResources().getString(
9507                                            R.string.android_upgrading_fstrim), true);
9508                        } catch (RemoteException e) {
9509                        }
9510                    }
9511                    sm.runMaintenance();
9512                }
9513            } else {
9514                Slog.e(TAG, "storageManager service unavailable!");
9515            }
9516        } catch (RemoteException e) {
9517            // Can't happen; StorageManagerService is local
9518        }
9519    }
9520
9521    @Override
9522    public void updatePackagesIfNeeded() {
9523        enforceSystemOrRoot("Only the system can request package update");
9524
9525        // We need to re-extract after an OTA.
9526        boolean causeUpgrade = isUpgrade();
9527
9528        // First boot or factory reset.
9529        // Note: we also handle devices that are upgrading to N right now as if it is their
9530        //       first boot, as they do not have profile data.
9531        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9532
9533        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9534        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9535
9536        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9537            return;
9538        }
9539
9540        List<PackageParser.Package> pkgs;
9541        synchronized (mPackages) {
9542            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9543        }
9544
9545        final long startTime = System.nanoTime();
9546        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9547                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9548                    false /* bootComplete */);
9549
9550        final int elapsedTimeSeconds =
9551                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9552
9553        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9554        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9555        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9556        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9557        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9558    }
9559
9560    /*
9561     * Return the prebuilt profile path given a package base code path.
9562     */
9563    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9564        return pkg.baseCodePath + ".prof";
9565    }
9566
9567    /**
9568     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9569     * containing statistics about the invocation. The array consists of three elements,
9570     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9571     * and {@code numberOfPackagesFailed}.
9572     */
9573    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9574            String compilerFilter, boolean bootComplete) {
9575
9576        int numberOfPackagesVisited = 0;
9577        int numberOfPackagesOptimized = 0;
9578        int numberOfPackagesSkipped = 0;
9579        int numberOfPackagesFailed = 0;
9580        final int numberOfPackagesToDexopt = pkgs.size();
9581
9582        for (PackageParser.Package pkg : pkgs) {
9583            numberOfPackagesVisited++;
9584
9585            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9586                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9587                // that are already compiled.
9588                File profileFile = new File(getPrebuildProfilePath(pkg));
9589                // Copy profile if it exists.
9590                if (profileFile.exists()) {
9591                    try {
9592                        // We could also do this lazily before calling dexopt in
9593                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9594                        // is that we don't have a good way to say "do this only once".
9595                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9596                                pkg.applicationInfo.uid, pkg.packageName)) {
9597                            Log.e(TAG, "Installer failed to copy system profile!");
9598                        }
9599                    } catch (Exception e) {
9600                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9601                                e);
9602                    }
9603                }
9604            }
9605
9606            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9607                if (DEBUG_DEXOPT) {
9608                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9609                }
9610                numberOfPackagesSkipped++;
9611                continue;
9612            }
9613
9614            if (DEBUG_DEXOPT) {
9615                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9616                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9617            }
9618
9619            if (showDialog) {
9620                try {
9621                    ActivityManager.getService().showBootMessage(
9622                            mContext.getResources().getString(R.string.android_upgrading_apk,
9623                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9624                } catch (RemoteException e) {
9625                }
9626                synchronized (mPackages) {
9627                    mDexOptDialogShown = true;
9628                }
9629            }
9630
9631            // If the OTA updates a system app which was previously preopted to a non-preopted state
9632            // the app might end up being verified at runtime. That's because by default the apps
9633            // are verify-profile but for preopted apps there's no profile.
9634            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
9635            // that before the OTA the app was preopted) the app gets compiled with a non-profile
9636            // filter (by default 'quicken').
9637            // Note that at this stage unused apps are already filtered.
9638            if (isSystemApp(pkg) &&
9639                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
9640                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
9641                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
9642            }
9643
9644            // checkProfiles is false to avoid merging profiles during boot which
9645            // might interfere with background compilation (b/28612421).
9646            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9647            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9648            // trade-off worth doing to save boot time work.
9649            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9650            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9651                    pkg.packageName,
9652                    compilerFilter,
9653                    dexoptFlags));
9654
9655            if (pkg.isSystemApp()) {
9656                // Only dexopt shared secondary dex files belonging to system apps to not slow down
9657                // too much boot after an OTA.
9658                int secondaryDexoptFlags = dexoptFlags |
9659                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9660                        DexoptOptions.DEXOPT_ONLY_SHARED_DEX;
9661                mDexManager.dexoptSecondaryDex(new DexoptOptions(
9662                        pkg.packageName,
9663                        compilerFilter,
9664                        secondaryDexoptFlags));
9665            }
9666
9667            // TODO(shubhamajmera): Record secondary dexopt stats.
9668            switch (primaryDexOptStaus) {
9669                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9670                    numberOfPackagesOptimized++;
9671                    break;
9672                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9673                    numberOfPackagesSkipped++;
9674                    break;
9675                case PackageDexOptimizer.DEX_OPT_FAILED:
9676                    numberOfPackagesFailed++;
9677                    break;
9678                default:
9679                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9680                    break;
9681            }
9682        }
9683
9684        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9685                numberOfPackagesFailed };
9686    }
9687
9688    @Override
9689    public void notifyPackageUse(String packageName, int reason) {
9690        synchronized (mPackages) {
9691            final int callingUid = Binder.getCallingUid();
9692            final int callingUserId = UserHandle.getUserId(callingUid);
9693            if (getInstantAppPackageName(callingUid) != null) {
9694                if (!isCallerSameApp(packageName, callingUid)) {
9695                    return;
9696                }
9697            } else {
9698                if (isInstantApp(packageName, callingUserId)) {
9699                    return;
9700                }
9701            }
9702            final PackageParser.Package p = mPackages.get(packageName);
9703            if (p == null) {
9704                return;
9705            }
9706            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9707        }
9708    }
9709
9710    @Override
9711    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
9712        int userId = UserHandle.getCallingUserId();
9713        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9714        if (ai == null) {
9715            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9716                + loadingPackageName + ", user=" + userId);
9717            return;
9718        }
9719        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
9720    }
9721
9722    @Override
9723    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9724            IDexModuleRegisterCallback callback) {
9725        int userId = UserHandle.getCallingUserId();
9726        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9727        DexManager.RegisterDexModuleResult result;
9728        if (ai == null) {
9729            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9730                     " calling user. package=" + packageName + ", user=" + userId);
9731            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9732        } else {
9733            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9734        }
9735
9736        if (callback != null) {
9737            mHandler.post(() -> {
9738                try {
9739                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9740                } catch (RemoteException e) {
9741                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9742                }
9743            });
9744        }
9745    }
9746
9747    /**
9748     * Ask the package manager to perform a dex-opt with the given compiler filter.
9749     *
9750     * Note: exposed only for the shell command to allow moving packages explicitly to a
9751     *       definite state.
9752     */
9753    @Override
9754    public boolean performDexOptMode(String packageName,
9755            boolean checkProfiles, String targetCompilerFilter, boolean force,
9756            boolean bootComplete, String splitName) {
9757        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9758                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9759                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9760        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
9761                splitName, flags));
9762    }
9763
9764    /**
9765     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9766     * secondary dex files belonging to the given package.
9767     *
9768     * Note: exposed only for the shell command to allow moving packages explicitly to a
9769     *       definite state.
9770     */
9771    @Override
9772    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9773            boolean force) {
9774        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9775                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9776                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9777                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9778        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9779    }
9780
9781    /*package*/ boolean performDexOpt(DexoptOptions options) {
9782        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9783            return false;
9784        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9785            return false;
9786        }
9787
9788        if (options.isDexoptOnlySecondaryDex()) {
9789            return mDexManager.dexoptSecondaryDex(options);
9790        } else {
9791            int dexoptStatus = performDexOptWithStatus(options);
9792            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9793        }
9794    }
9795
9796    /**
9797     * Perform dexopt on the given package and return one of following result:
9798     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9799     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9800     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9801     */
9802    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9803        return performDexOptTraced(options);
9804    }
9805
9806    private int performDexOptTraced(DexoptOptions options) {
9807        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9808        try {
9809            return performDexOptInternal(options);
9810        } finally {
9811            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9812        }
9813    }
9814
9815    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9816    // if the package can now be considered up to date for the given filter.
9817    private int performDexOptInternal(DexoptOptions options) {
9818        PackageParser.Package p;
9819        synchronized (mPackages) {
9820            p = mPackages.get(options.getPackageName());
9821            if (p == null) {
9822                // Package could not be found. Report failure.
9823                return PackageDexOptimizer.DEX_OPT_FAILED;
9824            }
9825            mPackageUsage.maybeWriteAsync(mPackages);
9826            mCompilerStats.maybeWriteAsync();
9827        }
9828        long callingId = Binder.clearCallingIdentity();
9829        try {
9830            synchronized (mInstallLock) {
9831                return performDexOptInternalWithDependenciesLI(p, options);
9832            }
9833        } finally {
9834            Binder.restoreCallingIdentity(callingId);
9835        }
9836    }
9837
9838    public ArraySet<String> getOptimizablePackages() {
9839        ArraySet<String> pkgs = new ArraySet<String>();
9840        synchronized (mPackages) {
9841            for (PackageParser.Package p : mPackages.values()) {
9842                if (PackageDexOptimizer.canOptimizePackage(p)) {
9843                    pkgs.add(p.packageName);
9844                }
9845            }
9846        }
9847        return pkgs;
9848    }
9849
9850    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9851            DexoptOptions options) {
9852        // Select the dex optimizer based on the force parameter.
9853        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9854        //       allocate an object here.
9855        PackageDexOptimizer pdo = options.isForce()
9856                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9857                : mPackageDexOptimizer;
9858
9859        // Dexopt all dependencies first. Note: we ignore the return value and march on
9860        // on errors.
9861        // Note that we are going to call performDexOpt on those libraries as many times as
9862        // they are referenced in packages. When we do a batch of performDexOpt (for example
9863        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9864        // and the first package that uses the library will dexopt it. The
9865        // others will see that the compiled code for the library is up to date.
9866        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9867        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9868        if (!deps.isEmpty()) {
9869            for (PackageParser.Package depPackage : deps) {
9870                // TODO: Analyze and investigate if we (should) profile libraries.
9871                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9872                        getOrCreateCompilerPackageStats(depPackage),
9873                        true /* isUsedByOtherApps */,
9874                        options);
9875            }
9876        }
9877        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9878                getOrCreateCompilerPackageStats(p),
9879                mDexManager.isUsedByOtherApps(p.packageName), options);
9880    }
9881
9882    /**
9883     * Reconcile the information we have about the secondary dex files belonging to
9884     * {@code packagName} and the actual dex files. For all dex files that were
9885     * deleted, update the internal records and delete the generated oat files.
9886     */
9887    @Override
9888    public void reconcileSecondaryDexFiles(String packageName) {
9889        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9890            return;
9891        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9892            return;
9893        }
9894        mDexManager.reconcileSecondaryDexFiles(packageName);
9895    }
9896
9897    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9898    // a reference there.
9899    /*package*/ DexManager getDexManager() {
9900        return mDexManager;
9901    }
9902
9903    /**
9904     * Execute the background dexopt job immediately.
9905     */
9906    @Override
9907    public boolean runBackgroundDexoptJob() {
9908        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9909            return false;
9910        }
9911        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9912    }
9913
9914    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9915        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9916                || p.usesStaticLibraries != null) {
9917            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9918            Set<String> collectedNames = new HashSet<>();
9919            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9920
9921            retValue.remove(p);
9922
9923            return retValue;
9924        } else {
9925            return Collections.emptyList();
9926        }
9927    }
9928
9929    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9930            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9931        if (!collectedNames.contains(p.packageName)) {
9932            collectedNames.add(p.packageName);
9933            collected.add(p);
9934
9935            if (p.usesLibraries != null) {
9936                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9937                        null, collected, collectedNames);
9938            }
9939            if (p.usesOptionalLibraries != null) {
9940                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9941                        null, collected, collectedNames);
9942            }
9943            if (p.usesStaticLibraries != null) {
9944                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9945                        p.usesStaticLibrariesVersions, collected, collectedNames);
9946            }
9947        }
9948    }
9949
9950    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9951            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9952        final int libNameCount = libs.size();
9953        for (int i = 0; i < libNameCount; i++) {
9954            String libName = libs.get(i);
9955            int version = (versions != null && versions.length == libNameCount)
9956                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9957            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9958            if (libPkg != null) {
9959                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9960            }
9961        }
9962    }
9963
9964    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9965        synchronized (mPackages) {
9966            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9967            if (libEntry != null) {
9968                return mPackages.get(libEntry.apk);
9969            }
9970            return null;
9971        }
9972    }
9973
9974    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9975        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9976        if (versionedLib == null) {
9977            return null;
9978        }
9979        return versionedLib.get(version);
9980    }
9981
9982    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9983        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9984                pkg.staticSharedLibName);
9985        if (versionedLib == null) {
9986            return null;
9987        }
9988        int previousLibVersion = -1;
9989        final int versionCount = versionedLib.size();
9990        for (int i = 0; i < versionCount; i++) {
9991            final int libVersion = versionedLib.keyAt(i);
9992            if (libVersion < pkg.staticSharedLibVersion) {
9993                previousLibVersion = Math.max(previousLibVersion, libVersion);
9994            }
9995        }
9996        if (previousLibVersion >= 0) {
9997            return versionedLib.get(previousLibVersion);
9998        }
9999        return null;
10000    }
10001
10002    public void shutdown() {
10003        mPackageUsage.writeNow(mPackages);
10004        mCompilerStats.writeNow();
10005    }
10006
10007    @Override
10008    public void dumpProfiles(String packageName) {
10009        PackageParser.Package pkg;
10010        synchronized (mPackages) {
10011            pkg = mPackages.get(packageName);
10012            if (pkg == null) {
10013                throw new IllegalArgumentException("Unknown package: " + packageName);
10014            }
10015        }
10016        /* Only the shell, root, or the app user should be able to dump profiles. */
10017        int callingUid = Binder.getCallingUid();
10018        if (callingUid != Process.SHELL_UID &&
10019            callingUid != Process.ROOT_UID &&
10020            callingUid != pkg.applicationInfo.uid) {
10021            throw new SecurityException("dumpProfiles");
10022        }
10023
10024        synchronized (mInstallLock) {
10025            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10026            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10027            try {
10028                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10029                String codePaths = TextUtils.join(";", allCodePaths);
10030                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10031            } catch (InstallerException e) {
10032                Slog.w(TAG, "Failed to dump profiles", e);
10033            }
10034            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10035        }
10036    }
10037
10038    @Override
10039    public void forceDexOpt(String packageName) {
10040        enforceSystemOrRoot("forceDexOpt");
10041
10042        PackageParser.Package pkg;
10043        synchronized (mPackages) {
10044            pkg = mPackages.get(packageName);
10045            if (pkg == null) {
10046                throw new IllegalArgumentException("Unknown package: " + packageName);
10047            }
10048        }
10049
10050        synchronized (mInstallLock) {
10051            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10052
10053            // Whoever is calling forceDexOpt wants a compiled package.
10054            // Don't use profiles since that may cause compilation to be skipped.
10055            final int res = performDexOptInternalWithDependenciesLI(
10056                    pkg,
10057                    new DexoptOptions(packageName,
10058                            getDefaultCompilerFilter(),
10059                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10060
10061            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10062            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10063                throw new IllegalStateException("Failed to dexopt: " + res);
10064            }
10065        }
10066    }
10067
10068    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10069        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10070            Slog.w(TAG, "Unable to update from " + oldPkg.name
10071                    + " to " + newPkg.packageName
10072                    + ": old package not in system partition");
10073            return false;
10074        } else if (mPackages.get(oldPkg.name) != null) {
10075            Slog.w(TAG, "Unable to update from " + oldPkg.name
10076                    + " to " + newPkg.packageName
10077                    + ": old package still exists");
10078            return false;
10079        }
10080        return true;
10081    }
10082
10083    void removeCodePathLI(File codePath) {
10084        if (codePath.isDirectory()) {
10085            try {
10086                mInstaller.rmPackageDir(codePath.getAbsolutePath());
10087            } catch (InstallerException e) {
10088                Slog.w(TAG, "Failed to remove code path", e);
10089            }
10090        } else {
10091            codePath.delete();
10092        }
10093    }
10094
10095    private int[] resolveUserIds(int userId) {
10096        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10097    }
10098
10099    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10100        if (pkg == null) {
10101            Slog.wtf(TAG, "Package was null!", new Throwable());
10102            return;
10103        }
10104        clearAppDataLeafLIF(pkg, userId, flags);
10105        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10106        for (int i = 0; i < childCount; i++) {
10107            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10108        }
10109    }
10110
10111    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10112        final PackageSetting ps;
10113        synchronized (mPackages) {
10114            ps = mSettings.mPackages.get(pkg.packageName);
10115        }
10116        for (int realUserId : resolveUserIds(userId)) {
10117            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10118            try {
10119                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10120                        ceDataInode);
10121            } catch (InstallerException e) {
10122                Slog.w(TAG, String.valueOf(e));
10123            }
10124        }
10125    }
10126
10127    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10128        if (pkg == null) {
10129            Slog.wtf(TAG, "Package was null!", new Throwable());
10130            return;
10131        }
10132        destroyAppDataLeafLIF(pkg, userId, flags);
10133        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10134        for (int i = 0; i < childCount; i++) {
10135            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10136        }
10137    }
10138
10139    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10140        final PackageSetting ps;
10141        synchronized (mPackages) {
10142            ps = mSettings.mPackages.get(pkg.packageName);
10143        }
10144        for (int realUserId : resolveUserIds(userId)) {
10145            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10146            try {
10147                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10148                        ceDataInode);
10149            } catch (InstallerException e) {
10150                Slog.w(TAG, String.valueOf(e));
10151            }
10152            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10153        }
10154    }
10155
10156    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10157        if (pkg == null) {
10158            Slog.wtf(TAG, "Package was null!", new Throwable());
10159            return;
10160        }
10161        destroyAppProfilesLeafLIF(pkg);
10162        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10163        for (int i = 0; i < childCount; i++) {
10164            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10165        }
10166    }
10167
10168    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10169        try {
10170            mInstaller.destroyAppProfiles(pkg.packageName);
10171        } catch (InstallerException e) {
10172            Slog.w(TAG, String.valueOf(e));
10173        }
10174    }
10175
10176    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10177        if (pkg == null) {
10178            Slog.wtf(TAG, "Package was null!", new Throwable());
10179            return;
10180        }
10181        clearAppProfilesLeafLIF(pkg);
10182        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10183        for (int i = 0; i < childCount; i++) {
10184            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10185        }
10186    }
10187
10188    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10189        try {
10190            mInstaller.clearAppProfiles(pkg.packageName);
10191        } catch (InstallerException e) {
10192            Slog.w(TAG, String.valueOf(e));
10193        }
10194    }
10195
10196    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10197            long lastUpdateTime) {
10198        // Set parent install/update time
10199        PackageSetting ps = (PackageSetting) pkg.mExtras;
10200        if (ps != null) {
10201            ps.firstInstallTime = firstInstallTime;
10202            ps.lastUpdateTime = lastUpdateTime;
10203        }
10204        // Set children install/update time
10205        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10206        for (int i = 0; i < childCount; i++) {
10207            PackageParser.Package childPkg = pkg.childPackages.get(i);
10208            ps = (PackageSetting) childPkg.mExtras;
10209            if (ps != null) {
10210                ps.firstInstallTime = firstInstallTime;
10211                ps.lastUpdateTime = lastUpdateTime;
10212            }
10213        }
10214    }
10215
10216    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10217            PackageParser.Package changingLib) {
10218        if (file.path != null) {
10219            usesLibraryFiles.add(file.path);
10220            return;
10221        }
10222        PackageParser.Package p = mPackages.get(file.apk);
10223        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10224            // If we are doing this while in the middle of updating a library apk,
10225            // then we need to make sure to use that new apk for determining the
10226            // dependencies here.  (We haven't yet finished committing the new apk
10227            // to the package manager state.)
10228            if (p == null || p.packageName.equals(changingLib.packageName)) {
10229                p = changingLib;
10230            }
10231        }
10232        if (p != null) {
10233            usesLibraryFiles.addAll(p.getAllCodePaths());
10234            if (p.usesLibraryFiles != null) {
10235                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10236            }
10237        }
10238    }
10239
10240    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10241            PackageParser.Package changingLib) throws PackageManagerException {
10242        if (pkg == null) {
10243            return;
10244        }
10245        ArraySet<String> usesLibraryFiles = null;
10246        if (pkg.usesLibraries != null) {
10247            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10248                    null, null, pkg.packageName, changingLib, true, null);
10249        }
10250        if (pkg.usesStaticLibraries != null) {
10251            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10252                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10253                    pkg.packageName, changingLib, true, usesLibraryFiles);
10254        }
10255        if (pkg.usesOptionalLibraries != null) {
10256            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10257                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
10258        }
10259        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10260            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10261        } else {
10262            pkg.usesLibraryFiles = null;
10263        }
10264    }
10265
10266    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10267            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
10268            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10269            boolean required, @Nullable ArraySet<String> outUsedLibraries)
10270            throws PackageManagerException {
10271        final int libCount = requestedLibraries.size();
10272        for (int i = 0; i < libCount; i++) {
10273            final String libName = requestedLibraries.get(i);
10274            final int libVersion = requiredVersions != null ? requiredVersions[i]
10275                    : SharedLibraryInfo.VERSION_UNDEFINED;
10276            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10277            if (libEntry == null) {
10278                if (required) {
10279                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10280                            "Package " + packageName + " requires unavailable shared library "
10281                                    + libName + "; failing!");
10282                } else if (DEBUG_SHARED_LIBRARIES) {
10283                    Slog.i(TAG, "Package " + packageName
10284                            + " desires unavailable shared library "
10285                            + libName + "; ignoring!");
10286                }
10287            } else {
10288                if (requiredVersions != null && requiredCertDigests != null) {
10289                    if (libEntry.info.getVersion() != requiredVersions[i]) {
10290                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10291                            "Package " + packageName + " requires unavailable static shared"
10292                                    + " library " + libName + " version "
10293                                    + libEntry.info.getVersion() + "; failing!");
10294                    }
10295
10296                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10297                    if (libPkg == null) {
10298                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10299                                "Package " + packageName + " requires unavailable static shared"
10300                                        + " library; failing!");
10301                    }
10302
10303                    String expectedCertDigest = requiredCertDigests[i];
10304                    String libCertDigest = PackageUtils.computeCertSha256Digest(
10305                                libPkg.mSignatures[0]);
10306                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
10307                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10308                                "Package " + packageName + " requires differently signed" +
10309                                        " static shared library; failing!");
10310                    }
10311                }
10312
10313                if (outUsedLibraries == null) {
10314                    outUsedLibraries = new ArraySet<>();
10315                }
10316                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10317            }
10318        }
10319        return outUsedLibraries;
10320    }
10321
10322    private static boolean hasString(List<String> list, List<String> which) {
10323        if (list == null) {
10324            return false;
10325        }
10326        for (int i=list.size()-1; i>=0; i--) {
10327            for (int j=which.size()-1; j>=0; j--) {
10328                if (which.get(j).equals(list.get(i))) {
10329                    return true;
10330                }
10331            }
10332        }
10333        return false;
10334    }
10335
10336    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10337            PackageParser.Package changingPkg) {
10338        ArrayList<PackageParser.Package> res = null;
10339        for (PackageParser.Package pkg : mPackages.values()) {
10340            if (changingPkg != null
10341                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10342                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10343                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10344                            changingPkg.staticSharedLibName)) {
10345                return null;
10346            }
10347            if (res == null) {
10348                res = new ArrayList<>();
10349            }
10350            res.add(pkg);
10351            try {
10352                updateSharedLibrariesLPr(pkg, changingPkg);
10353            } catch (PackageManagerException e) {
10354                // If a system app update or an app and a required lib missing we
10355                // delete the package and for updated system apps keep the data as
10356                // it is better for the user to reinstall than to be in an limbo
10357                // state. Also libs disappearing under an app should never happen
10358                // - just in case.
10359                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10360                    final int flags = pkg.isUpdatedSystemApp()
10361                            ? PackageManager.DELETE_KEEP_DATA : 0;
10362                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10363                            flags , null, true, null);
10364                }
10365                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10366            }
10367        }
10368        return res;
10369    }
10370
10371    /**
10372     * Derive the value of the {@code cpuAbiOverride} based on the provided
10373     * value and an optional stored value from the package settings.
10374     */
10375    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10376        String cpuAbiOverride = null;
10377
10378        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10379            cpuAbiOverride = null;
10380        } else if (abiOverride != null) {
10381            cpuAbiOverride = abiOverride;
10382        } else if (settings != null) {
10383            cpuAbiOverride = settings.cpuAbiOverrideString;
10384        }
10385
10386        return cpuAbiOverride;
10387    }
10388
10389    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10390            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10391                    throws PackageManagerException {
10392        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10393        // If the package has children and this is the first dive in the function
10394        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10395        // whether all packages (parent and children) would be successfully scanned
10396        // before the actual scan since scanning mutates internal state and we want
10397        // to atomically install the package and its children.
10398        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10399            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10400                scanFlags |= SCAN_CHECK_ONLY;
10401            }
10402        } else {
10403            scanFlags &= ~SCAN_CHECK_ONLY;
10404        }
10405
10406        final PackageParser.Package scannedPkg;
10407        try {
10408            // Scan the parent
10409            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10410            // Scan the children
10411            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10412            for (int i = 0; i < childCount; i++) {
10413                PackageParser.Package childPkg = pkg.childPackages.get(i);
10414                scanPackageLI(childPkg, policyFlags,
10415                        scanFlags, currentTime, user);
10416            }
10417        } finally {
10418            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10419        }
10420
10421        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10422            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10423        }
10424
10425        return scannedPkg;
10426    }
10427
10428    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10429            int scanFlags, long currentTime, @Nullable UserHandle user)
10430                    throws PackageManagerException {
10431        boolean success = false;
10432        try {
10433            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10434                    currentTime, user);
10435            success = true;
10436            return res;
10437        } finally {
10438            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10439                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10440                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10441                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10442                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10443            }
10444        }
10445    }
10446
10447    /**
10448     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10449     */
10450    private static boolean apkHasCode(String fileName) {
10451        StrictJarFile jarFile = null;
10452        try {
10453            jarFile = new StrictJarFile(fileName,
10454                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10455            return jarFile.findEntry("classes.dex") != null;
10456        } catch (IOException ignore) {
10457        } finally {
10458            try {
10459                if (jarFile != null) {
10460                    jarFile.close();
10461                }
10462            } catch (IOException ignore) {}
10463        }
10464        return false;
10465    }
10466
10467    /**
10468     * Enforces code policy for the package. This ensures that if an APK has
10469     * declared hasCode="true" in its manifest that the APK actually contains
10470     * code.
10471     *
10472     * @throws PackageManagerException If bytecode could not be found when it should exist
10473     */
10474    private static void assertCodePolicy(PackageParser.Package pkg)
10475            throws PackageManagerException {
10476        final boolean shouldHaveCode =
10477                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10478        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10479            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10480                    "Package " + pkg.baseCodePath + " code is missing");
10481        }
10482
10483        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10484            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10485                final boolean splitShouldHaveCode =
10486                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10487                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10488                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10489                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10490                }
10491            }
10492        }
10493    }
10494
10495    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10496            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10497                    throws PackageManagerException {
10498        if (DEBUG_PACKAGE_SCANNING) {
10499            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10500                Log.d(TAG, "Scanning package " + pkg.packageName);
10501        }
10502
10503        applyPolicy(pkg, policyFlags);
10504
10505        assertPackageIsValid(pkg, policyFlags, scanFlags);
10506
10507        // Initialize package source and resource directories
10508        final File scanFile = new File(pkg.codePath);
10509        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10510        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10511
10512        SharedUserSetting suid = null;
10513        PackageSetting pkgSetting = null;
10514
10515        // Getting the package setting may have a side-effect, so if we
10516        // are only checking if scan would succeed, stash a copy of the
10517        // old setting to restore at the end.
10518        PackageSetting nonMutatedPs = null;
10519
10520        // We keep references to the derived CPU Abis from settings in oder to reuse
10521        // them in the case where we're not upgrading or booting for the first time.
10522        String primaryCpuAbiFromSettings = null;
10523        String secondaryCpuAbiFromSettings = null;
10524
10525        // writer
10526        synchronized (mPackages) {
10527            if (pkg.mSharedUserId != null) {
10528                // SIDE EFFECTS; may potentially allocate a new shared user
10529                suid = mSettings.getSharedUserLPw(
10530                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10531                if (DEBUG_PACKAGE_SCANNING) {
10532                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10533                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10534                                + "): packages=" + suid.packages);
10535                }
10536            }
10537
10538            // Check if we are renaming from an original package name.
10539            PackageSetting origPackage = null;
10540            String realName = null;
10541            if (pkg.mOriginalPackages != null) {
10542                // This package may need to be renamed to a previously
10543                // installed name.  Let's check on that...
10544                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10545                if (pkg.mOriginalPackages.contains(renamed)) {
10546                    // This package had originally been installed as the
10547                    // original name, and we have already taken care of
10548                    // transitioning to the new one.  Just update the new
10549                    // one to continue using the old name.
10550                    realName = pkg.mRealPackage;
10551                    if (!pkg.packageName.equals(renamed)) {
10552                        // Callers into this function may have already taken
10553                        // care of renaming the package; only do it here if
10554                        // it is not already done.
10555                        pkg.setPackageName(renamed);
10556                    }
10557                } else {
10558                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10559                        if ((origPackage = mSettings.getPackageLPr(
10560                                pkg.mOriginalPackages.get(i))) != null) {
10561                            // We do have the package already installed under its
10562                            // original name...  should we use it?
10563                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10564                                // New package is not compatible with original.
10565                                origPackage = null;
10566                                continue;
10567                            } else if (origPackage.sharedUser != null) {
10568                                // Make sure uid is compatible between packages.
10569                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10570                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10571                                            + " to " + pkg.packageName + ": old uid "
10572                                            + origPackage.sharedUser.name
10573                                            + " differs from " + pkg.mSharedUserId);
10574                                    origPackage = null;
10575                                    continue;
10576                                }
10577                                // TODO: Add case when shared user id is added [b/28144775]
10578                            } else {
10579                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10580                                        + pkg.packageName + " to old name " + origPackage.name);
10581                            }
10582                            break;
10583                        }
10584                    }
10585                }
10586            }
10587
10588            if (mTransferedPackages.contains(pkg.packageName)) {
10589                Slog.w(TAG, "Package " + pkg.packageName
10590                        + " was transferred to another, but its .apk remains");
10591            }
10592
10593            // See comments in nonMutatedPs declaration
10594            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10595                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10596                if (foundPs != null) {
10597                    nonMutatedPs = new PackageSetting(foundPs);
10598                }
10599            }
10600
10601            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10602                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10603                if (foundPs != null) {
10604                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10605                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10606                }
10607            }
10608
10609            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10610            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10611                PackageManagerService.reportSettingsProblem(Log.WARN,
10612                        "Package " + pkg.packageName + " shared user changed from "
10613                                + (pkgSetting.sharedUser != null
10614                                        ? pkgSetting.sharedUser.name : "<nothing>")
10615                                + " to "
10616                                + (suid != null ? suid.name : "<nothing>")
10617                                + "; replacing with new");
10618                pkgSetting = null;
10619            }
10620            final PackageSetting oldPkgSetting =
10621                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10622            final PackageSetting disabledPkgSetting =
10623                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10624
10625            String[] usesStaticLibraries = null;
10626            if (pkg.usesStaticLibraries != null) {
10627                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10628                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10629            }
10630
10631            if (pkgSetting == null) {
10632                final String parentPackageName = (pkg.parentPackage != null)
10633                        ? pkg.parentPackage.packageName : null;
10634                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10635                // REMOVE SharedUserSetting from method; update in a separate call
10636                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10637                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10638                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10639                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10640                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10641                        true /*allowInstall*/, instantApp, parentPackageName,
10642                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
10643                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10644                // SIDE EFFECTS; updates system state; move elsewhere
10645                if (origPackage != null) {
10646                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10647                }
10648                mSettings.addUserToSettingLPw(pkgSetting);
10649            } else {
10650                // REMOVE SharedUserSetting from method; update in a separate call.
10651                //
10652                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10653                // secondaryCpuAbi are not known at this point so we always update them
10654                // to null here, only to reset them at a later point.
10655                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10656                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10657                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10658                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10659                        UserManagerService.getInstance(), usesStaticLibraries,
10660                        pkg.usesStaticLibrariesVersions);
10661            }
10662            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10663            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10664
10665            // SIDE EFFECTS; modifies system state; move elsewhere
10666            if (pkgSetting.origPackage != null) {
10667                // If we are first transitioning from an original package,
10668                // fix up the new package's name now.  We need to do this after
10669                // looking up the package under its new name, so getPackageLP
10670                // can take care of fiddling things correctly.
10671                pkg.setPackageName(origPackage.name);
10672
10673                // File a report about this.
10674                String msg = "New package " + pkgSetting.realName
10675                        + " renamed to replace old package " + pkgSetting.name;
10676                reportSettingsProblem(Log.WARN, msg);
10677
10678                // Make a note of it.
10679                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10680                    mTransferedPackages.add(origPackage.name);
10681                }
10682
10683                // No longer need to retain this.
10684                pkgSetting.origPackage = null;
10685            }
10686
10687            // SIDE EFFECTS; modifies system state; move elsewhere
10688            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10689                // Make a note of it.
10690                mTransferedPackages.add(pkg.packageName);
10691            }
10692
10693            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10694                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10695            }
10696
10697            if ((scanFlags & SCAN_BOOTING) == 0
10698                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10699                // Check all shared libraries and map to their actual file path.
10700                // We only do this here for apps not on a system dir, because those
10701                // are the only ones that can fail an install due to this.  We
10702                // will take care of the system apps by updating all of their
10703                // library paths after the scan is done. Also during the initial
10704                // scan don't update any libs as we do this wholesale after all
10705                // apps are scanned to avoid dependency based scanning.
10706                updateSharedLibrariesLPr(pkg, null);
10707            }
10708
10709            if (mFoundPolicyFile) {
10710                SELinuxMMAC.assignSeInfoValue(pkg);
10711            }
10712            pkg.applicationInfo.uid = pkgSetting.appId;
10713            pkg.mExtras = pkgSetting;
10714
10715
10716            // Static shared libs have same package with different versions where
10717            // we internally use a synthetic package name to allow multiple versions
10718            // of the same package, therefore we need to compare signatures against
10719            // the package setting for the latest library version.
10720            PackageSetting signatureCheckPs = pkgSetting;
10721            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10722                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10723                if (libraryEntry != null) {
10724                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10725                }
10726            }
10727
10728            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10729                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10730                    // We just determined the app is signed correctly, so bring
10731                    // over the latest parsed certs.
10732                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10733                } else {
10734                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10735                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10736                                "Package " + pkg.packageName + " upgrade keys do not match the "
10737                                + "previously installed version");
10738                    } else {
10739                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10740                        String msg = "System package " + pkg.packageName
10741                                + " signature changed; retaining data.";
10742                        reportSettingsProblem(Log.WARN, msg);
10743                    }
10744                }
10745            } else {
10746                try {
10747                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10748                    verifySignaturesLP(signatureCheckPs, pkg);
10749                    // We just determined the app is signed correctly, so bring
10750                    // over the latest parsed certs.
10751                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10752                } catch (PackageManagerException e) {
10753                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10754                        throw e;
10755                    }
10756                    // The signature has changed, but this package is in the system
10757                    // image...  let's recover!
10758                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10759                    // However...  if this package is part of a shared user, but it
10760                    // doesn't match the signature of the shared user, let's fail.
10761                    // What this means is that you can't change the signatures
10762                    // associated with an overall shared user, which doesn't seem all
10763                    // that unreasonable.
10764                    if (signatureCheckPs.sharedUser != null) {
10765                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10766                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10767                            throw new PackageManagerException(
10768                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10769                                    "Signature mismatch for shared user: "
10770                                            + pkgSetting.sharedUser);
10771                        }
10772                    }
10773                    // File a report about this.
10774                    String msg = "System package " + pkg.packageName
10775                            + " signature changed; retaining data.";
10776                    reportSettingsProblem(Log.WARN, msg);
10777                }
10778            }
10779
10780            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10781                // This package wants to adopt ownership of permissions from
10782                // another package.
10783                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10784                    final String origName = pkg.mAdoptPermissions.get(i);
10785                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10786                    if (orig != null) {
10787                        if (verifyPackageUpdateLPr(orig, pkg)) {
10788                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10789                                    + pkg.packageName);
10790                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10791                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10792                        }
10793                    }
10794                }
10795            }
10796        }
10797
10798        pkg.applicationInfo.processName = fixProcessName(
10799                pkg.applicationInfo.packageName,
10800                pkg.applicationInfo.processName);
10801
10802        if (pkg != mPlatformPackage) {
10803            // Get all of our default paths setup
10804            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10805        }
10806
10807        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10808
10809        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10810            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10811                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10812                final boolean extractNativeLibs = !pkg.isLibrary();
10813                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
10814                        mAppLib32InstallDir);
10815                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10816
10817                // Some system apps still use directory structure for native libraries
10818                // in which case we might end up not detecting abi solely based on apk
10819                // structure. Try to detect abi based on directory structure.
10820                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10821                        pkg.applicationInfo.primaryCpuAbi == null) {
10822                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10823                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10824                }
10825            } else {
10826                // This is not a first boot or an upgrade, don't bother deriving the
10827                // ABI during the scan. Instead, trust the value that was stored in the
10828                // package setting.
10829                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10830                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10831
10832                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10833
10834                if (DEBUG_ABI_SELECTION) {
10835                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10836                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10837                        pkg.applicationInfo.secondaryCpuAbi);
10838                }
10839            }
10840        } else {
10841            if ((scanFlags & SCAN_MOVE) != 0) {
10842                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10843                // but we already have this packages package info in the PackageSetting. We just
10844                // use that and derive the native library path based on the new codepath.
10845                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10846                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10847            }
10848
10849            // Set native library paths again. For moves, the path will be updated based on the
10850            // ABIs we've determined above. For non-moves, the path will be updated based on the
10851            // ABIs we determined during compilation, but the path will depend on the final
10852            // package path (after the rename away from the stage path).
10853            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10854        }
10855
10856        // This is a special case for the "system" package, where the ABI is
10857        // dictated by the zygote configuration (and init.rc). We should keep track
10858        // of this ABI so that we can deal with "normal" applications that run under
10859        // the same UID correctly.
10860        if (mPlatformPackage == pkg) {
10861            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10862                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10863        }
10864
10865        // If there's a mismatch between the abi-override in the package setting
10866        // and the abiOverride specified for the install. Warn about this because we
10867        // would've already compiled the app without taking the package setting into
10868        // account.
10869        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10870            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10871                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10872                        " for package " + pkg.packageName);
10873            }
10874        }
10875
10876        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10877        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10878        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10879
10880        // Copy the derived override back to the parsed package, so that we can
10881        // update the package settings accordingly.
10882        pkg.cpuAbiOverride = cpuAbiOverride;
10883
10884        if (DEBUG_ABI_SELECTION) {
10885            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10886                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10887                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10888        }
10889
10890        // Push the derived path down into PackageSettings so we know what to
10891        // clean up at uninstall time.
10892        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10893
10894        if (DEBUG_ABI_SELECTION) {
10895            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10896                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10897                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10898        }
10899
10900        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10901        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10902            // We don't do this here during boot because we can do it all
10903            // at once after scanning all existing packages.
10904            //
10905            // We also do this *before* we perform dexopt on this package, so that
10906            // we can avoid redundant dexopts, and also to make sure we've got the
10907            // code and package path correct.
10908            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10909        }
10910
10911        if (mFactoryTest && pkg.requestedPermissions.contains(
10912                android.Manifest.permission.FACTORY_TEST)) {
10913            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10914        }
10915
10916        if (isSystemApp(pkg)) {
10917            pkgSetting.isOrphaned = true;
10918        }
10919
10920        // Take care of first install / last update times.
10921        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10922        if (currentTime != 0) {
10923            if (pkgSetting.firstInstallTime == 0) {
10924                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10925            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10926                pkgSetting.lastUpdateTime = currentTime;
10927            }
10928        } else if (pkgSetting.firstInstallTime == 0) {
10929            // We need *something*.  Take time time stamp of the file.
10930            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10931        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10932            if (scanFileTime != pkgSetting.timeStamp) {
10933                // A package on the system image has changed; consider this
10934                // to be an update.
10935                pkgSetting.lastUpdateTime = scanFileTime;
10936            }
10937        }
10938        pkgSetting.setTimeStamp(scanFileTime);
10939
10940        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10941            if (nonMutatedPs != null) {
10942                synchronized (mPackages) {
10943                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10944                }
10945            }
10946        } else {
10947            final int userId = user == null ? 0 : user.getIdentifier();
10948            // Modify state for the given package setting
10949            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10950                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10951            if (pkgSetting.getInstantApp(userId)) {
10952                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10953            }
10954        }
10955        return pkg;
10956    }
10957
10958    /**
10959     * Applies policy to the parsed package based upon the given policy flags.
10960     * Ensures the package is in a good state.
10961     * <p>
10962     * Implementation detail: This method must NOT have any side effect. It would
10963     * ideally be static, but, it requires locks to read system state.
10964     */
10965    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10966        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10967            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10968            if (pkg.applicationInfo.isDirectBootAware()) {
10969                // we're direct boot aware; set for all components
10970                for (PackageParser.Service s : pkg.services) {
10971                    s.info.encryptionAware = s.info.directBootAware = true;
10972                }
10973                for (PackageParser.Provider p : pkg.providers) {
10974                    p.info.encryptionAware = p.info.directBootAware = true;
10975                }
10976                for (PackageParser.Activity a : pkg.activities) {
10977                    a.info.encryptionAware = a.info.directBootAware = true;
10978                }
10979                for (PackageParser.Activity r : pkg.receivers) {
10980                    r.info.encryptionAware = r.info.directBootAware = true;
10981                }
10982            }
10983            if (compressedFileExists(pkg.baseCodePath)) {
10984                pkg.isStub = true;
10985            }
10986        } else {
10987            // Only allow system apps to be flagged as core apps.
10988            pkg.coreApp = false;
10989            // clear flags not applicable to regular apps
10990            pkg.applicationInfo.privateFlags &=
10991                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10992            pkg.applicationInfo.privateFlags &=
10993                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10994        }
10995        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10996
10997        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10998            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10999        }
11000
11001        if (!isSystemApp(pkg)) {
11002            // Only system apps can use these features.
11003            pkg.mOriginalPackages = null;
11004            pkg.mRealPackage = null;
11005            pkg.mAdoptPermissions = null;
11006        }
11007    }
11008
11009    /**
11010     * Asserts the parsed package is valid according to the given policy. If the
11011     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11012     * <p>
11013     * Implementation detail: This method must NOT have any side effects. It would
11014     * ideally be static, but, it requires locks to read system state.
11015     *
11016     * @throws PackageManagerException If the package fails any of the validation checks
11017     */
11018    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11019            throws PackageManagerException {
11020        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11021            assertCodePolicy(pkg);
11022        }
11023
11024        if (pkg.applicationInfo.getCodePath() == null ||
11025                pkg.applicationInfo.getResourcePath() == null) {
11026            // Bail out. The resource and code paths haven't been set.
11027            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11028                    "Code and resource paths haven't been set correctly");
11029        }
11030
11031        // Make sure we're not adding any bogus keyset info
11032        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11033        ksms.assertScannedPackageValid(pkg);
11034
11035        synchronized (mPackages) {
11036            // The special "android" package can only be defined once
11037            if (pkg.packageName.equals("android")) {
11038                if (mAndroidApplication != null) {
11039                    Slog.w(TAG, "*************************************************");
11040                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
11041                    Slog.w(TAG, " codePath=" + pkg.codePath);
11042                    Slog.w(TAG, "*************************************************");
11043                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11044                            "Core android package being redefined.  Skipping.");
11045                }
11046            }
11047
11048            // A package name must be unique; don't allow duplicates
11049            if (mPackages.containsKey(pkg.packageName)) {
11050                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11051                        "Application package " + pkg.packageName
11052                        + " already installed.  Skipping duplicate.");
11053            }
11054
11055            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11056                // Static libs have a synthetic package name containing the version
11057                // but we still want the base name to be unique.
11058                if (mPackages.containsKey(pkg.manifestPackageName)) {
11059                    throw new PackageManagerException(
11060                            "Duplicate static shared lib provider package");
11061                }
11062
11063                // Static shared libraries should have at least O target SDK
11064                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11065                    throw new PackageManagerException(
11066                            "Packages declaring static-shared libs must target O SDK or higher");
11067                }
11068
11069                // Package declaring static a shared lib cannot be instant apps
11070                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11071                    throw new PackageManagerException(
11072                            "Packages declaring static-shared libs cannot be instant apps");
11073                }
11074
11075                // Package declaring static a shared lib cannot be renamed since the package
11076                // name is synthetic and apps can't code around package manager internals.
11077                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11078                    throw new PackageManagerException(
11079                            "Packages declaring static-shared libs cannot be renamed");
11080                }
11081
11082                // Package declaring static a shared lib cannot declare child packages
11083                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11084                    throw new PackageManagerException(
11085                            "Packages declaring static-shared libs cannot have child packages");
11086                }
11087
11088                // Package declaring static a shared lib cannot declare dynamic libs
11089                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11090                    throw new PackageManagerException(
11091                            "Packages declaring static-shared libs cannot declare dynamic libs");
11092                }
11093
11094                // Package declaring static a shared lib cannot declare shared users
11095                if (pkg.mSharedUserId != null) {
11096                    throw new PackageManagerException(
11097                            "Packages declaring static-shared libs cannot declare shared users");
11098                }
11099
11100                // Static shared libs cannot declare activities
11101                if (!pkg.activities.isEmpty()) {
11102                    throw new PackageManagerException(
11103                            "Static shared libs cannot declare activities");
11104                }
11105
11106                // Static shared libs cannot declare services
11107                if (!pkg.services.isEmpty()) {
11108                    throw new PackageManagerException(
11109                            "Static shared libs cannot declare services");
11110                }
11111
11112                // Static shared libs cannot declare providers
11113                if (!pkg.providers.isEmpty()) {
11114                    throw new PackageManagerException(
11115                            "Static shared libs cannot declare content providers");
11116                }
11117
11118                // Static shared libs cannot declare receivers
11119                if (!pkg.receivers.isEmpty()) {
11120                    throw new PackageManagerException(
11121                            "Static shared libs cannot declare broadcast receivers");
11122                }
11123
11124                // Static shared libs cannot declare permission groups
11125                if (!pkg.permissionGroups.isEmpty()) {
11126                    throw new PackageManagerException(
11127                            "Static shared libs cannot declare permission groups");
11128                }
11129
11130                // Static shared libs cannot declare permissions
11131                if (!pkg.permissions.isEmpty()) {
11132                    throw new PackageManagerException(
11133                            "Static shared libs cannot declare permissions");
11134                }
11135
11136                // Static shared libs cannot declare protected broadcasts
11137                if (pkg.protectedBroadcasts != null) {
11138                    throw new PackageManagerException(
11139                            "Static shared libs cannot declare protected broadcasts");
11140                }
11141
11142                // Static shared libs cannot be overlay targets
11143                if (pkg.mOverlayTarget != null) {
11144                    throw new PackageManagerException(
11145                            "Static shared libs cannot be overlay targets");
11146                }
11147
11148                // The version codes must be ordered as lib versions
11149                int minVersionCode = Integer.MIN_VALUE;
11150                int maxVersionCode = Integer.MAX_VALUE;
11151
11152                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11153                        pkg.staticSharedLibName);
11154                if (versionedLib != null) {
11155                    final int versionCount = versionedLib.size();
11156                    for (int i = 0; i < versionCount; i++) {
11157                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11158                        final int libVersionCode = libInfo.getDeclaringPackage()
11159                                .getVersionCode();
11160                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11161                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11162                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11163                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11164                        } else {
11165                            minVersionCode = maxVersionCode = libVersionCode;
11166                            break;
11167                        }
11168                    }
11169                }
11170                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11171                    throw new PackageManagerException("Static shared"
11172                            + " lib version codes must be ordered as lib versions");
11173                }
11174            }
11175
11176            // Only privileged apps and updated privileged apps can add child packages.
11177            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11178                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11179                    throw new PackageManagerException("Only privileged apps can add child "
11180                            + "packages. Ignoring package " + pkg.packageName);
11181                }
11182                final int childCount = pkg.childPackages.size();
11183                for (int i = 0; i < childCount; i++) {
11184                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11185                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11186                            childPkg.packageName)) {
11187                        throw new PackageManagerException("Can't override child of "
11188                                + "another disabled app. Ignoring package " + pkg.packageName);
11189                    }
11190                }
11191            }
11192
11193            // If we're only installing presumed-existing packages, require that the
11194            // scanned APK is both already known and at the path previously established
11195            // for it.  Previously unknown packages we pick up normally, but if we have an
11196            // a priori expectation about this package's install presence, enforce it.
11197            // With a singular exception for new system packages. When an OTA contains
11198            // a new system package, we allow the codepath to change from a system location
11199            // to the user-installed location. If we don't allow this change, any newer,
11200            // user-installed version of the application will be ignored.
11201            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11202                if (mExpectingBetter.containsKey(pkg.packageName)) {
11203                    logCriticalInfo(Log.WARN,
11204                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11205                } else {
11206                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11207                    if (known != null) {
11208                        if (DEBUG_PACKAGE_SCANNING) {
11209                            Log.d(TAG, "Examining " + pkg.codePath
11210                                    + " and requiring known paths " + known.codePathString
11211                                    + " & " + known.resourcePathString);
11212                        }
11213                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11214                                || !pkg.applicationInfo.getResourcePath().equals(
11215                                        known.resourcePathString)) {
11216                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11217                                    "Application package " + pkg.packageName
11218                                    + " found at " + pkg.applicationInfo.getCodePath()
11219                                    + " but expected at " + known.codePathString
11220                                    + "; ignoring.");
11221                        }
11222                    }
11223                }
11224            }
11225
11226            // Verify that this new package doesn't have any content providers
11227            // that conflict with existing packages.  Only do this if the
11228            // package isn't already installed, since we don't want to break
11229            // things that are installed.
11230            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11231                final int N = pkg.providers.size();
11232                int i;
11233                for (i=0; i<N; i++) {
11234                    PackageParser.Provider p = pkg.providers.get(i);
11235                    if (p.info.authority != null) {
11236                        String names[] = p.info.authority.split(";");
11237                        for (int j = 0; j < names.length; j++) {
11238                            if (mProvidersByAuthority.containsKey(names[j])) {
11239                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11240                                final String otherPackageName =
11241                                        ((other != null && other.getComponentName() != null) ?
11242                                                other.getComponentName().getPackageName() : "?");
11243                                throw new PackageManagerException(
11244                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11245                                        "Can't install because provider name " + names[j]
11246                                                + " (in package " + pkg.applicationInfo.packageName
11247                                                + ") is already used by " + otherPackageName);
11248                            }
11249                        }
11250                    }
11251                }
11252            }
11253        }
11254    }
11255
11256    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11257            int type, String declaringPackageName, int declaringVersionCode) {
11258        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11259        if (versionedLib == null) {
11260            versionedLib = new SparseArray<>();
11261            mSharedLibraries.put(name, versionedLib);
11262            if (type == SharedLibraryInfo.TYPE_STATIC) {
11263                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11264            }
11265        } else if (versionedLib.indexOfKey(version) >= 0) {
11266            return false;
11267        }
11268        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11269                version, type, declaringPackageName, declaringVersionCode);
11270        versionedLib.put(version, libEntry);
11271        return true;
11272    }
11273
11274    private boolean removeSharedLibraryLPw(String name, int version) {
11275        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11276        if (versionedLib == null) {
11277            return false;
11278        }
11279        final int libIdx = versionedLib.indexOfKey(version);
11280        if (libIdx < 0) {
11281            return false;
11282        }
11283        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11284        versionedLib.remove(version);
11285        if (versionedLib.size() <= 0) {
11286            mSharedLibraries.remove(name);
11287            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11288                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11289                        .getPackageName());
11290            }
11291        }
11292        return true;
11293    }
11294
11295    /**
11296     * Adds a scanned package to the system. When this method is finished, the package will
11297     * be available for query, resolution, etc...
11298     */
11299    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11300            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11301        final String pkgName = pkg.packageName;
11302        if (mCustomResolverComponentName != null &&
11303                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11304            setUpCustomResolverActivity(pkg);
11305        }
11306
11307        if (pkg.packageName.equals("android")) {
11308            synchronized (mPackages) {
11309                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11310                    // Set up information for our fall-back user intent resolution activity.
11311                    mPlatformPackage = pkg;
11312                    pkg.mVersionCode = mSdkVersion;
11313                    mAndroidApplication = pkg.applicationInfo;
11314                    if (!mResolverReplaced) {
11315                        mResolveActivity.applicationInfo = mAndroidApplication;
11316                        mResolveActivity.name = ResolverActivity.class.getName();
11317                        mResolveActivity.packageName = mAndroidApplication.packageName;
11318                        mResolveActivity.processName = "system:ui";
11319                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11320                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11321                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11322                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11323                        mResolveActivity.exported = true;
11324                        mResolveActivity.enabled = true;
11325                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11326                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11327                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11328                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11329                                | ActivityInfo.CONFIG_ORIENTATION
11330                                | ActivityInfo.CONFIG_KEYBOARD
11331                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11332                        mResolveInfo.activityInfo = mResolveActivity;
11333                        mResolveInfo.priority = 0;
11334                        mResolveInfo.preferredOrder = 0;
11335                        mResolveInfo.match = 0;
11336                        mResolveComponentName = new ComponentName(
11337                                mAndroidApplication.packageName, mResolveActivity.name);
11338                    }
11339                }
11340            }
11341        }
11342
11343        ArrayList<PackageParser.Package> clientLibPkgs = null;
11344        // writer
11345        synchronized (mPackages) {
11346            boolean hasStaticSharedLibs = false;
11347
11348            // Any app can add new static shared libraries
11349            if (pkg.staticSharedLibName != null) {
11350                // Static shared libs don't allow renaming as they have synthetic package
11351                // names to allow install of multiple versions, so use name from manifest.
11352                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11353                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11354                        pkg.manifestPackageName, pkg.mVersionCode)) {
11355                    hasStaticSharedLibs = true;
11356                } else {
11357                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11358                                + pkg.staticSharedLibName + " already exists; skipping");
11359                }
11360                // Static shared libs cannot be updated once installed since they
11361                // use synthetic package name which includes the version code, so
11362                // not need to update other packages's shared lib dependencies.
11363            }
11364
11365            if (!hasStaticSharedLibs
11366                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11367                // Only system apps can add new dynamic shared libraries.
11368                if (pkg.libraryNames != null) {
11369                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11370                        String name = pkg.libraryNames.get(i);
11371                        boolean allowed = false;
11372                        if (pkg.isUpdatedSystemApp()) {
11373                            // New library entries can only be added through the
11374                            // system image.  This is important to get rid of a lot
11375                            // of nasty edge cases: for example if we allowed a non-
11376                            // system update of the app to add a library, then uninstalling
11377                            // the update would make the library go away, and assumptions
11378                            // we made such as through app install filtering would now
11379                            // have allowed apps on the device which aren't compatible
11380                            // with it.  Better to just have the restriction here, be
11381                            // conservative, and create many fewer cases that can negatively
11382                            // impact the user experience.
11383                            final PackageSetting sysPs = mSettings
11384                                    .getDisabledSystemPkgLPr(pkg.packageName);
11385                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11386                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11387                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11388                                        allowed = true;
11389                                        break;
11390                                    }
11391                                }
11392                            }
11393                        } else {
11394                            allowed = true;
11395                        }
11396                        if (allowed) {
11397                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11398                                    SharedLibraryInfo.VERSION_UNDEFINED,
11399                                    SharedLibraryInfo.TYPE_DYNAMIC,
11400                                    pkg.packageName, pkg.mVersionCode)) {
11401                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11402                                        + name + " already exists; skipping");
11403                            }
11404                        } else {
11405                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11406                                    + name + " that is not declared on system image; skipping");
11407                        }
11408                    }
11409
11410                    if ((scanFlags & SCAN_BOOTING) == 0) {
11411                        // If we are not booting, we need to update any applications
11412                        // that are clients of our shared library.  If we are booting,
11413                        // this will all be done once the scan is complete.
11414                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11415                    }
11416                }
11417            }
11418        }
11419
11420        if ((scanFlags & SCAN_BOOTING) != 0) {
11421            // No apps can run during boot scan, so they don't need to be frozen
11422        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11423            // Caller asked to not kill app, so it's probably not frozen
11424        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11425            // Caller asked us to ignore frozen check for some reason; they
11426            // probably didn't know the package name
11427        } else {
11428            // We're doing major surgery on this package, so it better be frozen
11429            // right now to keep it from launching
11430            checkPackageFrozen(pkgName);
11431        }
11432
11433        // Also need to kill any apps that are dependent on the library.
11434        if (clientLibPkgs != null) {
11435            for (int i=0; i<clientLibPkgs.size(); i++) {
11436                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11437                killApplication(clientPkg.applicationInfo.packageName,
11438                        clientPkg.applicationInfo.uid, "update lib");
11439            }
11440        }
11441
11442        // writer
11443        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11444
11445        synchronized (mPackages) {
11446            // We don't expect installation to fail beyond this point
11447
11448            // Add the new setting to mSettings
11449            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11450            // Add the new setting to mPackages
11451            mPackages.put(pkg.applicationInfo.packageName, pkg);
11452            // Make sure we don't accidentally delete its data.
11453            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11454            while (iter.hasNext()) {
11455                PackageCleanItem item = iter.next();
11456                if (pkgName.equals(item.packageName)) {
11457                    iter.remove();
11458                }
11459            }
11460
11461            // Add the package's KeySets to the global KeySetManagerService
11462            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11463            ksms.addScannedPackageLPw(pkg);
11464
11465            int N = pkg.providers.size();
11466            StringBuilder r = null;
11467            int i;
11468            for (i=0; i<N; i++) {
11469                PackageParser.Provider p = pkg.providers.get(i);
11470                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11471                        p.info.processName);
11472                mProviders.addProvider(p);
11473                p.syncable = p.info.isSyncable;
11474                if (p.info.authority != null) {
11475                    String names[] = p.info.authority.split(";");
11476                    p.info.authority = null;
11477                    for (int j = 0; j < names.length; j++) {
11478                        if (j == 1 && p.syncable) {
11479                            // We only want the first authority for a provider to possibly be
11480                            // syncable, so if we already added this provider using a different
11481                            // authority clear the syncable flag. We copy the provider before
11482                            // changing it because the mProviders object contains a reference
11483                            // to a provider that we don't want to change.
11484                            // Only do this for the second authority since the resulting provider
11485                            // object can be the same for all future authorities for this provider.
11486                            p = new PackageParser.Provider(p);
11487                            p.syncable = false;
11488                        }
11489                        if (!mProvidersByAuthority.containsKey(names[j])) {
11490                            mProvidersByAuthority.put(names[j], p);
11491                            if (p.info.authority == null) {
11492                                p.info.authority = names[j];
11493                            } else {
11494                                p.info.authority = p.info.authority + ";" + names[j];
11495                            }
11496                            if (DEBUG_PACKAGE_SCANNING) {
11497                                if (chatty)
11498                                    Log.d(TAG, "Registered content provider: " + names[j]
11499                                            + ", className = " + p.info.name + ", isSyncable = "
11500                                            + p.info.isSyncable);
11501                            }
11502                        } else {
11503                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11504                            Slog.w(TAG, "Skipping provider name " + names[j] +
11505                                    " (in package " + pkg.applicationInfo.packageName +
11506                                    "): name already used by "
11507                                    + ((other != null && other.getComponentName() != null)
11508                                            ? other.getComponentName().getPackageName() : "?"));
11509                        }
11510                    }
11511                }
11512                if (chatty) {
11513                    if (r == null) {
11514                        r = new StringBuilder(256);
11515                    } else {
11516                        r.append(' ');
11517                    }
11518                    r.append(p.info.name);
11519                }
11520            }
11521            if (r != null) {
11522                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11523            }
11524
11525            N = pkg.services.size();
11526            r = null;
11527            for (i=0; i<N; i++) {
11528                PackageParser.Service s = pkg.services.get(i);
11529                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11530                        s.info.processName);
11531                mServices.addService(s);
11532                if (chatty) {
11533                    if (r == null) {
11534                        r = new StringBuilder(256);
11535                    } else {
11536                        r.append(' ');
11537                    }
11538                    r.append(s.info.name);
11539                }
11540            }
11541            if (r != null) {
11542                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11543            }
11544
11545            N = pkg.receivers.size();
11546            r = null;
11547            for (i=0; i<N; i++) {
11548                PackageParser.Activity a = pkg.receivers.get(i);
11549                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11550                        a.info.processName);
11551                mReceivers.addActivity(a, "receiver");
11552                if (chatty) {
11553                    if (r == null) {
11554                        r = new StringBuilder(256);
11555                    } else {
11556                        r.append(' ');
11557                    }
11558                    r.append(a.info.name);
11559                }
11560            }
11561            if (r != null) {
11562                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11563            }
11564
11565            N = pkg.activities.size();
11566            r = null;
11567            for (i=0; i<N; i++) {
11568                PackageParser.Activity a = pkg.activities.get(i);
11569                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11570                        a.info.processName);
11571                mActivities.addActivity(a, "activity");
11572                if (chatty) {
11573                    if (r == null) {
11574                        r = new StringBuilder(256);
11575                    } else {
11576                        r.append(' ');
11577                    }
11578                    r.append(a.info.name);
11579                }
11580            }
11581            if (r != null) {
11582                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11583            }
11584
11585            N = pkg.permissionGroups.size();
11586            r = null;
11587            for (i=0; i<N; i++) {
11588                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11589                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11590                final String curPackageName = cur == null ? null : cur.info.packageName;
11591                // Dont allow ephemeral apps to define new permission groups.
11592                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11593                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11594                            + pg.info.packageName
11595                            + " ignored: instant apps cannot define new permission groups.");
11596                    continue;
11597                }
11598                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11599                if (cur == null || isPackageUpdate) {
11600                    mPermissionGroups.put(pg.info.name, pg);
11601                    if (chatty) {
11602                        if (r == null) {
11603                            r = new StringBuilder(256);
11604                        } else {
11605                            r.append(' ');
11606                        }
11607                        if (isPackageUpdate) {
11608                            r.append("UPD:");
11609                        }
11610                        r.append(pg.info.name);
11611                    }
11612                } else {
11613                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11614                            + pg.info.packageName + " ignored: original from "
11615                            + cur.info.packageName);
11616                    if (chatty) {
11617                        if (r == null) {
11618                            r = new StringBuilder(256);
11619                        } else {
11620                            r.append(' ');
11621                        }
11622                        r.append("DUP:");
11623                        r.append(pg.info.name);
11624                    }
11625                }
11626            }
11627            if (r != null) {
11628                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11629            }
11630
11631            N = pkg.permissions.size();
11632            r = null;
11633            for (i=0; i<N; i++) {
11634                PackageParser.Permission p = pkg.permissions.get(i);
11635
11636                // Dont allow ephemeral apps to define new permissions.
11637                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11638                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11639                            + p.info.packageName
11640                            + " ignored: instant apps cannot define new permissions.");
11641                    continue;
11642                }
11643
11644                // Assume by default that we did not install this permission into the system.
11645                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11646
11647                // Now that permission groups have a special meaning, we ignore permission
11648                // groups for legacy apps to prevent unexpected behavior. In particular,
11649                // permissions for one app being granted to someone just because they happen
11650                // to be in a group defined by another app (before this had no implications).
11651                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11652                    p.group = mPermissionGroups.get(p.info.group);
11653                    // Warn for a permission in an unknown group.
11654                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11655                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11656                                + p.info.packageName + " in an unknown group " + p.info.group);
11657                    }
11658                }
11659
11660                ArrayMap<String, BasePermission> permissionMap =
11661                        p.tree ? mSettings.mPermissionTrees
11662                                : mSettings.mPermissions;
11663                BasePermission bp = permissionMap.get(p.info.name);
11664
11665                // Allow system apps to redefine non-system permissions
11666                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11667                    final boolean currentOwnerIsSystem = (bp.perm != null
11668                            && isSystemApp(bp.perm.owner));
11669                    if (isSystemApp(p.owner)) {
11670                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
11671                            // It's a built-in permission and no owner, take ownership now
11672                            bp.packageSetting = pkgSetting;
11673                            bp.perm = p;
11674                            bp.uid = pkg.applicationInfo.uid;
11675                            bp.sourcePackage = p.info.packageName;
11676                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11677                        } else if (!currentOwnerIsSystem) {
11678                            String msg = "New decl " + p.owner + " of permission  "
11679                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
11680                            reportSettingsProblem(Log.WARN, msg);
11681                            bp = null;
11682                        }
11683                    }
11684                }
11685
11686                if (bp == null) {
11687                    bp = new BasePermission(p.info.name, p.info.packageName,
11688                            BasePermission.TYPE_NORMAL);
11689                    permissionMap.put(p.info.name, bp);
11690                }
11691
11692                if (bp.perm == null) {
11693                    if (bp.sourcePackage == null
11694                            || bp.sourcePackage.equals(p.info.packageName)) {
11695                        BasePermission tree = findPermissionTreeLP(p.info.name);
11696                        if (tree == null
11697                                || tree.sourcePackage.equals(p.info.packageName)) {
11698                            bp.packageSetting = pkgSetting;
11699                            bp.perm = p;
11700                            bp.uid = pkg.applicationInfo.uid;
11701                            bp.sourcePackage = p.info.packageName;
11702                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11703                            if (chatty) {
11704                                if (r == null) {
11705                                    r = new StringBuilder(256);
11706                                } else {
11707                                    r.append(' ');
11708                                }
11709                                r.append(p.info.name);
11710                            }
11711                        } else {
11712                            Slog.w(TAG, "Permission " + p.info.name + " from package "
11713                                    + p.info.packageName + " ignored: base tree "
11714                                    + tree.name + " is from package "
11715                                    + tree.sourcePackage);
11716                        }
11717                    } else {
11718                        Slog.w(TAG, "Permission " + p.info.name + " from package "
11719                                + p.info.packageName + " ignored: original from "
11720                                + bp.sourcePackage);
11721                    }
11722                } else if (chatty) {
11723                    if (r == null) {
11724                        r = new StringBuilder(256);
11725                    } else {
11726                        r.append(' ');
11727                    }
11728                    r.append("DUP:");
11729                    r.append(p.info.name);
11730                }
11731                if (bp.perm == p) {
11732                    bp.protectionLevel = p.info.protectionLevel;
11733                }
11734            }
11735
11736            if (r != null) {
11737                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
11738            }
11739
11740            N = pkg.instrumentation.size();
11741            r = null;
11742            for (i=0; i<N; i++) {
11743                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11744                a.info.packageName = pkg.applicationInfo.packageName;
11745                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11746                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11747                a.info.splitNames = pkg.splitNames;
11748                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11749                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11750                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11751                a.info.dataDir = pkg.applicationInfo.dataDir;
11752                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11753                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11754                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11755                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11756                mInstrumentation.put(a.getComponentName(), a);
11757                if (chatty) {
11758                    if (r == null) {
11759                        r = new StringBuilder(256);
11760                    } else {
11761                        r.append(' ');
11762                    }
11763                    r.append(a.info.name);
11764                }
11765            }
11766            if (r != null) {
11767                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11768            }
11769
11770            if (pkg.protectedBroadcasts != null) {
11771                N = pkg.protectedBroadcasts.size();
11772                synchronized (mProtectedBroadcasts) {
11773                    for (i = 0; i < N; i++) {
11774                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11775                    }
11776                }
11777            }
11778        }
11779
11780        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11781    }
11782
11783    /**
11784     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11785     * is derived purely on the basis of the contents of {@code scanFile} and
11786     * {@code cpuAbiOverride}.
11787     *
11788     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11789     */
11790    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11791                                 String cpuAbiOverride, boolean extractLibs,
11792                                 File appLib32InstallDir)
11793            throws PackageManagerException {
11794        // Give ourselves some initial paths; we'll come back for another
11795        // pass once we've determined ABI below.
11796        setNativeLibraryPaths(pkg, appLib32InstallDir);
11797
11798        // We would never need to extract libs for forward-locked and external packages,
11799        // since the container service will do it for us. We shouldn't attempt to
11800        // extract libs from system app when it was not updated.
11801        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11802                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11803            extractLibs = false;
11804        }
11805
11806        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11807        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11808
11809        NativeLibraryHelper.Handle handle = null;
11810        try {
11811            handle = NativeLibraryHelper.Handle.create(pkg);
11812            // TODO(multiArch): This can be null for apps that didn't go through the
11813            // usual installation process. We can calculate it again, like we
11814            // do during install time.
11815            //
11816            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11817            // unnecessary.
11818            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11819
11820            // Null out the abis so that they can be recalculated.
11821            pkg.applicationInfo.primaryCpuAbi = null;
11822            pkg.applicationInfo.secondaryCpuAbi = null;
11823            if (isMultiArch(pkg.applicationInfo)) {
11824                // Warn if we've set an abiOverride for multi-lib packages..
11825                // By definition, we need to copy both 32 and 64 bit libraries for
11826                // such packages.
11827                if (pkg.cpuAbiOverride != null
11828                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11829                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11830                }
11831
11832                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11833                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11834                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11835                    if (extractLibs) {
11836                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11837                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11838                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11839                                useIsaSpecificSubdirs);
11840                    } else {
11841                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11842                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11843                    }
11844                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11845                }
11846
11847                // Shared library native code should be in the APK zip aligned
11848                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11849                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11850                            "Shared library native lib extraction not supported");
11851                }
11852
11853                maybeThrowExceptionForMultiArchCopy(
11854                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11855
11856                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11857                    if (extractLibs) {
11858                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11859                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11860                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11861                                useIsaSpecificSubdirs);
11862                    } else {
11863                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11864                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11865                    }
11866                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11867                }
11868
11869                maybeThrowExceptionForMultiArchCopy(
11870                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11871
11872                if (abi64 >= 0) {
11873                    // Shared library native libs should be in the APK zip aligned
11874                    if (extractLibs && pkg.isLibrary()) {
11875                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11876                                "Shared library native lib extraction not supported");
11877                    }
11878                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11879                }
11880
11881                if (abi32 >= 0) {
11882                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11883                    if (abi64 >= 0) {
11884                        if (pkg.use32bitAbi) {
11885                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11886                            pkg.applicationInfo.primaryCpuAbi = abi;
11887                        } else {
11888                            pkg.applicationInfo.secondaryCpuAbi = abi;
11889                        }
11890                    } else {
11891                        pkg.applicationInfo.primaryCpuAbi = abi;
11892                    }
11893                }
11894            } else {
11895                String[] abiList = (cpuAbiOverride != null) ?
11896                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11897
11898                // Enable gross and lame hacks for apps that are built with old
11899                // SDK tools. We must scan their APKs for renderscript bitcode and
11900                // not launch them if it's present. Don't bother checking on devices
11901                // that don't have 64 bit support.
11902                boolean needsRenderScriptOverride = false;
11903                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11904                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11905                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11906                    needsRenderScriptOverride = true;
11907                }
11908
11909                final int copyRet;
11910                if (extractLibs) {
11911                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11912                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11913                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11914                } else {
11915                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11916                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11917                }
11918                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11919
11920                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11921                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11922                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11923                }
11924
11925                if (copyRet >= 0) {
11926                    // Shared libraries that have native libs must be multi-architecture
11927                    if (pkg.isLibrary()) {
11928                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11929                                "Shared library with native libs must be multiarch");
11930                    }
11931                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11932                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11933                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11934                } else if (needsRenderScriptOverride) {
11935                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11936                }
11937            }
11938        } catch (IOException ioe) {
11939            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11940        } finally {
11941            IoUtils.closeQuietly(handle);
11942        }
11943
11944        // Now that we've calculated the ABIs and determined if it's an internal app,
11945        // we will go ahead and populate the nativeLibraryPath.
11946        setNativeLibraryPaths(pkg, appLib32InstallDir);
11947    }
11948
11949    /**
11950     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11951     * i.e, so that all packages can be run inside a single process if required.
11952     *
11953     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11954     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11955     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11956     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11957     * updating a package that belongs to a shared user.
11958     *
11959     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11960     * adds unnecessary complexity.
11961     */
11962    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11963            PackageParser.Package scannedPackage) {
11964        String requiredInstructionSet = null;
11965        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11966            requiredInstructionSet = VMRuntime.getInstructionSet(
11967                     scannedPackage.applicationInfo.primaryCpuAbi);
11968        }
11969
11970        PackageSetting requirer = null;
11971        for (PackageSetting ps : packagesForUser) {
11972            // If packagesForUser contains scannedPackage, we skip it. This will happen
11973            // when scannedPackage is an update of an existing package. Without this check,
11974            // we will never be able to change the ABI of any package belonging to a shared
11975            // user, even if it's compatible with other packages.
11976            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11977                if (ps.primaryCpuAbiString == null) {
11978                    continue;
11979                }
11980
11981                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11982                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11983                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11984                    // this but there's not much we can do.
11985                    String errorMessage = "Instruction set mismatch, "
11986                            + ((requirer == null) ? "[caller]" : requirer)
11987                            + " requires " + requiredInstructionSet + " whereas " + ps
11988                            + " requires " + instructionSet;
11989                    Slog.w(TAG, errorMessage);
11990                }
11991
11992                if (requiredInstructionSet == null) {
11993                    requiredInstructionSet = instructionSet;
11994                    requirer = ps;
11995                }
11996            }
11997        }
11998
11999        if (requiredInstructionSet != null) {
12000            String adjustedAbi;
12001            if (requirer != null) {
12002                // requirer != null implies that either scannedPackage was null or that scannedPackage
12003                // did not require an ABI, in which case we have to adjust scannedPackage to match
12004                // the ABI of the set (which is the same as requirer's ABI)
12005                adjustedAbi = requirer.primaryCpuAbiString;
12006                if (scannedPackage != null) {
12007                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12008                }
12009            } else {
12010                // requirer == null implies that we're updating all ABIs in the set to
12011                // match scannedPackage.
12012                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
12013            }
12014
12015            for (PackageSetting ps : packagesForUser) {
12016                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12017                    if (ps.primaryCpuAbiString != null) {
12018                        continue;
12019                    }
12020
12021                    ps.primaryCpuAbiString = adjustedAbi;
12022                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12023                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12024                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12025                        if (DEBUG_ABI_SELECTION) {
12026                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12027                                    + " (requirer="
12028                                    + (requirer != null ? requirer.pkg : "null")
12029                                    + ", scannedPackage="
12030                                    + (scannedPackage != null ? scannedPackage : "null")
12031                                    + ")");
12032                        }
12033                        try {
12034                            mInstaller.rmdex(ps.codePathString,
12035                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
12036                        } catch (InstallerException ignored) {
12037                        }
12038                    }
12039                }
12040            }
12041        }
12042    }
12043
12044    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12045        synchronized (mPackages) {
12046            mResolverReplaced = true;
12047            // Set up information for custom user intent resolution activity.
12048            mResolveActivity.applicationInfo = pkg.applicationInfo;
12049            mResolveActivity.name = mCustomResolverComponentName.getClassName();
12050            mResolveActivity.packageName = pkg.applicationInfo.packageName;
12051            mResolveActivity.processName = pkg.applicationInfo.packageName;
12052            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12053            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12054                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12055            mResolveActivity.theme = 0;
12056            mResolveActivity.exported = true;
12057            mResolveActivity.enabled = true;
12058            mResolveInfo.activityInfo = mResolveActivity;
12059            mResolveInfo.priority = 0;
12060            mResolveInfo.preferredOrder = 0;
12061            mResolveInfo.match = 0;
12062            mResolveComponentName = mCustomResolverComponentName;
12063            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12064                    mResolveComponentName);
12065        }
12066    }
12067
12068    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12069        if (installerActivity == null) {
12070            if (DEBUG_EPHEMERAL) {
12071                Slog.d(TAG, "Clear ephemeral installer activity");
12072            }
12073            mInstantAppInstallerActivity = null;
12074            return;
12075        }
12076
12077        if (DEBUG_EPHEMERAL) {
12078            Slog.d(TAG, "Set ephemeral installer activity: "
12079                    + installerActivity.getComponentName());
12080        }
12081        // Set up information for ephemeral installer activity
12082        mInstantAppInstallerActivity = installerActivity;
12083        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12084                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12085        mInstantAppInstallerActivity.exported = true;
12086        mInstantAppInstallerActivity.enabled = true;
12087        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12088        mInstantAppInstallerInfo.priority = 0;
12089        mInstantAppInstallerInfo.preferredOrder = 1;
12090        mInstantAppInstallerInfo.isDefault = true;
12091        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12092                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12093    }
12094
12095    private static String calculateBundledApkRoot(final String codePathString) {
12096        final File codePath = new File(codePathString);
12097        final File codeRoot;
12098        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12099            codeRoot = Environment.getRootDirectory();
12100        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12101            codeRoot = Environment.getOemDirectory();
12102        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12103            codeRoot = Environment.getVendorDirectory();
12104        } else {
12105            // Unrecognized code path; take its top real segment as the apk root:
12106            // e.g. /something/app/blah.apk => /something
12107            try {
12108                File f = codePath.getCanonicalFile();
12109                File parent = f.getParentFile();    // non-null because codePath is a file
12110                File tmp;
12111                while ((tmp = parent.getParentFile()) != null) {
12112                    f = parent;
12113                    parent = tmp;
12114                }
12115                codeRoot = f;
12116                Slog.w(TAG, "Unrecognized code path "
12117                        + codePath + " - using " + codeRoot);
12118            } catch (IOException e) {
12119                // Can't canonicalize the code path -- shenanigans?
12120                Slog.w(TAG, "Can't canonicalize code path " + codePath);
12121                return Environment.getRootDirectory().getPath();
12122            }
12123        }
12124        return codeRoot.getPath();
12125    }
12126
12127    /**
12128     * Derive and set the location of native libraries for the given package,
12129     * which varies depending on where and how the package was installed.
12130     */
12131    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12132        final ApplicationInfo info = pkg.applicationInfo;
12133        final String codePath = pkg.codePath;
12134        final File codeFile = new File(codePath);
12135        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12136        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12137
12138        info.nativeLibraryRootDir = null;
12139        info.nativeLibraryRootRequiresIsa = false;
12140        info.nativeLibraryDir = null;
12141        info.secondaryNativeLibraryDir = null;
12142
12143        if (isApkFile(codeFile)) {
12144            // Monolithic install
12145            if (bundledApp) {
12146                // If "/system/lib64/apkname" exists, assume that is the per-package
12147                // native library directory to use; otherwise use "/system/lib/apkname".
12148                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12149                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12150                        getPrimaryInstructionSet(info));
12151
12152                // This is a bundled system app so choose the path based on the ABI.
12153                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12154                // is just the default path.
12155                final String apkName = deriveCodePathName(codePath);
12156                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12157                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12158                        apkName).getAbsolutePath();
12159
12160                if (info.secondaryCpuAbi != null) {
12161                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12162                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12163                            secondaryLibDir, apkName).getAbsolutePath();
12164                }
12165            } else if (asecApp) {
12166                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12167                        .getAbsolutePath();
12168            } else {
12169                final String apkName = deriveCodePathName(codePath);
12170                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12171                        .getAbsolutePath();
12172            }
12173
12174            info.nativeLibraryRootRequiresIsa = false;
12175            info.nativeLibraryDir = info.nativeLibraryRootDir;
12176        } else {
12177            // Cluster install
12178            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12179            info.nativeLibraryRootRequiresIsa = true;
12180
12181            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12182                    getPrimaryInstructionSet(info)).getAbsolutePath();
12183
12184            if (info.secondaryCpuAbi != null) {
12185                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12186                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12187            }
12188        }
12189    }
12190
12191    /**
12192     * Calculate the abis and roots for a bundled app. These can uniquely
12193     * be determined from the contents of the system partition, i.e whether
12194     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12195     * of this information, and instead assume that the system was built
12196     * sensibly.
12197     */
12198    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12199                                           PackageSetting pkgSetting) {
12200        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12201
12202        // If "/system/lib64/apkname" exists, assume that is the per-package
12203        // native library directory to use; otherwise use "/system/lib/apkname".
12204        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12205        setBundledAppAbi(pkg, apkRoot, apkName);
12206        // pkgSetting might be null during rescan following uninstall of updates
12207        // to a bundled app, so accommodate that possibility.  The settings in
12208        // that case will be established later from the parsed package.
12209        //
12210        // If the settings aren't null, sync them up with what we've just derived.
12211        // note that apkRoot isn't stored in the package settings.
12212        if (pkgSetting != null) {
12213            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12214            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12215        }
12216    }
12217
12218    /**
12219     * Deduces the ABI of a bundled app and sets the relevant fields on the
12220     * parsed pkg object.
12221     *
12222     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12223     *        under which system libraries are installed.
12224     * @param apkName the name of the installed package.
12225     */
12226    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12227        final File codeFile = new File(pkg.codePath);
12228
12229        final boolean has64BitLibs;
12230        final boolean has32BitLibs;
12231        if (isApkFile(codeFile)) {
12232            // Monolithic install
12233            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12234            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12235        } else {
12236            // Cluster install
12237            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12238            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12239                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12240                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12241                has64BitLibs = (new File(rootDir, isa)).exists();
12242            } else {
12243                has64BitLibs = false;
12244            }
12245            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12246                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12247                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12248                has32BitLibs = (new File(rootDir, isa)).exists();
12249            } else {
12250                has32BitLibs = false;
12251            }
12252        }
12253
12254        if (has64BitLibs && !has32BitLibs) {
12255            // The package has 64 bit libs, but not 32 bit libs. Its primary
12256            // ABI should be 64 bit. We can safely assume here that the bundled
12257            // native libraries correspond to the most preferred ABI in the list.
12258
12259            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12260            pkg.applicationInfo.secondaryCpuAbi = null;
12261        } else if (has32BitLibs && !has64BitLibs) {
12262            // The package has 32 bit libs but not 64 bit libs. Its primary
12263            // ABI should be 32 bit.
12264
12265            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12266            pkg.applicationInfo.secondaryCpuAbi = null;
12267        } else if (has32BitLibs && has64BitLibs) {
12268            // The application has both 64 and 32 bit bundled libraries. We check
12269            // here that the app declares multiArch support, and warn if it doesn't.
12270            //
12271            // We will be lenient here and record both ABIs. The primary will be the
12272            // ABI that's higher on the list, i.e, a device that's configured to prefer
12273            // 64 bit apps will see a 64 bit primary ABI,
12274
12275            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12276                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12277            }
12278
12279            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12280                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12281                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12282            } else {
12283                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12284                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12285            }
12286        } else {
12287            pkg.applicationInfo.primaryCpuAbi = null;
12288            pkg.applicationInfo.secondaryCpuAbi = null;
12289        }
12290    }
12291
12292    private void killApplication(String pkgName, int appId, String reason) {
12293        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12294    }
12295
12296    private void killApplication(String pkgName, int appId, int userId, String reason) {
12297        // Request the ActivityManager to kill the process(only for existing packages)
12298        // so that we do not end up in a confused state while the user is still using the older
12299        // version of the application while the new one gets installed.
12300        final long token = Binder.clearCallingIdentity();
12301        try {
12302            IActivityManager am = ActivityManager.getService();
12303            if (am != null) {
12304                try {
12305                    am.killApplication(pkgName, appId, userId, reason);
12306                } catch (RemoteException e) {
12307                }
12308            }
12309        } finally {
12310            Binder.restoreCallingIdentity(token);
12311        }
12312    }
12313
12314    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12315        // Remove the parent package setting
12316        PackageSetting ps = (PackageSetting) pkg.mExtras;
12317        if (ps != null) {
12318            removePackageLI(ps, chatty);
12319        }
12320        // Remove the child package setting
12321        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12322        for (int i = 0; i < childCount; i++) {
12323            PackageParser.Package childPkg = pkg.childPackages.get(i);
12324            ps = (PackageSetting) childPkg.mExtras;
12325            if (ps != null) {
12326                removePackageLI(ps, chatty);
12327            }
12328        }
12329    }
12330
12331    void removePackageLI(PackageSetting ps, boolean chatty) {
12332        if (DEBUG_INSTALL) {
12333            if (chatty)
12334                Log.d(TAG, "Removing package " + ps.name);
12335        }
12336
12337        // writer
12338        synchronized (mPackages) {
12339            mPackages.remove(ps.name);
12340            final PackageParser.Package pkg = ps.pkg;
12341            if (pkg != null) {
12342                cleanPackageDataStructuresLILPw(pkg, chatty);
12343            }
12344        }
12345    }
12346
12347    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12348        if (DEBUG_INSTALL) {
12349            if (chatty)
12350                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12351        }
12352
12353        // writer
12354        synchronized (mPackages) {
12355            // Remove the parent package
12356            mPackages.remove(pkg.applicationInfo.packageName);
12357            cleanPackageDataStructuresLILPw(pkg, chatty);
12358
12359            // Remove the child packages
12360            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12361            for (int i = 0; i < childCount; i++) {
12362                PackageParser.Package childPkg = pkg.childPackages.get(i);
12363                mPackages.remove(childPkg.applicationInfo.packageName);
12364                cleanPackageDataStructuresLILPw(childPkg, chatty);
12365            }
12366        }
12367    }
12368
12369    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12370        int N = pkg.providers.size();
12371        StringBuilder r = null;
12372        int i;
12373        for (i=0; i<N; i++) {
12374            PackageParser.Provider p = pkg.providers.get(i);
12375            mProviders.removeProvider(p);
12376            if (p.info.authority == null) {
12377
12378                /* There was another ContentProvider with this authority when
12379                 * this app was installed so this authority is null,
12380                 * Ignore it as we don't have to unregister the provider.
12381                 */
12382                continue;
12383            }
12384            String names[] = p.info.authority.split(";");
12385            for (int j = 0; j < names.length; j++) {
12386                if (mProvidersByAuthority.get(names[j]) == p) {
12387                    mProvidersByAuthority.remove(names[j]);
12388                    if (DEBUG_REMOVE) {
12389                        if (chatty)
12390                            Log.d(TAG, "Unregistered content provider: " + names[j]
12391                                    + ", className = " + p.info.name + ", isSyncable = "
12392                                    + p.info.isSyncable);
12393                    }
12394                }
12395            }
12396            if (DEBUG_REMOVE && chatty) {
12397                if (r == null) {
12398                    r = new StringBuilder(256);
12399                } else {
12400                    r.append(' ');
12401                }
12402                r.append(p.info.name);
12403            }
12404        }
12405        if (r != null) {
12406            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12407        }
12408
12409        N = pkg.services.size();
12410        r = null;
12411        for (i=0; i<N; i++) {
12412            PackageParser.Service s = pkg.services.get(i);
12413            mServices.removeService(s);
12414            if (chatty) {
12415                if (r == null) {
12416                    r = new StringBuilder(256);
12417                } else {
12418                    r.append(' ');
12419                }
12420                r.append(s.info.name);
12421            }
12422        }
12423        if (r != null) {
12424            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12425        }
12426
12427        N = pkg.receivers.size();
12428        r = null;
12429        for (i=0; i<N; i++) {
12430            PackageParser.Activity a = pkg.receivers.get(i);
12431            mReceivers.removeActivity(a, "receiver");
12432            if (DEBUG_REMOVE && chatty) {
12433                if (r == null) {
12434                    r = new StringBuilder(256);
12435                } else {
12436                    r.append(' ');
12437                }
12438                r.append(a.info.name);
12439            }
12440        }
12441        if (r != null) {
12442            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12443        }
12444
12445        N = pkg.activities.size();
12446        r = null;
12447        for (i=0; i<N; i++) {
12448            PackageParser.Activity a = pkg.activities.get(i);
12449            mActivities.removeActivity(a, "activity");
12450            if (DEBUG_REMOVE && chatty) {
12451                if (r == null) {
12452                    r = new StringBuilder(256);
12453                } else {
12454                    r.append(' ');
12455                }
12456                r.append(a.info.name);
12457            }
12458        }
12459        if (r != null) {
12460            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12461        }
12462
12463        N = pkg.permissions.size();
12464        r = null;
12465        for (i=0; i<N; i++) {
12466            PackageParser.Permission p = pkg.permissions.get(i);
12467            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12468            if (bp == null) {
12469                bp = mSettings.mPermissionTrees.get(p.info.name);
12470            }
12471            if (bp != null && bp.perm == p) {
12472                bp.perm = null;
12473                if (DEBUG_REMOVE && chatty) {
12474                    if (r == null) {
12475                        r = new StringBuilder(256);
12476                    } else {
12477                        r.append(' ');
12478                    }
12479                    r.append(p.info.name);
12480                }
12481            }
12482            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12483                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12484                if (appOpPkgs != null) {
12485                    appOpPkgs.remove(pkg.packageName);
12486                }
12487            }
12488        }
12489        if (r != null) {
12490            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12491        }
12492
12493        N = pkg.requestedPermissions.size();
12494        r = null;
12495        for (i=0; i<N; i++) {
12496            String perm = pkg.requestedPermissions.get(i);
12497            BasePermission bp = mSettings.mPermissions.get(perm);
12498            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12499                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12500                if (appOpPkgs != null) {
12501                    appOpPkgs.remove(pkg.packageName);
12502                    if (appOpPkgs.isEmpty()) {
12503                        mAppOpPermissionPackages.remove(perm);
12504                    }
12505                }
12506            }
12507        }
12508        if (r != null) {
12509            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12510        }
12511
12512        N = pkg.instrumentation.size();
12513        r = null;
12514        for (i=0; i<N; i++) {
12515            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12516            mInstrumentation.remove(a.getComponentName());
12517            if (DEBUG_REMOVE && chatty) {
12518                if (r == null) {
12519                    r = new StringBuilder(256);
12520                } else {
12521                    r.append(' ');
12522                }
12523                r.append(a.info.name);
12524            }
12525        }
12526        if (r != null) {
12527            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12528        }
12529
12530        r = null;
12531        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12532            // Only system apps can hold shared libraries.
12533            if (pkg.libraryNames != null) {
12534                for (i = 0; i < pkg.libraryNames.size(); i++) {
12535                    String name = pkg.libraryNames.get(i);
12536                    if (removeSharedLibraryLPw(name, 0)) {
12537                        if (DEBUG_REMOVE && chatty) {
12538                            if (r == null) {
12539                                r = new StringBuilder(256);
12540                            } else {
12541                                r.append(' ');
12542                            }
12543                            r.append(name);
12544                        }
12545                    }
12546                }
12547            }
12548        }
12549
12550        r = null;
12551
12552        // Any package can hold static shared libraries.
12553        if (pkg.staticSharedLibName != null) {
12554            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12555                if (DEBUG_REMOVE && chatty) {
12556                    if (r == null) {
12557                        r = new StringBuilder(256);
12558                    } else {
12559                        r.append(' ');
12560                    }
12561                    r.append(pkg.staticSharedLibName);
12562                }
12563            }
12564        }
12565
12566        if (r != null) {
12567            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12568        }
12569    }
12570
12571    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12572        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12573            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12574                return true;
12575            }
12576        }
12577        return false;
12578    }
12579
12580    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12581    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12582    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12583
12584    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12585        // Update the parent permissions
12586        updatePermissionsLPw(pkg.packageName, pkg, flags);
12587        // Update the child permissions
12588        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12589        for (int i = 0; i < childCount; i++) {
12590            PackageParser.Package childPkg = pkg.childPackages.get(i);
12591            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12592        }
12593    }
12594
12595    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12596            int flags) {
12597        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12598        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12599    }
12600
12601    private void updatePermissionsLPw(String changingPkg,
12602            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12603        // Make sure there are no dangling permission trees.
12604        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12605        while (it.hasNext()) {
12606            final BasePermission bp = it.next();
12607            if (bp.packageSetting == null) {
12608                // We may not yet have parsed the package, so just see if
12609                // we still know about its settings.
12610                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12611            }
12612            if (bp.packageSetting == null) {
12613                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12614                        + " from package " + bp.sourcePackage);
12615                it.remove();
12616            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12617                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12618                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12619                            + " from package " + bp.sourcePackage);
12620                    flags |= UPDATE_PERMISSIONS_ALL;
12621                    it.remove();
12622                }
12623            }
12624        }
12625
12626        // Make sure all dynamic permissions have been assigned to a package,
12627        // and make sure there are no dangling permissions.
12628        it = mSettings.mPermissions.values().iterator();
12629        while (it.hasNext()) {
12630            final BasePermission bp = it.next();
12631            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12632                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12633                        + bp.name + " pkg=" + bp.sourcePackage
12634                        + " info=" + bp.pendingInfo);
12635                if (bp.packageSetting == null && bp.pendingInfo != null) {
12636                    final BasePermission tree = findPermissionTreeLP(bp.name);
12637                    if (tree != null && tree.perm != null) {
12638                        bp.packageSetting = tree.packageSetting;
12639                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12640                                new PermissionInfo(bp.pendingInfo));
12641                        bp.perm.info.packageName = tree.perm.info.packageName;
12642                        bp.perm.info.name = bp.name;
12643                        bp.uid = tree.uid;
12644                    }
12645                }
12646            }
12647            if (bp.packageSetting == null) {
12648                // We may not yet have parsed the package, so just see if
12649                // we still know about its settings.
12650                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12651            }
12652            if (bp.packageSetting == null) {
12653                Slog.w(TAG, "Removing dangling permission: " + bp.name
12654                        + " from package " + bp.sourcePackage);
12655                it.remove();
12656            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12657                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12658                    Slog.i(TAG, "Removing old permission: " + bp.name
12659                            + " from package " + bp.sourcePackage);
12660                    flags |= UPDATE_PERMISSIONS_ALL;
12661                    it.remove();
12662                }
12663            }
12664        }
12665
12666        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12667        // Now update the permissions for all packages, in particular
12668        // replace the granted permissions of the system packages.
12669        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12670            for (PackageParser.Package pkg : mPackages.values()) {
12671                if (pkg != pkgInfo) {
12672                    // Only replace for packages on requested volume
12673                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12674                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12675                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12676                    grantPermissionsLPw(pkg, replace, changingPkg);
12677                }
12678            }
12679        }
12680
12681        if (pkgInfo != null) {
12682            // Only replace for packages on requested volume
12683            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12684            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12685                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12686            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12687        }
12688        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12689    }
12690
12691    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12692            String packageOfInterest) {
12693        // IMPORTANT: There are two types of permissions: install and runtime.
12694        // Install time permissions are granted when the app is installed to
12695        // all device users and users added in the future. Runtime permissions
12696        // are granted at runtime explicitly to specific users. Normal and signature
12697        // protected permissions are install time permissions. Dangerous permissions
12698        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12699        // otherwise they are runtime permissions. This function does not manage
12700        // runtime permissions except for the case an app targeting Lollipop MR1
12701        // being upgraded to target a newer SDK, in which case dangerous permissions
12702        // are transformed from install time to runtime ones.
12703
12704        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12705        if (ps == null) {
12706            return;
12707        }
12708
12709        PermissionsState permissionsState = ps.getPermissionsState();
12710        PermissionsState origPermissions = permissionsState;
12711
12712        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12713
12714        boolean runtimePermissionsRevoked = false;
12715        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12716
12717        boolean changedInstallPermission = false;
12718
12719        if (replace) {
12720            ps.installPermissionsFixed = false;
12721            if (!ps.isSharedUser()) {
12722                origPermissions = new PermissionsState(permissionsState);
12723                permissionsState.reset();
12724            } else {
12725                // We need to know only about runtime permission changes since the
12726                // calling code always writes the install permissions state but
12727                // the runtime ones are written only if changed. The only cases of
12728                // changed runtime permissions here are promotion of an install to
12729                // runtime and revocation of a runtime from a shared user.
12730                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12731                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12732                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12733                    runtimePermissionsRevoked = true;
12734                }
12735            }
12736        }
12737
12738        permissionsState.setGlobalGids(mGlobalGids);
12739
12740        final int N = pkg.requestedPermissions.size();
12741        for (int i=0; i<N; i++) {
12742            final String name = pkg.requestedPermissions.get(i);
12743            final BasePermission bp = mSettings.mPermissions.get(name);
12744            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12745                    >= Build.VERSION_CODES.M;
12746
12747            if (DEBUG_INSTALL) {
12748                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12749            }
12750
12751            if (bp == null || bp.packageSetting == null) {
12752                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12753                    if (DEBUG_PERMISSIONS) {
12754                        Slog.i(TAG, "Unknown permission " + name
12755                                + " in package " + pkg.packageName);
12756                    }
12757                }
12758                continue;
12759            }
12760
12761
12762            // Limit ephemeral apps to ephemeral allowed permissions.
12763            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12764                if (DEBUG_PERMISSIONS) {
12765                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
12766                            + pkg.packageName);
12767                }
12768                continue;
12769            }
12770
12771            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12772                if (DEBUG_PERMISSIONS) {
12773                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
12774                            + pkg.packageName);
12775                }
12776                continue;
12777            }
12778
12779            final String perm = bp.name;
12780            boolean allowedSig = false;
12781            int grant = GRANT_DENIED;
12782
12783            // Keep track of app op permissions.
12784            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12785                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12786                if (pkgs == null) {
12787                    pkgs = new ArraySet<>();
12788                    mAppOpPermissionPackages.put(bp.name, pkgs);
12789                }
12790                pkgs.add(pkg.packageName);
12791            }
12792
12793            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12794            switch (level) {
12795                case PermissionInfo.PROTECTION_NORMAL: {
12796                    // For all apps normal permissions are install time ones.
12797                    grant = GRANT_INSTALL;
12798                } break;
12799
12800                case PermissionInfo.PROTECTION_DANGEROUS: {
12801                    // If a permission review is required for legacy apps we represent
12802                    // their permissions as always granted runtime ones since we need
12803                    // to keep the review required permission flag per user while an
12804                    // install permission's state is shared across all users.
12805                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12806                        // For legacy apps dangerous permissions are install time ones.
12807                        grant = GRANT_INSTALL;
12808                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12809                        // For legacy apps that became modern, install becomes runtime.
12810                        grant = GRANT_UPGRADE;
12811                    } else if (mPromoteSystemApps
12812                            && isSystemApp(ps)
12813                            && mExistingSystemPackages.contains(ps.name)) {
12814                        // For legacy system apps, install becomes runtime.
12815                        // We cannot check hasInstallPermission() for system apps since those
12816                        // permissions were granted implicitly and not persisted pre-M.
12817                        grant = GRANT_UPGRADE;
12818                    } else {
12819                        // For modern apps keep runtime permissions unchanged.
12820                        grant = GRANT_RUNTIME;
12821                    }
12822                } break;
12823
12824                case PermissionInfo.PROTECTION_SIGNATURE: {
12825                    // For all apps signature permissions are install time ones.
12826                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12827                    if (allowedSig) {
12828                        grant = GRANT_INSTALL;
12829                    }
12830                } break;
12831            }
12832
12833            if (DEBUG_PERMISSIONS) {
12834                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12835            }
12836
12837            if (grant != GRANT_DENIED) {
12838                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12839                    // If this is an existing, non-system package, then
12840                    // we can't add any new permissions to it.
12841                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12842                        // Except...  if this is a permission that was added
12843                        // to the platform (note: need to only do this when
12844                        // updating the platform).
12845                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12846                            grant = GRANT_DENIED;
12847                        }
12848                    }
12849                }
12850
12851                switch (grant) {
12852                    case GRANT_INSTALL: {
12853                        // Revoke this as runtime permission to handle the case of
12854                        // a runtime permission being downgraded to an install one.
12855                        // Also in permission review mode we keep dangerous permissions
12856                        // for legacy apps
12857                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12858                            if (origPermissions.getRuntimePermissionState(
12859                                    bp.name, userId) != null) {
12860                                // Revoke the runtime permission and clear the flags.
12861                                origPermissions.revokeRuntimePermission(bp, userId);
12862                                origPermissions.updatePermissionFlags(bp, userId,
12863                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12864                                // If we revoked a permission permission, we have to write.
12865                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12866                                        changedRuntimePermissionUserIds, userId);
12867                            }
12868                        }
12869                        // Grant an install permission.
12870                        if (permissionsState.grantInstallPermission(bp) !=
12871                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12872                            changedInstallPermission = true;
12873                        }
12874                    } break;
12875
12876                    case GRANT_RUNTIME: {
12877                        // Grant previously granted runtime permissions.
12878                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12879                            PermissionState permissionState = origPermissions
12880                                    .getRuntimePermissionState(bp.name, userId);
12881                            int flags = permissionState != null
12882                                    ? permissionState.getFlags() : 0;
12883                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12884                                // Don't propagate the permission in a permission review mode if
12885                                // the former was revoked, i.e. marked to not propagate on upgrade.
12886                                // Note that in a permission review mode install permissions are
12887                                // represented as constantly granted runtime ones since we need to
12888                                // keep a per user state associated with the permission. Also the
12889                                // revoke on upgrade flag is no longer applicable and is reset.
12890                                final boolean revokeOnUpgrade = (flags & PackageManager
12891                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12892                                if (revokeOnUpgrade) {
12893                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12894                                    // Since we changed the flags, we have to write.
12895                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12896                                            changedRuntimePermissionUserIds, userId);
12897                                }
12898                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12899                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12900                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12901                                        // If we cannot put the permission as it was,
12902                                        // we have to write.
12903                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12904                                                changedRuntimePermissionUserIds, userId);
12905                                    }
12906                                }
12907
12908                                // If the app supports runtime permissions no need for a review.
12909                                if (mPermissionReviewRequired
12910                                        && appSupportsRuntimePermissions
12911                                        && (flags & PackageManager
12912                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12913                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12914                                    // Since we changed the flags, we have to write.
12915                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12916                                            changedRuntimePermissionUserIds, userId);
12917                                }
12918                            } else if (mPermissionReviewRequired
12919                                    && !appSupportsRuntimePermissions) {
12920                                // For legacy apps that need a permission review, every new
12921                                // runtime permission is granted but it is pending a review.
12922                                // We also need to review only platform defined runtime
12923                                // permissions as these are the only ones the platform knows
12924                                // how to disable the API to simulate revocation as legacy
12925                                // apps don't expect to run with revoked permissions.
12926                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12927                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12928                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12929                                        // We changed the flags, hence have to write.
12930                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12931                                                changedRuntimePermissionUserIds, userId);
12932                                    }
12933                                }
12934                                if (permissionsState.grantRuntimePermission(bp, userId)
12935                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12936                                    // We changed the permission, hence have to write.
12937                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12938                                            changedRuntimePermissionUserIds, userId);
12939                                }
12940                            }
12941                            // Propagate the permission flags.
12942                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12943                        }
12944                    } break;
12945
12946                    case GRANT_UPGRADE: {
12947                        // Grant runtime permissions for a previously held install permission.
12948                        PermissionState permissionState = origPermissions
12949                                .getInstallPermissionState(bp.name);
12950                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12951
12952                        if (origPermissions.revokeInstallPermission(bp)
12953                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12954                            // We will be transferring the permission flags, so clear them.
12955                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12956                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12957                            changedInstallPermission = true;
12958                        }
12959
12960                        // If the permission is not to be promoted to runtime we ignore it and
12961                        // also its other flags as they are not applicable to install permissions.
12962                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12963                            for (int userId : currentUserIds) {
12964                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12965                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12966                                    // Transfer the permission flags.
12967                                    permissionsState.updatePermissionFlags(bp, userId,
12968                                            flags, flags);
12969                                    // If we granted the permission, we have to write.
12970                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12971                                            changedRuntimePermissionUserIds, userId);
12972                                }
12973                            }
12974                        }
12975                    } break;
12976
12977                    default: {
12978                        if (packageOfInterest == null
12979                                || packageOfInterest.equals(pkg.packageName)) {
12980                            if (DEBUG_PERMISSIONS) {
12981                                Slog.i(TAG, "Not granting permission " + perm
12982                                        + " to package " + pkg.packageName
12983                                        + " because it was previously installed without");
12984                            }
12985                        }
12986                    } break;
12987                }
12988            } else {
12989                if (permissionsState.revokeInstallPermission(bp) !=
12990                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12991                    // Also drop the permission flags.
12992                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12993                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12994                    changedInstallPermission = true;
12995                    Slog.i(TAG, "Un-granting permission " + perm
12996                            + " from package " + pkg.packageName
12997                            + " (protectionLevel=" + bp.protectionLevel
12998                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12999                            + ")");
13000                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
13001                    // Don't print warning for app op permissions, since it is fine for them
13002                    // not to be granted, there is a UI for the user to decide.
13003                    if (DEBUG_PERMISSIONS
13004                            && (packageOfInterest == null
13005                                    || packageOfInterest.equals(pkg.packageName))) {
13006                        Slog.i(TAG, "Not granting permission " + perm
13007                                + " to package " + pkg.packageName
13008                                + " (protectionLevel=" + bp.protectionLevel
13009                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13010                                + ")");
13011                    }
13012                }
13013            }
13014        }
13015
13016        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13017                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13018            // This is the first that we have heard about this package, so the
13019            // permissions we have now selected are fixed until explicitly
13020            // changed.
13021            ps.installPermissionsFixed = true;
13022        }
13023
13024        // Persist the runtime permissions state for users with changes. If permissions
13025        // were revoked because no app in the shared user declares them we have to
13026        // write synchronously to avoid losing runtime permissions state.
13027        for (int userId : changedRuntimePermissionUserIds) {
13028            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13029        }
13030    }
13031
13032    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13033        boolean allowed = false;
13034        final int NP = PackageParser.NEW_PERMISSIONS.length;
13035        for (int ip=0; ip<NP; ip++) {
13036            final PackageParser.NewPermissionInfo npi
13037                    = PackageParser.NEW_PERMISSIONS[ip];
13038            if (npi.name.equals(perm)
13039                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13040                allowed = true;
13041                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13042                        + pkg.packageName);
13043                break;
13044            }
13045        }
13046        return allowed;
13047    }
13048
13049    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13050            BasePermission bp, PermissionsState origPermissions) {
13051        boolean privilegedPermission = (bp.protectionLevel
13052                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13053        boolean privappPermissionsDisable =
13054                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13055        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13056        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13057        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13058                && !platformPackage && platformPermission) {
13059            ArraySet<String> wlPermissions = SystemConfig.getInstance()
13060                    .getPrivAppPermissions(pkg.packageName);
13061            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
13062            if (!whitelisted) {
13063                Slog.w(TAG, "Privileged permission " + perm + " for package "
13064                        + pkg.packageName + " - not in privapp-permissions whitelist");
13065                // Only report violations for apps on system image
13066                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13067                    if (mPrivappPermissionsViolations == null) {
13068                        mPrivappPermissionsViolations = new ArraySet<>();
13069                    }
13070                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13071                }
13072                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13073                    return false;
13074                }
13075            }
13076        }
13077        boolean allowed = (compareSignatures(
13078                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13079                        == PackageManager.SIGNATURE_MATCH)
13080                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13081                        == PackageManager.SIGNATURE_MATCH);
13082        if (!allowed && privilegedPermission) {
13083            if (isSystemApp(pkg)) {
13084                // For updated system applications, a system permission
13085                // is granted only if it had been defined by the original application.
13086                if (pkg.isUpdatedSystemApp()) {
13087                    final PackageSetting sysPs = mSettings
13088                            .getDisabledSystemPkgLPr(pkg.packageName);
13089                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13090                        // If the original was granted this permission, we take
13091                        // that grant decision as read and propagate it to the
13092                        // update.
13093                        if (sysPs.isPrivileged()) {
13094                            allowed = true;
13095                        }
13096                    } else {
13097                        // The system apk may have been updated with an older
13098                        // version of the one on the data partition, but which
13099                        // granted a new system permission that it didn't have
13100                        // before.  In this case we do want to allow the app to
13101                        // now get the new permission if the ancestral apk is
13102                        // privileged to get it.
13103                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13104                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13105                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13106                                    allowed = true;
13107                                    break;
13108                                }
13109                            }
13110                        }
13111                        // Also if a privileged parent package on the system image or any of
13112                        // its children requested a privileged permission, the updated child
13113                        // packages can also get the permission.
13114                        if (pkg.parentPackage != null) {
13115                            final PackageSetting disabledSysParentPs = mSettings
13116                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13117                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13118                                    && disabledSysParentPs.isPrivileged()) {
13119                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13120                                    allowed = true;
13121                                } else if (disabledSysParentPs.pkg.childPackages != null) {
13122                                    final int count = disabledSysParentPs.pkg.childPackages.size();
13123                                    for (int i = 0; i < count; i++) {
13124                                        PackageParser.Package disabledSysChildPkg =
13125                                                disabledSysParentPs.pkg.childPackages.get(i);
13126                                        if (isPackageRequestingPermission(disabledSysChildPkg,
13127                                                perm)) {
13128                                            allowed = true;
13129                                            break;
13130                                        }
13131                                    }
13132                                }
13133                            }
13134                        }
13135                    }
13136                } else {
13137                    allowed = isPrivilegedApp(pkg);
13138                }
13139            }
13140        }
13141        if (!allowed) {
13142            if (!allowed && (bp.protectionLevel
13143                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13144                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13145                // If this was a previously normal/dangerous permission that got moved
13146                // to a system permission as part of the runtime permission redesign, then
13147                // we still want to blindly grant it to old apps.
13148                allowed = true;
13149            }
13150            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13151                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
13152                // If this permission is to be granted to the system installer and
13153                // this app is an installer, then it gets the permission.
13154                allowed = true;
13155            }
13156            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13157                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
13158                // If this permission is to be granted to the system verifier and
13159                // this app is a verifier, then it gets the permission.
13160                allowed = true;
13161            }
13162            if (!allowed && (bp.protectionLevel
13163                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13164                    && isSystemApp(pkg)) {
13165                // Any pre-installed system app is allowed to get this permission.
13166                allowed = true;
13167            }
13168            if (!allowed && (bp.protectionLevel
13169                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13170                // For development permissions, a development permission
13171                // is granted only if it was already granted.
13172                allowed = origPermissions.hasInstallPermission(perm);
13173            }
13174            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13175                    && pkg.packageName.equals(mSetupWizardPackage)) {
13176                // If this permission is to be granted to the system setup wizard and
13177                // this app is a setup wizard, then it gets the permission.
13178                allowed = true;
13179            }
13180        }
13181        return allowed;
13182    }
13183
13184    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13185        final int permCount = pkg.requestedPermissions.size();
13186        for (int j = 0; j < permCount; j++) {
13187            String requestedPermission = pkg.requestedPermissions.get(j);
13188            if (permission.equals(requestedPermission)) {
13189                return true;
13190            }
13191        }
13192        return false;
13193    }
13194
13195    final class ActivityIntentResolver
13196            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13197        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13198                boolean defaultOnly, int userId) {
13199            if (!sUserManager.exists(userId)) return null;
13200            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13201            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13202        }
13203
13204        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13205                int userId) {
13206            if (!sUserManager.exists(userId)) return null;
13207            mFlags = flags;
13208            return super.queryIntent(intent, resolvedType,
13209                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13210                    userId);
13211        }
13212
13213        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13214                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13215            if (!sUserManager.exists(userId)) return null;
13216            if (packageActivities == null) {
13217                return null;
13218            }
13219            mFlags = flags;
13220            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13221            final int N = packageActivities.size();
13222            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13223                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13224
13225            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13226            for (int i = 0; i < N; ++i) {
13227                intentFilters = packageActivities.get(i).intents;
13228                if (intentFilters != null && intentFilters.size() > 0) {
13229                    PackageParser.ActivityIntentInfo[] array =
13230                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
13231                    intentFilters.toArray(array);
13232                    listCut.add(array);
13233                }
13234            }
13235            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13236        }
13237
13238        /**
13239         * Finds a privileged activity that matches the specified activity names.
13240         */
13241        private PackageParser.Activity findMatchingActivity(
13242                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13243            for (PackageParser.Activity sysActivity : activityList) {
13244                if (sysActivity.info.name.equals(activityInfo.name)) {
13245                    return sysActivity;
13246                }
13247                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13248                    return sysActivity;
13249                }
13250                if (sysActivity.info.targetActivity != null) {
13251                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13252                        return sysActivity;
13253                    }
13254                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13255                        return sysActivity;
13256                    }
13257                }
13258            }
13259            return null;
13260        }
13261
13262        public class IterGenerator<E> {
13263            public Iterator<E> generate(ActivityIntentInfo info) {
13264                return null;
13265            }
13266        }
13267
13268        public class ActionIterGenerator extends IterGenerator<String> {
13269            @Override
13270            public Iterator<String> generate(ActivityIntentInfo info) {
13271                return info.actionsIterator();
13272            }
13273        }
13274
13275        public class CategoriesIterGenerator extends IterGenerator<String> {
13276            @Override
13277            public Iterator<String> generate(ActivityIntentInfo info) {
13278                return info.categoriesIterator();
13279            }
13280        }
13281
13282        public class SchemesIterGenerator extends IterGenerator<String> {
13283            @Override
13284            public Iterator<String> generate(ActivityIntentInfo info) {
13285                return info.schemesIterator();
13286            }
13287        }
13288
13289        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13290            @Override
13291            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13292                return info.authoritiesIterator();
13293            }
13294        }
13295
13296        /**
13297         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13298         * MODIFIED. Do not pass in a list that should not be changed.
13299         */
13300        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13301                IterGenerator<T> generator, Iterator<T> searchIterator) {
13302            // loop through the set of actions; every one must be found in the intent filter
13303            while (searchIterator.hasNext()) {
13304                // we must have at least one filter in the list to consider a match
13305                if (intentList.size() == 0) {
13306                    break;
13307                }
13308
13309                final T searchAction = searchIterator.next();
13310
13311                // loop through the set of intent filters
13312                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13313                while (intentIter.hasNext()) {
13314                    final ActivityIntentInfo intentInfo = intentIter.next();
13315                    boolean selectionFound = false;
13316
13317                    // loop through the intent filter's selection criteria; at least one
13318                    // of them must match the searched criteria
13319                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13320                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13321                        final T intentSelection = intentSelectionIter.next();
13322                        if (intentSelection != null && intentSelection.equals(searchAction)) {
13323                            selectionFound = true;
13324                            break;
13325                        }
13326                    }
13327
13328                    // the selection criteria wasn't found in this filter's set; this filter
13329                    // is not a potential match
13330                    if (!selectionFound) {
13331                        intentIter.remove();
13332                    }
13333                }
13334            }
13335        }
13336
13337        private boolean isProtectedAction(ActivityIntentInfo filter) {
13338            final Iterator<String> actionsIter = filter.actionsIterator();
13339            while (actionsIter != null && actionsIter.hasNext()) {
13340                final String filterAction = actionsIter.next();
13341                if (PROTECTED_ACTIONS.contains(filterAction)) {
13342                    return true;
13343                }
13344            }
13345            return false;
13346        }
13347
13348        /**
13349         * Adjusts the priority of the given intent filter according to policy.
13350         * <p>
13351         * <ul>
13352         * <li>The priority for non privileged applications is capped to '0'</li>
13353         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13354         * <li>The priority for unbundled updates to privileged applications is capped to the
13355         *      priority defined on the system partition</li>
13356         * </ul>
13357         * <p>
13358         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13359         * allowed to obtain any priority on any action.
13360         */
13361        private void adjustPriority(
13362                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13363            // nothing to do; priority is fine as-is
13364            if (intent.getPriority() <= 0) {
13365                return;
13366            }
13367
13368            final ActivityInfo activityInfo = intent.activity.info;
13369            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13370
13371            final boolean privilegedApp =
13372                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13373            if (!privilegedApp) {
13374                // non-privileged applications can never define a priority >0
13375                if (DEBUG_FILTERS) {
13376                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13377                            + " package: " + applicationInfo.packageName
13378                            + " activity: " + intent.activity.className
13379                            + " origPrio: " + intent.getPriority());
13380                }
13381                intent.setPriority(0);
13382                return;
13383            }
13384
13385            if (systemActivities == null) {
13386                // the system package is not disabled; we're parsing the system partition
13387                if (isProtectedAction(intent)) {
13388                    if (mDeferProtectedFilters) {
13389                        // We can't deal with these just yet. No component should ever obtain a
13390                        // >0 priority for a protected actions, with ONE exception -- the setup
13391                        // wizard. The setup wizard, however, cannot be known until we're able to
13392                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13393                        // until all intent filters have been processed. Chicken, meet egg.
13394                        // Let the filter temporarily have a high priority and rectify the
13395                        // priorities after all system packages have been scanned.
13396                        mProtectedFilters.add(intent);
13397                        if (DEBUG_FILTERS) {
13398                            Slog.i(TAG, "Protected action; save for later;"
13399                                    + " package: " + applicationInfo.packageName
13400                                    + " activity: " + intent.activity.className
13401                                    + " origPrio: " + intent.getPriority());
13402                        }
13403                        return;
13404                    } else {
13405                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13406                            Slog.i(TAG, "No setup wizard;"
13407                                + " All protected intents capped to priority 0");
13408                        }
13409                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13410                            if (DEBUG_FILTERS) {
13411                                Slog.i(TAG, "Found setup wizard;"
13412                                    + " allow priority " + intent.getPriority() + ";"
13413                                    + " package: " + intent.activity.info.packageName
13414                                    + " activity: " + intent.activity.className
13415                                    + " priority: " + intent.getPriority());
13416                            }
13417                            // setup wizard gets whatever it wants
13418                            return;
13419                        }
13420                        if (DEBUG_FILTERS) {
13421                            Slog.i(TAG, "Protected action; cap priority to 0;"
13422                                    + " package: " + intent.activity.info.packageName
13423                                    + " activity: " + intent.activity.className
13424                                    + " origPrio: " + intent.getPriority());
13425                        }
13426                        intent.setPriority(0);
13427                        return;
13428                    }
13429                }
13430                // privileged apps on the system image get whatever priority they request
13431                return;
13432            }
13433
13434            // privileged app unbundled update ... try to find the same activity
13435            final PackageParser.Activity foundActivity =
13436                    findMatchingActivity(systemActivities, activityInfo);
13437            if (foundActivity == null) {
13438                // this is a new activity; it cannot obtain >0 priority
13439                if (DEBUG_FILTERS) {
13440                    Slog.i(TAG, "New activity; cap priority to 0;"
13441                            + " package: " + applicationInfo.packageName
13442                            + " activity: " + intent.activity.className
13443                            + " origPrio: " + intent.getPriority());
13444                }
13445                intent.setPriority(0);
13446                return;
13447            }
13448
13449            // found activity, now check for filter equivalence
13450
13451            // a shallow copy is enough; we modify the list, not its contents
13452            final List<ActivityIntentInfo> intentListCopy =
13453                    new ArrayList<>(foundActivity.intents);
13454            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13455
13456            // find matching action subsets
13457            final Iterator<String> actionsIterator = intent.actionsIterator();
13458            if (actionsIterator != null) {
13459                getIntentListSubset(
13460                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13461                if (intentListCopy.size() == 0) {
13462                    // no more intents to match; we're not equivalent
13463                    if (DEBUG_FILTERS) {
13464                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13465                                + " package: " + applicationInfo.packageName
13466                                + " activity: " + intent.activity.className
13467                                + " origPrio: " + intent.getPriority());
13468                    }
13469                    intent.setPriority(0);
13470                    return;
13471                }
13472            }
13473
13474            // find matching category subsets
13475            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13476            if (categoriesIterator != null) {
13477                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13478                        categoriesIterator);
13479                if (intentListCopy.size() == 0) {
13480                    // no more intents to match; we're not equivalent
13481                    if (DEBUG_FILTERS) {
13482                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13483                                + " package: " + applicationInfo.packageName
13484                                + " activity: " + intent.activity.className
13485                                + " origPrio: " + intent.getPriority());
13486                    }
13487                    intent.setPriority(0);
13488                    return;
13489                }
13490            }
13491
13492            // find matching schemes subsets
13493            final Iterator<String> schemesIterator = intent.schemesIterator();
13494            if (schemesIterator != null) {
13495                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13496                        schemesIterator);
13497                if (intentListCopy.size() == 0) {
13498                    // no more intents to match; we're not equivalent
13499                    if (DEBUG_FILTERS) {
13500                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13501                                + " package: " + applicationInfo.packageName
13502                                + " activity: " + intent.activity.className
13503                                + " origPrio: " + intent.getPriority());
13504                    }
13505                    intent.setPriority(0);
13506                    return;
13507                }
13508            }
13509
13510            // find matching authorities subsets
13511            final Iterator<IntentFilter.AuthorityEntry>
13512                    authoritiesIterator = intent.authoritiesIterator();
13513            if (authoritiesIterator != null) {
13514                getIntentListSubset(intentListCopy,
13515                        new AuthoritiesIterGenerator(),
13516                        authoritiesIterator);
13517                if (intentListCopy.size() == 0) {
13518                    // no more intents to match; we're not equivalent
13519                    if (DEBUG_FILTERS) {
13520                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13521                                + " package: " + applicationInfo.packageName
13522                                + " activity: " + intent.activity.className
13523                                + " origPrio: " + intent.getPriority());
13524                    }
13525                    intent.setPriority(0);
13526                    return;
13527                }
13528            }
13529
13530            // we found matching filter(s); app gets the max priority of all intents
13531            int cappedPriority = 0;
13532            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13533                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13534            }
13535            if (intent.getPriority() > cappedPriority) {
13536                if (DEBUG_FILTERS) {
13537                    Slog.i(TAG, "Found matching filter(s);"
13538                            + " cap priority to " + cappedPriority + ";"
13539                            + " package: " + applicationInfo.packageName
13540                            + " activity: " + intent.activity.className
13541                            + " origPrio: " + intent.getPriority());
13542                }
13543                intent.setPriority(cappedPriority);
13544                return;
13545            }
13546            // all this for nothing; the requested priority was <= what was on the system
13547        }
13548
13549        public final void addActivity(PackageParser.Activity a, String type) {
13550            mActivities.put(a.getComponentName(), a);
13551            if (DEBUG_SHOW_INFO)
13552                Log.v(
13553                TAG, "  " + type + " " +
13554                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13555            if (DEBUG_SHOW_INFO)
13556                Log.v(TAG, "    Class=" + a.info.name);
13557            final int NI = a.intents.size();
13558            for (int j=0; j<NI; j++) {
13559                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13560                if ("activity".equals(type)) {
13561                    final PackageSetting ps =
13562                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13563                    final List<PackageParser.Activity> systemActivities =
13564                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13565                    adjustPriority(systemActivities, intent);
13566                }
13567                if (DEBUG_SHOW_INFO) {
13568                    Log.v(TAG, "    IntentFilter:");
13569                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13570                }
13571                if (!intent.debugCheck()) {
13572                    Log.w(TAG, "==> For Activity " + a.info.name);
13573                }
13574                addFilter(intent);
13575            }
13576        }
13577
13578        public final void removeActivity(PackageParser.Activity a, String type) {
13579            mActivities.remove(a.getComponentName());
13580            if (DEBUG_SHOW_INFO) {
13581                Log.v(TAG, "  " + type + " "
13582                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13583                                : a.info.name) + ":");
13584                Log.v(TAG, "    Class=" + a.info.name);
13585            }
13586            final int NI = a.intents.size();
13587            for (int j=0; j<NI; j++) {
13588                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13589                if (DEBUG_SHOW_INFO) {
13590                    Log.v(TAG, "    IntentFilter:");
13591                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13592                }
13593                removeFilter(intent);
13594            }
13595        }
13596
13597        @Override
13598        protected boolean allowFilterResult(
13599                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13600            ActivityInfo filterAi = filter.activity.info;
13601            for (int i=dest.size()-1; i>=0; i--) {
13602                ActivityInfo destAi = dest.get(i).activityInfo;
13603                if (destAi.name == filterAi.name
13604                        && destAi.packageName == filterAi.packageName) {
13605                    return false;
13606                }
13607            }
13608            return true;
13609        }
13610
13611        @Override
13612        protected ActivityIntentInfo[] newArray(int size) {
13613            return new ActivityIntentInfo[size];
13614        }
13615
13616        @Override
13617        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13618            if (!sUserManager.exists(userId)) return true;
13619            PackageParser.Package p = filter.activity.owner;
13620            if (p != null) {
13621                PackageSetting ps = (PackageSetting)p.mExtras;
13622                if (ps != null) {
13623                    // System apps are never considered stopped for purposes of
13624                    // filtering, because there may be no way for the user to
13625                    // actually re-launch them.
13626                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13627                            && ps.getStopped(userId);
13628                }
13629            }
13630            return false;
13631        }
13632
13633        @Override
13634        protected boolean isPackageForFilter(String packageName,
13635                PackageParser.ActivityIntentInfo info) {
13636            return packageName.equals(info.activity.owner.packageName);
13637        }
13638
13639        @Override
13640        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13641                int match, int userId) {
13642            if (!sUserManager.exists(userId)) return null;
13643            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13644                return null;
13645            }
13646            final PackageParser.Activity activity = info.activity;
13647            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13648            if (ps == null) {
13649                return null;
13650            }
13651            final PackageUserState userState = ps.readUserState(userId);
13652            ActivityInfo ai =
13653                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13654            if (ai == null) {
13655                return null;
13656            }
13657            final boolean matchExplicitlyVisibleOnly =
13658                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13659            final boolean matchVisibleToInstantApp =
13660                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13661            final boolean componentVisible =
13662                    matchVisibleToInstantApp
13663                    && info.isVisibleToInstantApp()
13664                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13665            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13666            // throw out filters that aren't visible to ephemeral apps
13667            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13668                return null;
13669            }
13670            // throw out instant app filters if we're not explicitly requesting them
13671            if (!matchInstantApp && userState.instantApp) {
13672                return null;
13673            }
13674            // throw out instant app filters if updates are available; will trigger
13675            // instant app resolution
13676            if (userState.instantApp && ps.isUpdateAvailable()) {
13677                return null;
13678            }
13679            final ResolveInfo res = new ResolveInfo();
13680            res.activityInfo = ai;
13681            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13682                res.filter = info;
13683            }
13684            if (info != null) {
13685                res.handleAllWebDataURI = info.handleAllWebDataURI();
13686            }
13687            res.priority = info.getPriority();
13688            res.preferredOrder = activity.owner.mPreferredOrder;
13689            //System.out.println("Result: " + res.activityInfo.className +
13690            //                   " = " + res.priority);
13691            res.match = match;
13692            res.isDefault = info.hasDefault;
13693            res.labelRes = info.labelRes;
13694            res.nonLocalizedLabel = info.nonLocalizedLabel;
13695            if (userNeedsBadging(userId)) {
13696                res.noResourceId = true;
13697            } else {
13698                res.icon = info.icon;
13699            }
13700            res.iconResourceId = info.icon;
13701            res.system = res.activityInfo.applicationInfo.isSystemApp();
13702            res.isInstantAppAvailable = userState.instantApp;
13703            return res;
13704        }
13705
13706        @Override
13707        protected void sortResults(List<ResolveInfo> results) {
13708            Collections.sort(results, mResolvePrioritySorter);
13709        }
13710
13711        @Override
13712        protected void dumpFilter(PrintWriter out, String prefix,
13713                PackageParser.ActivityIntentInfo filter) {
13714            out.print(prefix); out.print(
13715                    Integer.toHexString(System.identityHashCode(filter.activity)));
13716                    out.print(' ');
13717                    filter.activity.printComponentShortName(out);
13718                    out.print(" filter ");
13719                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13720        }
13721
13722        @Override
13723        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13724            return filter.activity;
13725        }
13726
13727        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13728            PackageParser.Activity activity = (PackageParser.Activity)label;
13729            out.print(prefix); out.print(
13730                    Integer.toHexString(System.identityHashCode(activity)));
13731                    out.print(' ');
13732                    activity.printComponentShortName(out);
13733            if (count > 1) {
13734                out.print(" ("); out.print(count); out.print(" filters)");
13735            }
13736            out.println();
13737        }
13738
13739        // Keys are String (activity class name), values are Activity.
13740        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13741                = new ArrayMap<ComponentName, PackageParser.Activity>();
13742        private int mFlags;
13743    }
13744
13745    private final class ServiceIntentResolver
13746            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13747        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13748                boolean defaultOnly, int userId) {
13749            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13750            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13751        }
13752
13753        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13754                int userId) {
13755            if (!sUserManager.exists(userId)) return null;
13756            mFlags = flags;
13757            return super.queryIntent(intent, resolvedType,
13758                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13759                    userId);
13760        }
13761
13762        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13763                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13764            if (!sUserManager.exists(userId)) return null;
13765            if (packageServices == null) {
13766                return null;
13767            }
13768            mFlags = flags;
13769            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13770            final int N = packageServices.size();
13771            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13772                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13773
13774            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13775            for (int i = 0; i < N; ++i) {
13776                intentFilters = packageServices.get(i).intents;
13777                if (intentFilters != null && intentFilters.size() > 0) {
13778                    PackageParser.ServiceIntentInfo[] array =
13779                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13780                    intentFilters.toArray(array);
13781                    listCut.add(array);
13782                }
13783            }
13784            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13785        }
13786
13787        public final void addService(PackageParser.Service s) {
13788            mServices.put(s.getComponentName(), s);
13789            if (DEBUG_SHOW_INFO) {
13790                Log.v(TAG, "  "
13791                        + (s.info.nonLocalizedLabel != null
13792                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13793                Log.v(TAG, "    Class=" + s.info.name);
13794            }
13795            final int NI = s.intents.size();
13796            int j;
13797            for (j=0; j<NI; j++) {
13798                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13799                if (DEBUG_SHOW_INFO) {
13800                    Log.v(TAG, "    IntentFilter:");
13801                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13802                }
13803                if (!intent.debugCheck()) {
13804                    Log.w(TAG, "==> For Service " + s.info.name);
13805                }
13806                addFilter(intent);
13807            }
13808        }
13809
13810        public final void removeService(PackageParser.Service s) {
13811            mServices.remove(s.getComponentName());
13812            if (DEBUG_SHOW_INFO) {
13813                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13814                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13815                Log.v(TAG, "    Class=" + s.info.name);
13816            }
13817            final int NI = s.intents.size();
13818            int j;
13819            for (j=0; j<NI; j++) {
13820                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13821                if (DEBUG_SHOW_INFO) {
13822                    Log.v(TAG, "    IntentFilter:");
13823                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13824                }
13825                removeFilter(intent);
13826            }
13827        }
13828
13829        @Override
13830        protected boolean allowFilterResult(
13831                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13832            ServiceInfo filterSi = filter.service.info;
13833            for (int i=dest.size()-1; i>=0; i--) {
13834                ServiceInfo destAi = dest.get(i).serviceInfo;
13835                if (destAi.name == filterSi.name
13836                        && destAi.packageName == filterSi.packageName) {
13837                    return false;
13838                }
13839            }
13840            return true;
13841        }
13842
13843        @Override
13844        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13845            return new PackageParser.ServiceIntentInfo[size];
13846        }
13847
13848        @Override
13849        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13850            if (!sUserManager.exists(userId)) return true;
13851            PackageParser.Package p = filter.service.owner;
13852            if (p != null) {
13853                PackageSetting ps = (PackageSetting)p.mExtras;
13854                if (ps != null) {
13855                    // System apps are never considered stopped for purposes of
13856                    // filtering, because there may be no way for the user to
13857                    // actually re-launch them.
13858                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13859                            && ps.getStopped(userId);
13860                }
13861            }
13862            return false;
13863        }
13864
13865        @Override
13866        protected boolean isPackageForFilter(String packageName,
13867                PackageParser.ServiceIntentInfo info) {
13868            return packageName.equals(info.service.owner.packageName);
13869        }
13870
13871        @Override
13872        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13873                int match, int userId) {
13874            if (!sUserManager.exists(userId)) return null;
13875            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13876            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13877                return null;
13878            }
13879            final PackageParser.Service service = info.service;
13880            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13881            if (ps == null) {
13882                return null;
13883            }
13884            final PackageUserState userState = ps.readUserState(userId);
13885            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13886                    userState, userId);
13887            if (si == null) {
13888                return null;
13889            }
13890            final boolean matchVisibleToInstantApp =
13891                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13892            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13893            // throw out filters that aren't visible to ephemeral apps
13894            if (matchVisibleToInstantApp
13895                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13896                return null;
13897            }
13898            // throw out ephemeral filters if we're not explicitly requesting them
13899            if (!isInstantApp && userState.instantApp) {
13900                return null;
13901            }
13902            // throw out instant app filters if updates are available; will trigger
13903            // instant app resolution
13904            if (userState.instantApp && ps.isUpdateAvailable()) {
13905                return null;
13906            }
13907            final ResolveInfo res = new ResolveInfo();
13908            res.serviceInfo = si;
13909            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13910                res.filter = filter;
13911            }
13912            res.priority = info.getPriority();
13913            res.preferredOrder = service.owner.mPreferredOrder;
13914            res.match = match;
13915            res.isDefault = info.hasDefault;
13916            res.labelRes = info.labelRes;
13917            res.nonLocalizedLabel = info.nonLocalizedLabel;
13918            res.icon = info.icon;
13919            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13920            return res;
13921        }
13922
13923        @Override
13924        protected void sortResults(List<ResolveInfo> results) {
13925            Collections.sort(results, mResolvePrioritySorter);
13926        }
13927
13928        @Override
13929        protected void dumpFilter(PrintWriter out, String prefix,
13930                PackageParser.ServiceIntentInfo filter) {
13931            out.print(prefix); out.print(
13932                    Integer.toHexString(System.identityHashCode(filter.service)));
13933                    out.print(' ');
13934                    filter.service.printComponentShortName(out);
13935                    out.print(" filter ");
13936                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13937        }
13938
13939        @Override
13940        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13941            return filter.service;
13942        }
13943
13944        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13945            PackageParser.Service service = (PackageParser.Service)label;
13946            out.print(prefix); out.print(
13947                    Integer.toHexString(System.identityHashCode(service)));
13948                    out.print(' ');
13949                    service.printComponentShortName(out);
13950            if (count > 1) {
13951                out.print(" ("); out.print(count); out.print(" filters)");
13952            }
13953            out.println();
13954        }
13955
13956//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13957//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13958//            final List<ResolveInfo> retList = Lists.newArrayList();
13959//            while (i.hasNext()) {
13960//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13961//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13962//                    retList.add(resolveInfo);
13963//                }
13964//            }
13965//            return retList;
13966//        }
13967
13968        // Keys are String (activity class name), values are Activity.
13969        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13970                = new ArrayMap<ComponentName, PackageParser.Service>();
13971        private int mFlags;
13972    }
13973
13974    private final class ProviderIntentResolver
13975            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13976        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13977                boolean defaultOnly, int userId) {
13978            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13979            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13980        }
13981
13982        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13983                int userId) {
13984            if (!sUserManager.exists(userId))
13985                return null;
13986            mFlags = flags;
13987            return super.queryIntent(intent, resolvedType,
13988                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13989                    userId);
13990        }
13991
13992        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13993                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13994            if (!sUserManager.exists(userId))
13995                return null;
13996            if (packageProviders == null) {
13997                return null;
13998            }
13999            mFlags = flags;
14000            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14001            final int N = packageProviders.size();
14002            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14003                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14004
14005            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14006            for (int i = 0; i < N; ++i) {
14007                intentFilters = packageProviders.get(i).intents;
14008                if (intentFilters != null && intentFilters.size() > 0) {
14009                    PackageParser.ProviderIntentInfo[] array =
14010                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
14011                    intentFilters.toArray(array);
14012                    listCut.add(array);
14013                }
14014            }
14015            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14016        }
14017
14018        public final void addProvider(PackageParser.Provider p) {
14019            if (mProviders.containsKey(p.getComponentName())) {
14020                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14021                return;
14022            }
14023
14024            mProviders.put(p.getComponentName(), p);
14025            if (DEBUG_SHOW_INFO) {
14026                Log.v(TAG, "  "
14027                        + (p.info.nonLocalizedLabel != null
14028                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
14029                Log.v(TAG, "    Class=" + p.info.name);
14030            }
14031            final int NI = p.intents.size();
14032            int j;
14033            for (j = 0; j < NI; j++) {
14034                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14035                if (DEBUG_SHOW_INFO) {
14036                    Log.v(TAG, "    IntentFilter:");
14037                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14038                }
14039                if (!intent.debugCheck()) {
14040                    Log.w(TAG, "==> For Provider " + p.info.name);
14041                }
14042                addFilter(intent);
14043            }
14044        }
14045
14046        public final void removeProvider(PackageParser.Provider p) {
14047            mProviders.remove(p.getComponentName());
14048            if (DEBUG_SHOW_INFO) {
14049                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14050                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
14051                Log.v(TAG, "    Class=" + p.info.name);
14052            }
14053            final int NI = p.intents.size();
14054            int j;
14055            for (j = 0; j < NI; j++) {
14056                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14057                if (DEBUG_SHOW_INFO) {
14058                    Log.v(TAG, "    IntentFilter:");
14059                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14060                }
14061                removeFilter(intent);
14062            }
14063        }
14064
14065        @Override
14066        protected boolean allowFilterResult(
14067                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14068            ProviderInfo filterPi = filter.provider.info;
14069            for (int i = dest.size() - 1; i >= 0; i--) {
14070                ProviderInfo destPi = dest.get(i).providerInfo;
14071                if (destPi.name == filterPi.name
14072                        && destPi.packageName == filterPi.packageName) {
14073                    return false;
14074                }
14075            }
14076            return true;
14077        }
14078
14079        @Override
14080        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14081            return new PackageParser.ProviderIntentInfo[size];
14082        }
14083
14084        @Override
14085        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14086            if (!sUserManager.exists(userId))
14087                return true;
14088            PackageParser.Package p = filter.provider.owner;
14089            if (p != null) {
14090                PackageSetting ps = (PackageSetting) p.mExtras;
14091                if (ps != null) {
14092                    // System apps are never considered stopped for purposes of
14093                    // filtering, because there may be no way for the user to
14094                    // actually re-launch them.
14095                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14096                            && ps.getStopped(userId);
14097                }
14098            }
14099            return false;
14100        }
14101
14102        @Override
14103        protected boolean isPackageForFilter(String packageName,
14104                PackageParser.ProviderIntentInfo info) {
14105            return packageName.equals(info.provider.owner.packageName);
14106        }
14107
14108        @Override
14109        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14110                int match, int userId) {
14111            if (!sUserManager.exists(userId))
14112                return null;
14113            final PackageParser.ProviderIntentInfo info = filter;
14114            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14115                return null;
14116            }
14117            final PackageParser.Provider provider = info.provider;
14118            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14119            if (ps == null) {
14120                return null;
14121            }
14122            final PackageUserState userState = ps.readUserState(userId);
14123            final boolean matchVisibleToInstantApp =
14124                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14125            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14126            // throw out filters that aren't visible to instant applications
14127            if (matchVisibleToInstantApp
14128                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14129                return null;
14130            }
14131            // throw out instant application filters if we're not explicitly requesting them
14132            if (!isInstantApp && userState.instantApp) {
14133                return null;
14134            }
14135            // throw out instant application filters if updates are available; will trigger
14136            // instant application resolution
14137            if (userState.instantApp && ps.isUpdateAvailable()) {
14138                return null;
14139            }
14140            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14141                    userState, userId);
14142            if (pi == null) {
14143                return null;
14144            }
14145            final ResolveInfo res = new ResolveInfo();
14146            res.providerInfo = pi;
14147            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14148                res.filter = filter;
14149            }
14150            res.priority = info.getPriority();
14151            res.preferredOrder = provider.owner.mPreferredOrder;
14152            res.match = match;
14153            res.isDefault = info.hasDefault;
14154            res.labelRes = info.labelRes;
14155            res.nonLocalizedLabel = info.nonLocalizedLabel;
14156            res.icon = info.icon;
14157            res.system = res.providerInfo.applicationInfo.isSystemApp();
14158            return res;
14159        }
14160
14161        @Override
14162        protected void sortResults(List<ResolveInfo> results) {
14163            Collections.sort(results, mResolvePrioritySorter);
14164        }
14165
14166        @Override
14167        protected void dumpFilter(PrintWriter out, String prefix,
14168                PackageParser.ProviderIntentInfo filter) {
14169            out.print(prefix);
14170            out.print(
14171                    Integer.toHexString(System.identityHashCode(filter.provider)));
14172            out.print(' ');
14173            filter.provider.printComponentShortName(out);
14174            out.print(" filter ");
14175            out.println(Integer.toHexString(System.identityHashCode(filter)));
14176        }
14177
14178        @Override
14179        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14180            return filter.provider;
14181        }
14182
14183        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14184            PackageParser.Provider provider = (PackageParser.Provider)label;
14185            out.print(prefix); out.print(
14186                    Integer.toHexString(System.identityHashCode(provider)));
14187                    out.print(' ');
14188                    provider.printComponentShortName(out);
14189            if (count > 1) {
14190                out.print(" ("); out.print(count); out.print(" filters)");
14191            }
14192            out.println();
14193        }
14194
14195        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14196                = new ArrayMap<ComponentName, PackageParser.Provider>();
14197        private int mFlags;
14198    }
14199
14200    static final class EphemeralIntentResolver
14201            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14202        /**
14203         * The result that has the highest defined order. Ordering applies on a
14204         * per-package basis. Mapping is from package name to Pair of order and
14205         * EphemeralResolveInfo.
14206         * <p>
14207         * NOTE: This is implemented as a field variable for convenience and efficiency.
14208         * By having a field variable, we're able to track filter ordering as soon as
14209         * a non-zero order is defined. Otherwise, multiple loops across the result set
14210         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14211         * this needs to be contained entirely within {@link #filterResults}.
14212         */
14213        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14214
14215        @Override
14216        protected AuxiliaryResolveInfo[] newArray(int size) {
14217            return new AuxiliaryResolveInfo[size];
14218        }
14219
14220        @Override
14221        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14222            return true;
14223        }
14224
14225        @Override
14226        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14227                int userId) {
14228            if (!sUserManager.exists(userId)) {
14229                return null;
14230            }
14231            final String packageName = responseObj.resolveInfo.getPackageName();
14232            final Integer order = responseObj.getOrder();
14233            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14234                    mOrderResult.get(packageName);
14235            // ordering is enabled and this item's order isn't high enough
14236            if (lastOrderResult != null && lastOrderResult.first >= order) {
14237                return null;
14238            }
14239            final InstantAppResolveInfo res = responseObj.resolveInfo;
14240            if (order > 0) {
14241                // non-zero order, enable ordering
14242                mOrderResult.put(packageName, new Pair<>(order, res));
14243            }
14244            return responseObj;
14245        }
14246
14247        @Override
14248        protected void filterResults(List<AuxiliaryResolveInfo> results) {
14249            // only do work if ordering is enabled [most of the time it won't be]
14250            if (mOrderResult.size() == 0) {
14251                return;
14252            }
14253            int resultSize = results.size();
14254            for (int i = 0; i < resultSize; i++) {
14255                final InstantAppResolveInfo info = results.get(i).resolveInfo;
14256                final String packageName = info.getPackageName();
14257                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14258                if (savedInfo == null) {
14259                    // package doesn't having ordering
14260                    continue;
14261                }
14262                if (savedInfo.second == info) {
14263                    // circled back to the highest ordered item; remove from order list
14264                    mOrderResult.remove(savedInfo);
14265                    if (mOrderResult.size() == 0) {
14266                        // no more ordered items
14267                        break;
14268                    }
14269                    continue;
14270                }
14271                // item has a worse order, remove it from the result list
14272                results.remove(i);
14273                resultSize--;
14274                i--;
14275            }
14276        }
14277    }
14278
14279    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14280            new Comparator<ResolveInfo>() {
14281        public int compare(ResolveInfo r1, ResolveInfo r2) {
14282            int v1 = r1.priority;
14283            int v2 = r2.priority;
14284            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14285            if (v1 != v2) {
14286                return (v1 > v2) ? -1 : 1;
14287            }
14288            v1 = r1.preferredOrder;
14289            v2 = r2.preferredOrder;
14290            if (v1 != v2) {
14291                return (v1 > v2) ? -1 : 1;
14292            }
14293            if (r1.isDefault != r2.isDefault) {
14294                return r1.isDefault ? -1 : 1;
14295            }
14296            v1 = r1.match;
14297            v2 = r2.match;
14298            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14299            if (v1 != v2) {
14300                return (v1 > v2) ? -1 : 1;
14301            }
14302            if (r1.system != r2.system) {
14303                return r1.system ? -1 : 1;
14304            }
14305            if (r1.activityInfo != null) {
14306                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14307            }
14308            if (r1.serviceInfo != null) {
14309                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14310            }
14311            if (r1.providerInfo != null) {
14312                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14313            }
14314            return 0;
14315        }
14316    };
14317
14318    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14319            new Comparator<ProviderInfo>() {
14320        public int compare(ProviderInfo p1, ProviderInfo p2) {
14321            final int v1 = p1.initOrder;
14322            final int v2 = p2.initOrder;
14323            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14324        }
14325    };
14326
14327    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14328            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14329            final int[] userIds) {
14330        mHandler.post(new Runnable() {
14331            @Override
14332            public void run() {
14333                try {
14334                    final IActivityManager am = ActivityManager.getService();
14335                    if (am == null) return;
14336                    final int[] resolvedUserIds;
14337                    if (userIds == null) {
14338                        resolvedUserIds = am.getRunningUserIds();
14339                    } else {
14340                        resolvedUserIds = userIds;
14341                    }
14342                    for (int id : resolvedUserIds) {
14343                        final Intent intent = new Intent(action,
14344                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14345                        if (extras != null) {
14346                            intent.putExtras(extras);
14347                        }
14348                        if (targetPkg != null) {
14349                            intent.setPackage(targetPkg);
14350                        }
14351                        // Modify the UID when posting to other users
14352                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14353                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14354                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14355                            intent.putExtra(Intent.EXTRA_UID, uid);
14356                        }
14357                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14358                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14359                        if (DEBUG_BROADCASTS) {
14360                            RuntimeException here = new RuntimeException("here");
14361                            here.fillInStackTrace();
14362                            Slog.d(TAG, "Sending to user " + id + ": "
14363                                    + intent.toShortString(false, true, false, false)
14364                                    + " " + intent.getExtras(), here);
14365                        }
14366                        am.broadcastIntent(null, intent, null, finishedReceiver,
14367                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14368                                null, finishedReceiver != null, false, id);
14369                    }
14370                } catch (RemoteException ex) {
14371                }
14372            }
14373        });
14374    }
14375
14376    /**
14377     * Check if the external storage media is available. This is true if there
14378     * is a mounted external storage medium or if the external storage is
14379     * emulated.
14380     */
14381    private boolean isExternalMediaAvailable() {
14382        return mMediaMounted || Environment.isExternalStorageEmulated();
14383    }
14384
14385    @Override
14386    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14387        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14388            return null;
14389        }
14390        // writer
14391        synchronized (mPackages) {
14392            if (!isExternalMediaAvailable()) {
14393                // If the external storage is no longer mounted at this point,
14394                // the caller may not have been able to delete all of this
14395                // packages files and can not delete any more.  Bail.
14396                return null;
14397            }
14398            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14399            if (lastPackage != null) {
14400                pkgs.remove(lastPackage);
14401            }
14402            if (pkgs.size() > 0) {
14403                return pkgs.get(0);
14404            }
14405        }
14406        return null;
14407    }
14408
14409    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14410        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14411                userId, andCode ? 1 : 0, packageName);
14412        if (mSystemReady) {
14413            msg.sendToTarget();
14414        } else {
14415            if (mPostSystemReadyMessages == null) {
14416                mPostSystemReadyMessages = new ArrayList<>();
14417            }
14418            mPostSystemReadyMessages.add(msg);
14419        }
14420    }
14421
14422    void startCleaningPackages() {
14423        // reader
14424        if (!isExternalMediaAvailable()) {
14425            return;
14426        }
14427        synchronized (mPackages) {
14428            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14429                return;
14430            }
14431        }
14432        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14433        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14434        IActivityManager am = ActivityManager.getService();
14435        if (am != null) {
14436            int dcsUid = -1;
14437            synchronized (mPackages) {
14438                if (!mDefaultContainerWhitelisted) {
14439                    mDefaultContainerWhitelisted = true;
14440                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14441                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14442                }
14443            }
14444            try {
14445                if (dcsUid > 0) {
14446                    am.backgroundWhitelistUid(dcsUid);
14447                }
14448                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14449                        UserHandle.USER_SYSTEM);
14450            } catch (RemoteException e) {
14451            }
14452        }
14453    }
14454
14455    @Override
14456    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14457            int installFlags, String installerPackageName, int userId) {
14458        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14459
14460        final int callingUid = Binder.getCallingUid();
14461        enforceCrossUserPermission(callingUid, userId,
14462                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14463
14464        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14465            try {
14466                if (observer != null) {
14467                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14468                }
14469            } catch (RemoteException re) {
14470            }
14471            return;
14472        }
14473
14474        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14475            installFlags |= PackageManager.INSTALL_FROM_ADB;
14476
14477        } else {
14478            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14479            // about installerPackageName.
14480
14481            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14482            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14483        }
14484
14485        UserHandle user;
14486        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14487            user = UserHandle.ALL;
14488        } else {
14489            user = new UserHandle(userId);
14490        }
14491
14492        // Only system components can circumvent runtime permissions when installing.
14493        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14494                && mContext.checkCallingOrSelfPermission(Manifest.permission
14495                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14496            throw new SecurityException("You need the "
14497                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14498                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14499        }
14500
14501        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14502                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14503            throw new IllegalArgumentException(
14504                    "New installs into ASEC containers no longer supported");
14505        }
14506
14507        final File originFile = new File(originPath);
14508        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14509
14510        final Message msg = mHandler.obtainMessage(INIT_COPY);
14511        final VerificationInfo verificationInfo = new VerificationInfo(
14512                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14513        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14514                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14515                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14516                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14517        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14518        msg.obj = params;
14519
14520        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14521                System.identityHashCode(msg.obj));
14522        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14523                System.identityHashCode(msg.obj));
14524
14525        mHandler.sendMessage(msg);
14526    }
14527
14528
14529    /**
14530     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14531     * it is acting on behalf on an enterprise or the user).
14532     *
14533     * Note that the ordering of the conditionals in this method is important. The checks we perform
14534     * are as follows, in this order:
14535     *
14536     * 1) If the install is being performed by a system app, we can trust the app to have set the
14537     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14538     *    what it is.
14539     * 2) If the install is being performed by a device or profile owner app, the install reason
14540     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14541     *    set the install reason correctly. If the app targets an older SDK version where install
14542     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14543     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14544     * 3) In all other cases, the install is being performed by a regular app that is neither part
14545     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14546     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14547     *    set to enterprise policy and if so, change it to unknown instead.
14548     */
14549    private int fixUpInstallReason(String installerPackageName, int installerUid,
14550            int installReason) {
14551        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14552                == PERMISSION_GRANTED) {
14553            // If the install is being performed by a system app, we trust that app to have set the
14554            // install reason correctly.
14555            return installReason;
14556        }
14557
14558        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14559            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14560        if (dpm != null) {
14561            ComponentName owner = null;
14562            try {
14563                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14564                if (owner == null) {
14565                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14566                }
14567            } catch (RemoteException e) {
14568            }
14569            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14570                // If the install is being performed by a device or profile owner, the install
14571                // reason should be enterprise policy.
14572                return PackageManager.INSTALL_REASON_POLICY;
14573            }
14574        }
14575
14576        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14577            // If the install is being performed by a regular app (i.e. neither system app nor
14578            // device or profile owner), we have no reason to believe that the app is acting on
14579            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14580            // change it to unknown instead.
14581            return PackageManager.INSTALL_REASON_UNKNOWN;
14582        }
14583
14584        // If the install is being performed by a regular app and the install reason was set to any
14585        // value but enterprise policy, leave the install reason unchanged.
14586        return installReason;
14587    }
14588
14589    void installStage(String packageName, File stagedDir, String stagedCid,
14590            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14591            String installerPackageName, int installerUid, UserHandle user,
14592            Certificate[][] certificates) {
14593        if (DEBUG_EPHEMERAL) {
14594            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14595                Slog.d(TAG, "Ephemeral install of " + packageName);
14596            }
14597        }
14598        final VerificationInfo verificationInfo = new VerificationInfo(
14599                sessionParams.originatingUri, sessionParams.referrerUri,
14600                sessionParams.originatingUid, installerUid);
14601
14602        final OriginInfo origin;
14603        if (stagedDir != null) {
14604            origin = OriginInfo.fromStagedFile(stagedDir);
14605        } else {
14606            origin = OriginInfo.fromStagedContainer(stagedCid);
14607        }
14608
14609        final Message msg = mHandler.obtainMessage(INIT_COPY);
14610        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14611                sessionParams.installReason);
14612        final InstallParams params = new InstallParams(origin, null, observer,
14613                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14614                verificationInfo, user, sessionParams.abiOverride,
14615                sessionParams.grantedRuntimePermissions, certificates, installReason);
14616        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14617        msg.obj = params;
14618
14619        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14620                System.identityHashCode(msg.obj));
14621        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14622                System.identityHashCode(msg.obj));
14623
14624        mHandler.sendMessage(msg);
14625    }
14626
14627    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14628            int userId) {
14629        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14630        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14631                false /*startReceiver*/, pkgSetting.appId, userId);
14632
14633        // Send a session commit broadcast
14634        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14635        info.installReason = pkgSetting.getInstallReason(userId);
14636        info.appPackageName = packageName;
14637        sendSessionCommitBroadcast(info, userId);
14638    }
14639
14640    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14641            boolean includeStopped, int appId, int... userIds) {
14642        if (ArrayUtils.isEmpty(userIds)) {
14643            return;
14644        }
14645        Bundle extras = new Bundle(1);
14646        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14647        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14648
14649        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14650                packageName, extras, 0, null, null, userIds);
14651        if (sendBootCompleted) {
14652            mHandler.post(() -> {
14653                        for (int userId : userIds) {
14654                            sendBootCompletedBroadcastToSystemApp(
14655                                    packageName, includeStopped, userId);
14656                        }
14657                    }
14658            );
14659        }
14660    }
14661
14662    /**
14663     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14664     * automatically without needing an explicit launch.
14665     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14666     */
14667    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
14668            int userId) {
14669        // If user is not running, the app didn't miss any broadcast
14670        if (!mUserManagerInternal.isUserRunning(userId)) {
14671            return;
14672        }
14673        final IActivityManager am = ActivityManager.getService();
14674        try {
14675            // Deliver LOCKED_BOOT_COMPLETED first
14676            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14677                    .setPackage(packageName);
14678            if (includeStopped) {
14679                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14680            }
14681            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14682            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14683                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14684
14685            // Deliver BOOT_COMPLETED only if user is unlocked
14686            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14687                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14688                if (includeStopped) {
14689                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14690                }
14691                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14692                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14693            }
14694        } catch (RemoteException e) {
14695            throw e.rethrowFromSystemServer();
14696        }
14697    }
14698
14699    @Override
14700    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14701            int userId) {
14702        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14703        PackageSetting pkgSetting;
14704        final int callingUid = Binder.getCallingUid();
14705        enforceCrossUserPermission(callingUid, userId,
14706                true /* requireFullPermission */, true /* checkShell */,
14707                "setApplicationHiddenSetting for user " + userId);
14708
14709        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14710            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14711            return false;
14712        }
14713
14714        long callingId = Binder.clearCallingIdentity();
14715        try {
14716            boolean sendAdded = false;
14717            boolean sendRemoved = false;
14718            // writer
14719            synchronized (mPackages) {
14720                pkgSetting = mSettings.mPackages.get(packageName);
14721                if (pkgSetting == null) {
14722                    return false;
14723                }
14724                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14725                    return false;
14726                }
14727                // Do not allow "android" is being disabled
14728                if ("android".equals(packageName)) {
14729                    Slog.w(TAG, "Cannot hide package: android");
14730                    return false;
14731                }
14732                // Cannot hide static shared libs as they are considered
14733                // a part of the using app (emulating static linking). Also
14734                // static libs are installed always on internal storage.
14735                PackageParser.Package pkg = mPackages.get(packageName);
14736                if (pkg != null && pkg.staticSharedLibName != null) {
14737                    Slog.w(TAG, "Cannot hide package: " + packageName
14738                            + " providing static shared library: "
14739                            + pkg.staticSharedLibName);
14740                    return false;
14741                }
14742                // Only allow protected packages to hide themselves.
14743                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
14744                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14745                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14746                    return false;
14747                }
14748
14749                if (pkgSetting.getHidden(userId) != hidden) {
14750                    pkgSetting.setHidden(hidden, userId);
14751                    mSettings.writePackageRestrictionsLPr(userId);
14752                    if (hidden) {
14753                        sendRemoved = true;
14754                    } else {
14755                        sendAdded = true;
14756                    }
14757                }
14758            }
14759            if (sendAdded) {
14760                sendPackageAddedForUser(packageName, pkgSetting, userId);
14761                return true;
14762            }
14763            if (sendRemoved) {
14764                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14765                        "hiding pkg");
14766                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14767                return true;
14768            }
14769        } finally {
14770            Binder.restoreCallingIdentity(callingId);
14771        }
14772        return false;
14773    }
14774
14775    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14776            int userId) {
14777        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14778        info.removedPackage = packageName;
14779        info.installerPackageName = pkgSetting.installerPackageName;
14780        info.removedUsers = new int[] {userId};
14781        info.broadcastUsers = new int[] {userId};
14782        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14783        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14784    }
14785
14786    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14787        if (pkgList.length > 0) {
14788            Bundle extras = new Bundle(1);
14789            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14790
14791            sendPackageBroadcast(
14792                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14793                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14794                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14795                    new int[] {userId});
14796        }
14797    }
14798
14799    /**
14800     * Returns true if application is not found or there was an error. Otherwise it returns
14801     * the hidden state of the package for the given user.
14802     */
14803    @Override
14804    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14805        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14806        final int callingUid = Binder.getCallingUid();
14807        enforceCrossUserPermission(callingUid, userId,
14808                true /* requireFullPermission */, false /* checkShell */,
14809                "getApplicationHidden for user " + userId);
14810        PackageSetting ps;
14811        long callingId = Binder.clearCallingIdentity();
14812        try {
14813            // writer
14814            synchronized (mPackages) {
14815                ps = mSettings.mPackages.get(packageName);
14816                if (ps == null) {
14817                    return true;
14818                }
14819                if (filterAppAccessLPr(ps, callingUid, userId)) {
14820                    return true;
14821                }
14822                return ps.getHidden(userId);
14823            }
14824        } finally {
14825            Binder.restoreCallingIdentity(callingId);
14826        }
14827    }
14828
14829    /**
14830     * @hide
14831     */
14832    @Override
14833    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14834            int installReason) {
14835        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14836                null);
14837        PackageSetting pkgSetting;
14838        final int callingUid = Binder.getCallingUid();
14839        enforceCrossUserPermission(callingUid, userId,
14840                true /* requireFullPermission */, true /* checkShell */,
14841                "installExistingPackage for user " + userId);
14842        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14843            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14844        }
14845
14846        long callingId = Binder.clearCallingIdentity();
14847        try {
14848            boolean installed = false;
14849            final boolean instantApp =
14850                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14851            final boolean fullApp =
14852                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14853
14854            // writer
14855            synchronized (mPackages) {
14856                pkgSetting = mSettings.mPackages.get(packageName);
14857                if (pkgSetting == null) {
14858                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14859                }
14860                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14861                    // only allow the existing package to be used if it's installed as a full
14862                    // application for at least one user
14863                    boolean installAllowed = false;
14864                    for (int checkUserId : sUserManager.getUserIds()) {
14865                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
14866                        if (installAllowed) {
14867                            break;
14868                        }
14869                    }
14870                    if (!installAllowed) {
14871                        return PackageManager.INSTALL_FAILED_INVALID_URI;
14872                    }
14873                }
14874                if (!pkgSetting.getInstalled(userId)) {
14875                    pkgSetting.setInstalled(true, userId);
14876                    pkgSetting.setHidden(false, userId);
14877                    pkgSetting.setInstallReason(installReason, userId);
14878                    mSettings.writePackageRestrictionsLPr(userId);
14879                    mSettings.writeKernelMappingLPr(pkgSetting);
14880                    installed = true;
14881                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14882                    // upgrade app from instant to full; we don't allow app downgrade
14883                    installed = true;
14884                }
14885                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14886            }
14887
14888            if (installed) {
14889                if (pkgSetting.pkg != null) {
14890                    synchronized (mInstallLock) {
14891                        // We don't need to freeze for a brand new install
14892                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14893                    }
14894                }
14895                sendPackageAddedForUser(packageName, pkgSetting, userId);
14896                synchronized (mPackages) {
14897                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14898                }
14899            }
14900        } finally {
14901            Binder.restoreCallingIdentity(callingId);
14902        }
14903
14904        return PackageManager.INSTALL_SUCCEEDED;
14905    }
14906
14907    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14908            boolean instantApp, boolean fullApp) {
14909        // no state specified; do nothing
14910        if (!instantApp && !fullApp) {
14911            return;
14912        }
14913        if (userId != UserHandle.USER_ALL) {
14914            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14915                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14916            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14917                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14918            }
14919        } else {
14920            for (int currentUserId : sUserManager.getUserIds()) {
14921                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14922                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14923                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14924                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14925                }
14926            }
14927        }
14928    }
14929
14930    boolean isUserRestricted(int userId, String restrictionKey) {
14931        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14932        if (restrictions.getBoolean(restrictionKey, false)) {
14933            Log.w(TAG, "User is restricted: " + restrictionKey);
14934            return true;
14935        }
14936        return false;
14937    }
14938
14939    @Override
14940    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14941            int userId) {
14942        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14943        final int callingUid = Binder.getCallingUid();
14944        enforceCrossUserPermission(callingUid, userId,
14945                true /* requireFullPermission */, true /* checkShell */,
14946                "setPackagesSuspended for user " + userId);
14947
14948        if (ArrayUtils.isEmpty(packageNames)) {
14949            return packageNames;
14950        }
14951
14952        // List of package names for whom the suspended state has changed.
14953        List<String> changedPackages = new ArrayList<>(packageNames.length);
14954        // List of package names for whom the suspended state is not set as requested in this
14955        // method.
14956        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14957        long callingId = Binder.clearCallingIdentity();
14958        try {
14959            for (int i = 0; i < packageNames.length; i++) {
14960                String packageName = packageNames[i];
14961                boolean changed = false;
14962                final int appId;
14963                synchronized (mPackages) {
14964                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14965                    if (pkgSetting == null
14966                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14967                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14968                                + "\". Skipping suspending/un-suspending.");
14969                        unactionedPackages.add(packageName);
14970                        continue;
14971                    }
14972                    appId = pkgSetting.appId;
14973                    if (pkgSetting.getSuspended(userId) != suspended) {
14974                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14975                            unactionedPackages.add(packageName);
14976                            continue;
14977                        }
14978                        pkgSetting.setSuspended(suspended, userId);
14979                        mSettings.writePackageRestrictionsLPr(userId);
14980                        changed = true;
14981                        changedPackages.add(packageName);
14982                    }
14983                }
14984
14985                if (changed && suspended) {
14986                    killApplication(packageName, UserHandle.getUid(userId, appId),
14987                            "suspending package");
14988                }
14989            }
14990        } finally {
14991            Binder.restoreCallingIdentity(callingId);
14992        }
14993
14994        if (!changedPackages.isEmpty()) {
14995            sendPackagesSuspendedForUser(changedPackages.toArray(
14996                    new String[changedPackages.size()]), userId, suspended);
14997        }
14998
14999        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15000    }
15001
15002    @Override
15003    public boolean isPackageSuspendedForUser(String packageName, int userId) {
15004        final int callingUid = Binder.getCallingUid();
15005        enforceCrossUserPermission(callingUid, userId,
15006                true /* requireFullPermission */, false /* checkShell */,
15007                "isPackageSuspendedForUser for user " + userId);
15008        synchronized (mPackages) {
15009            final PackageSetting ps = mSettings.mPackages.get(packageName);
15010            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15011                throw new IllegalArgumentException("Unknown target package: " + packageName);
15012            }
15013            return ps.getSuspended(userId);
15014        }
15015    }
15016
15017    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15018        if (isPackageDeviceAdmin(packageName, userId)) {
15019            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15020                    + "\": has an active device admin");
15021            return false;
15022        }
15023
15024        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15025        if (packageName.equals(activeLauncherPackageName)) {
15026            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15027                    + "\": contains the active launcher");
15028            return false;
15029        }
15030
15031        if (packageName.equals(mRequiredInstallerPackage)) {
15032            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15033                    + "\": required for package installation");
15034            return false;
15035        }
15036
15037        if (packageName.equals(mRequiredUninstallerPackage)) {
15038            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15039                    + "\": required for package uninstallation");
15040            return false;
15041        }
15042
15043        if (packageName.equals(mRequiredVerifierPackage)) {
15044            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15045                    + "\": required for package verification");
15046            return false;
15047        }
15048
15049        if (packageName.equals(getDefaultDialerPackageName(userId))) {
15050            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15051                    + "\": is the default dialer");
15052            return false;
15053        }
15054
15055        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15056            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15057                    + "\": protected package");
15058            return false;
15059        }
15060
15061        // Cannot suspend static shared libs as they are considered
15062        // a part of the using app (emulating static linking). Also
15063        // static libs are installed always on internal storage.
15064        PackageParser.Package pkg = mPackages.get(packageName);
15065        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15066            Slog.w(TAG, "Cannot suspend package: " + packageName
15067                    + " providing static shared library: "
15068                    + pkg.staticSharedLibName);
15069            return false;
15070        }
15071
15072        return true;
15073    }
15074
15075    private String getActiveLauncherPackageName(int userId) {
15076        Intent intent = new Intent(Intent.ACTION_MAIN);
15077        intent.addCategory(Intent.CATEGORY_HOME);
15078        ResolveInfo resolveInfo = resolveIntent(
15079                intent,
15080                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15081                PackageManager.MATCH_DEFAULT_ONLY,
15082                userId);
15083
15084        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15085    }
15086
15087    private String getDefaultDialerPackageName(int userId) {
15088        synchronized (mPackages) {
15089            return mSettings.getDefaultDialerPackageNameLPw(userId);
15090        }
15091    }
15092
15093    @Override
15094    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15095        mContext.enforceCallingOrSelfPermission(
15096                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15097                "Only package verification agents can verify applications");
15098
15099        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15100        final PackageVerificationResponse response = new PackageVerificationResponse(
15101                verificationCode, Binder.getCallingUid());
15102        msg.arg1 = id;
15103        msg.obj = response;
15104        mHandler.sendMessage(msg);
15105    }
15106
15107    @Override
15108    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15109            long millisecondsToDelay) {
15110        mContext.enforceCallingOrSelfPermission(
15111                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15112                "Only package verification agents can extend verification timeouts");
15113
15114        final PackageVerificationState state = mPendingVerification.get(id);
15115        final PackageVerificationResponse response = new PackageVerificationResponse(
15116                verificationCodeAtTimeout, Binder.getCallingUid());
15117
15118        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15119            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15120        }
15121        if (millisecondsToDelay < 0) {
15122            millisecondsToDelay = 0;
15123        }
15124        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15125                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15126            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15127        }
15128
15129        if ((state != null) && !state.timeoutExtended()) {
15130            state.extendTimeout();
15131
15132            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15133            msg.arg1 = id;
15134            msg.obj = response;
15135            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15136        }
15137    }
15138
15139    private void broadcastPackageVerified(int verificationId, Uri packageUri,
15140            int verificationCode, UserHandle user) {
15141        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15142        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15143        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15144        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15145        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15146
15147        mContext.sendBroadcastAsUser(intent, user,
15148                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15149    }
15150
15151    private ComponentName matchComponentForVerifier(String packageName,
15152            List<ResolveInfo> receivers) {
15153        ActivityInfo targetReceiver = null;
15154
15155        final int NR = receivers.size();
15156        for (int i = 0; i < NR; i++) {
15157            final ResolveInfo info = receivers.get(i);
15158            if (info.activityInfo == null) {
15159                continue;
15160            }
15161
15162            if (packageName.equals(info.activityInfo.packageName)) {
15163                targetReceiver = info.activityInfo;
15164                break;
15165            }
15166        }
15167
15168        if (targetReceiver == null) {
15169            return null;
15170        }
15171
15172        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15173    }
15174
15175    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15176            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15177        if (pkgInfo.verifiers.length == 0) {
15178            return null;
15179        }
15180
15181        final int N = pkgInfo.verifiers.length;
15182        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15183        for (int i = 0; i < N; i++) {
15184            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15185
15186            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15187                    receivers);
15188            if (comp == null) {
15189                continue;
15190            }
15191
15192            final int verifierUid = getUidForVerifier(verifierInfo);
15193            if (verifierUid == -1) {
15194                continue;
15195            }
15196
15197            if (DEBUG_VERIFY) {
15198                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15199                        + " with the correct signature");
15200            }
15201            sufficientVerifiers.add(comp);
15202            verificationState.addSufficientVerifier(verifierUid);
15203        }
15204
15205        return sufficientVerifiers;
15206    }
15207
15208    private int getUidForVerifier(VerifierInfo verifierInfo) {
15209        synchronized (mPackages) {
15210            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15211            if (pkg == null) {
15212                return -1;
15213            } else if (pkg.mSignatures.length != 1) {
15214                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15215                        + " has more than one signature; ignoring");
15216                return -1;
15217            }
15218
15219            /*
15220             * If the public key of the package's signature does not match
15221             * our expected public key, then this is a different package and
15222             * we should skip.
15223             */
15224
15225            final byte[] expectedPublicKey;
15226            try {
15227                final Signature verifierSig = pkg.mSignatures[0];
15228                final PublicKey publicKey = verifierSig.getPublicKey();
15229                expectedPublicKey = publicKey.getEncoded();
15230            } catch (CertificateException e) {
15231                return -1;
15232            }
15233
15234            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15235
15236            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15237                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15238                        + " does not have the expected public key; ignoring");
15239                return -1;
15240            }
15241
15242            return pkg.applicationInfo.uid;
15243        }
15244    }
15245
15246    @Override
15247    public void finishPackageInstall(int token, boolean didLaunch) {
15248        enforceSystemOrRoot("Only the system is allowed to finish installs");
15249
15250        if (DEBUG_INSTALL) {
15251            Slog.v(TAG, "BM finishing package install for " + token);
15252        }
15253        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15254
15255        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15256        mHandler.sendMessage(msg);
15257    }
15258
15259    /**
15260     * Get the verification agent timeout.  Used for both the APK verifier and the
15261     * intent filter verifier.
15262     *
15263     * @return verification timeout in milliseconds
15264     */
15265    private long getVerificationTimeout() {
15266        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15267                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15268                DEFAULT_VERIFICATION_TIMEOUT);
15269    }
15270
15271    /**
15272     * Get the default verification agent response code.
15273     *
15274     * @return default verification response code
15275     */
15276    private int getDefaultVerificationResponse(UserHandle user) {
15277        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15278            return PackageManager.VERIFICATION_REJECT;
15279        }
15280        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15281                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15282                DEFAULT_VERIFICATION_RESPONSE);
15283    }
15284
15285    /**
15286     * Check whether or not package verification has been enabled.
15287     *
15288     * @return true if verification should be performed
15289     */
15290    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15291        if (!DEFAULT_VERIFY_ENABLE) {
15292            return false;
15293        }
15294
15295        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15296
15297        // Check if installing from ADB
15298        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15299            // Do not run verification in a test harness environment
15300            if (ActivityManager.isRunningInTestHarness()) {
15301                return false;
15302            }
15303            if (ensureVerifyAppsEnabled) {
15304                return true;
15305            }
15306            // Check if the developer does not want package verification for ADB installs
15307            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15308                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15309                return false;
15310            }
15311        } else {
15312            // only when not installed from ADB, skip verification for instant apps when
15313            // the installer and verifier are the same.
15314            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15315                if (mInstantAppInstallerActivity != null
15316                        && mInstantAppInstallerActivity.packageName.equals(
15317                                mRequiredVerifierPackage)) {
15318                    try {
15319                        mContext.getSystemService(AppOpsManager.class)
15320                                .checkPackage(installerUid, mRequiredVerifierPackage);
15321                        if (DEBUG_VERIFY) {
15322                            Slog.i(TAG, "disable verification for instant app");
15323                        }
15324                        return false;
15325                    } catch (SecurityException ignore) { }
15326                }
15327            }
15328        }
15329
15330        if (ensureVerifyAppsEnabled) {
15331            return true;
15332        }
15333
15334        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15335                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15336    }
15337
15338    @Override
15339    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15340            throws RemoteException {
15341        mContext.enforceCallingOrSelfPermission(
15342                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15343                "Only intentfilter verification agents can verify applications");
15344
15345        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15346        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15347                Binder.getCallingUid(), verificationCode, failedDomains);
15348        msg.arg1 = id;
15349        msg.obj = response;
15350        mHandler.sendMessage(msg);
15351    }
15352
15353    @Override
15354    public int getIntentVerificationStatus(String packageName, int userId) {
15355        final int callingUid = Binder.getCallingUid();
15356        if (UserHandle.getUserId(callingUid) != userId) {
15357            mContext.enforceCallingOrSelfPermission(
15358                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15359                    "getIntentVerificationStatus" + userId);
15360        }
15361        if (getInstantAppPackageName(callingUid) != null) {
15362            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15363        }
15364        synchronized (mPackages) {
15365            final PackageSetting ps = mSettings.mPackages.get(packageName);
15366            if (ps == null
15367                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15368                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15369            }
15370            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15371        }
15372    }
15373
15374    @Override
15375    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15376        mContext.enforceCallingOrSelfPermission(
15377                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15378
15379        boolean result = false;
15380        synchronized (mPackages) {
15381            final PackageSetting ps = mSettings.mPackages.get(packageName);
15382            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15383                return false;
15384            }
15385            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15386        }
15387        if (result) {
15388            scheduleWritePackageRestrictionsLocked(userId);
15389        }
15390        return result;
15391    }
15392
15393    @Override
15394    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15395            String packageName) {
15396        final int callingUid = Binder.getCallingUid();
15397        if (getInstantAppPackageName(callingUid) != null) {
15398            return ParceledListSlice.emptyList();
15399        }
15400        synchronized (mPackages) {
15401            final PackageSetting ps = mSettings.mPackages.get(packageName);
15402            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15403                return ParceledListSlice.emptyList();
15404            }
15405            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15406        }
15407    }
15408
15409    @Override
15410    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15411        if (TextUtils.isEmpty(packageName)) {
15412            return ParceledListSlice.emptyList();
15413        }
15414        final int callingUid = Binder.getCallingUid();
15415        final int callingUserId = UserHandle.getUserId(callingUid);
15416        synchronized (mPackages) {
15417            PackageParser.Package pkg = mPackages.get(packageName);
15418            if (pkg == null || pkg.activities == null) {
15419                return ParceledListSlice.emptyList();
15420            }
15421            if (pkg.mExtras == null) {
15422                return ParceledListSlice.emptyList();
15423            }
15424            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15425            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15426                return ParceledListSlice.emptyList();
15427            }
15428            final int count = pkg.activities.size();
15429            ArrayList<IntentFilter> result = new ArrayList<>();
15430            for (int n=0; n<count; n++) {
15431                PackageParser.Activity activity = pkg.activities.get(n);
15432                if (activity.intents != null && activity.intents.size() > 0) {
15433                    result.addAll(activity.intents);
15434                }
15435            }
15436            return new ParceledListSlice<>(result);
15437        }
15438    }
15439
15440    @Override
15441    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15442        mContext.enforceCallingOrSelfPermission(
15443                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15444        if (UserHandle.getCallingUserId() != userId) {
15445            mContext.enforceCallingOrSelfPermission(
15446                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15447        }
15448
15449        synchronized (mPackages) {
15450            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15451            if (packageName != null) {
15452                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15453                        packageName, userId);
15454            }
15455            return result;
15456        }
15457    }
15458
15459    @Override
15460    public String getDefaultBrowserPackageName(int userId) {
15461        if (UserHandle.getCallingUserId() != userId) {
15462            mContext.enforceCallingOrSelfPermission(
15463                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15464        }
15465        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15466            return null;
15467        }
15468        synchronized (mPackages) {
15469            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15470        }
15471    }
15472
15473    /**
15474     * Get the "allow unknown sources" setting.
15475     *
15476     * @return the current "allow unknown sources" setting
15477     */
15478    private int getUnknownSourcesSettings() {
15479        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15480                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15481                -1);
15482    }
15483
15484    @Override
15485    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15486        final int callingUid = Binder.getCallingUid();
15487        if (getInstantAppPackageName(callingUid) != null) {
15488            return;
15489        }
15490        // writer
15491        synchronized (mPackages) {
15492            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15493            if (targetPackageSetting == null
15494                    || filterAppAccessLPr(
15495                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15496                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15497            }
15498
15499            PackageSetting installerPackageSetting;
15500            if (installerPackageName != null) {
15501                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15502                if (installerPackageSetting == null) {
15503                    throw new IllegalArgumentException("Unknown installer package: "
15504                            + installerPackageName);
15505                }
15506            } else {
15507                installerPackageSetting = null;
15508            }
15509
15510            Signature[] callerSignature;
15511            Object obj = mSettings.getUserIdLPr(callingUid);
15512            if (obj != null) {
15513                if (obj instanceof SharedUserSetting) {
15514                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15515                } else if (obj instanceof PackageSetting) {
15516                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15517                } else {
15518                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15519                }
15520            } else {
15521                throw new SecurityException("Unknown calling UID: " + callingUid);
15522            }
15523
15524            // Verify: can't set installerPackageName to a package that is
15525            // not signed with the same cert as the caller.
15526            if (installerPackageSetting != null) {
15527                if (compareSignatures(callerSignature,
15528                        installerPackageSetting.signatures.mSignatures)
15529                        != PackageManager.SIGNATURE_MATCH) {
15530                    throw new SecurityException(
15531                            "Caller does not have same cert as new installer package "
15532                            + installerPackageName);
15533                }
15534            }
15535
15536            // Verify: if target already has an installer package, it must
15537            // be signed with the same cert as the caller.
15538            if (targetPackageSetting.installerPackageName != null) {
15539                PackageSetting setting = mSettings.mPackages.get(
15540                        targetPackageSetting.installerPackageName);
15541                // If the currently set package isn't valid, then it's always
15542                // okay to change it.
15543                if (setting != null) {
15544                    if (compareSignatures(callerSignature,
15545                            setting.signatures.mSignatures)
15546                            != PackageManager.SIGNATURE_MATCH) {
15547                        throw new SecurityException(
15548                                "Caller does not have same cert as old installer package "
15549                                + targetPackageSetting.installerPackageName);
15550                    }
15551                }
15552            }
15553
15554            // Okay!
15555            targetPackageSetting.installerPackageName = installerPackageName;
15556            if (installerPackageName != null) {
15557                mSettings.mInstallerPackages.add(installerPackageName);
15558            }
15559            scheduleWriteSettingsLocked();
15560        }
15561    }
15562
15563    @Override
15564    public void setApplicationCategoryHint(String packageName, int categoryHint,
15565            String callerPackageName) {
15566        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15567            throw new SecurityException("Instant applications don't have access to this method");
15568        }
15569        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15570                callerPackageName);
15571        synchronized (mPackages) {
15572            PackageSetting ps = mSettings.mPackages.get(packageName);
15573            if (ps == null) {
15574                throw new IllegalArgumentException("Unknown target package " + packageName);
15575            }
15576            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15577                throw new IllegalArgumentException("Unknown target package " + packageName);
15578            }
15579            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15580                throw new IllegalArgumentException("Calling package " + callerPackageName
15581                        + " is not installer for " + packageName);
15582            }
15583
15584            if (ps.categoryHint != categoryHint) {
15585                ps.categoryHint = categoryHint;
15586                scheduleWriteSettingsLocked();
15587            }
15588        }
15589    }
15590
15591    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15592        // Queue up an async operation since the package installation may take a little while.
15593        mHandler.post(new Runnable() {
15594            public void run() {
15595                mHandler.removeCallbacks(this);
15596                 // Result object to be returned
15597                PackageInstalledInfo res = new PackageInstalledInfo();
15598                res.setReturnCode(currentStatus);
15599                res.uid = -1;
15600                res.pkg = null;
15601                res.removedInfo = null;
15602                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15603                    args.doPreInstall(res.returnCode);
15604                    synchronized (mInstallLock) {
15605                        installPackageTracedLI(args, res);
15606                    }
15607                    args.doPostInstall(res.returnCode, res.uid);
15608                }
15609
15610                // A restore should be performed at this point if (a) the install
15611                // succeeded, (b) the operation is not an update, and (c) the new
15612                // package has not opted out of backup participation.
15613                final boolean update = res.removedInfo != null
15614                        && res.removedInfo.removedPackage != null;
15615                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15616                boolean doRestore = !update
15617                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15618
15619                // Set up the post-install work request bookkeeping.  This will be used
15620                // and cleaned up by the post-install event handling regardless of whether
15621                // there's a restore pass performed.  Token values are >= 1.
15622                int token;
15623                if (mNextInstallToken < 0) mNextInstallToken = 1;
15624                token = mNextInstallToken++;
15625
15626                PostInstallData data = new PostInstallData(args, res);
15627                mRunningInstalls.put(token, data);
15628                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15629
15630                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15631                    // Pass responsibility to the Backup Manager.  It will perform a
15632                    // restore if appropriate, then pass responsibility back to the
15633                    // Package Manager to run the post-install observer callbacks
15634                    // and broadcasts.
15635                    IBackupManager bm = IBackupManager.Stub.asInterface(
15636                            ServiceManager.getService(Context.BACKUP_SERVICE));
15637                    if (bm != null) {
15638                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15639                                + " to BM for possible restore");
15640                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15641                        try {
15642                            // TODO: http://b/22388012
15643                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15644                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15645                            } else {
15646                                doRestore = false;
15647                            }
15648                        } catch (RemoteException e) {
15649                            // can't happen; the backup manager is local
15650                        } catch (Exception e) {
15651                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15652                            doRestore = false;
15653                        }
15654                    } else {
15655                        Slog.e(TAG, "Backup Manager not found!");
15656                        doRestore = false;
15657                    }
15658                }
15659
15660                if (!doRestore) {
15661                    // No restore possible, or the Backup Manager was mysteriously not
15662                    // available -- just fire the post-install work request directly.
15663                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15664
15665                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15666
15667                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15668                    mHandler.sendMessage(msg);
15669                }
15670            }
15671        });
15672    }
15673
15674    /**
15675     * Callback from PackageSettings whenever an app is first transitioned out of the
15676     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15677     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15678     * here whether the app is the target of an ongoing install, and only send the
15679     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15680     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15681     * handling.
15682     */
15683    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15684        // Serialize this with the rest of the install-process message chain.  In the
15685        // restore-at-install case, this Runnable will necessarily run before the
15686        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15687        // are coherent.  In the non-restore case, the app has already completed install
15688        // and been launched through some other means, so it is not in a problematic
15689        // state for observers to see the FIRST_LAUNCH signal.
15690        mHandler.post(new Runnable() {
15691            @Override
15692            public void run() {
15693                for (int i = 0; i < mRunningInstalls.size(); i++) {
15694                    final PostInstallData data = mRunningInstalls.valueAt(i);
15695                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15696                        continue;
15697                    }
15698                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15699                        // right package; but is it for the right user?
15700                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15701                            if (userId == data.res.newUsers[uIndex]) {
15702                                if (DEBUG_BACKUP) {
15703                                    Slog.i(TAG, "Package " + pkgName
15704                                            + " being restored so deferring FIRST_LAUNCH");
15705                                }
15706                                return;
15707                            }
15708                        }
15709                    }
15710                }
15711                // didn't find it, so not being restored
15712                if (DEBUG_BACKUP) {
15713                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15714                }
15715                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15716            }
15717        });
15718    }
15719
15720    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15721        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15722                installerPkg, null, userIds);
15723    }
15724
15725    private abstract class HandlerParams {
15726        private static final int MAX_RETRIES = 4;
15727
15728        /**
15729         * Number of times startCopy() has been attempted and had a non-fatal
15730         * error.
15731         */
15732        private int mRetries = 0;
15733
15734        /** User handle for the user requesting the information or installation. */
15735        private final UserHandle mUser;
15736        String traceMethod;
15737        int traceCookie;
15738
15739        HandlerParams(UserHandle user) {
15740            mUser = user;
15741        }
15742
15743        UserHandle getUser() {
15744            return mUser;
15745        }
15746
15747        HandlerParams setTraceMethod(String traceMethod) {
15748            this.traceMethod = traceMethod;
15749            return this;
15750        }
15751
15752        HandlerParams setTraceCookie(int traceCookie) {
15753            this.traceCookie = traceCookie;
15754            return this;
15755        }
15756
15757        final boolean startCopy() {
15758            boolean res;
15759            try {
15760                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15761
15762                if (++mRetries > MAX_RETRIES) {
15763                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15764                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15765                    handleServiceError();
15766                    return false;
15767                } else {
15768                    handleStartCopy();
15769                    res = true;
15770                }
15771            } catch (RemoteException e) {
15772                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15773                mHandler.sendEmptyMessage(MCS_RECONNECT);
15774                res = false;
15775            }
15776            handleReturnCode();
15777            return res;
15778        }
15779
15780        final void serviceError() {
15781            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15782            handleServiceError();
15783            handleReturnCode();
15784        }
15785
15786        abstract void handleStartCopy() throws RemoteException;
15787        abstract void handleServiceError();
15788        abstract void handleReturnCode();
15789    }
15790
15791    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15792        for (File path : paths) {
15793            try {
15794                mcs.clearDirectory(path.getAbsolutePath());
15795            } catch (RemoteException e) {
15796            }
15797        }
15798    }
15799
15800    static class OriginInfo {
15801        /**
15802         * Location where install is coming from, before it has been
15803         * copied/renamed into place. This could be a single monolithic APK
15804         * file, or a cluster directory. This location may be untrusted.
15805         */
15806        final File file;
15807        final String cid;
15808
15809        /**
15810         * Flag indicating that {@link #file} or {@link #cid} has already been
15811         * staged, meaning downstream users don't need to defensively copy the
15812         * contents.
15813         */
15814        final boolean staged;
15815
15816        /**
15817         * Flag indicating that {@link #file} or {@link #cid} is an already
15818         * installed app that is being moved.
15819         */
15820        final boolean existing;
15821
15822        final String resolvedPath;
15823        final File resolvedFile;
15824
15825        static OriginInfo fromNothing() {
15826            return new OriginInfo(null, null, false, false);
15827        }
15828
15829        static OriginInfo fromUntrustedFile(File file) {
15830            return new OriginInfo(file, null, false, false);
15831        }
15832
15833        static OriginInfo fromExistingFile(File file) {
15834            return new OriginInfo(file, null, false, true);
15835        }
15836
15837        static OriginInfo fromStagedFile(File file) {
15838            return new OriginInfo(file, null, true, false);
15839        }
15840
15841        static OriginInfo fromStagedContainer(String cid) {
15842            return new OriginInfo(null, cid, true, false);
15843        }
15844
15845        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
15846            this.file = file;
15847            this.cid = cid;
15848            this.staged = staged;
15849            this.existing = existing;
15850
15851            if (cid != null) {
15852                resolvedPath = PackageHelper.getSdDir(cid);
15853                resolvedFile = new File(resolvedPath);
15854            } else if (file != null) {
15855                resolvedPath = file.getAbsolutePath();
15856                resolvedFile = file;
15857            } else {
15858                resolvedPath = null;
15859                resolvedFile = null;
15860            }
15861        }
15862    }
15863
15864    static class MoveInfo {
15865        final int moveId;
15866        final String fromUuid;
15867        final String toUuid;
15868        final String packageName;
15869        final String dataAppName;
15870        final int appId;
15871        final String seinfo;
15872        final int targetSdkVersion;
15873
15874        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15875                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15876            this.moveId = moveId;
15877            this.fromUuid = fromUuid;
15878            this.toUuid = toUuid;
15879            this.packageName = packageName;
15880            this.dataAppName = dataAppName;
15881            this.appId = appId;
15882            this.seinfo = seinfo;
15883            this.targetSdkVersion = targetSdkVersion;
15884        }
15885    }
15886
15887    static class VerificationInfo {
15888        /** A constant used to indicate that a uid value is not present. */
15889        public static final int NO_UID = -1;
15890
15891        /** URI referencing where the package was downloaded from. */
15892        final Uri originatingUri;
15893
15894        /** HTTP referrer URI associated with the originatingURI. */
15895        final Uri referrer;
15896
15897        /** UID of the application that the install request originated from. */
15898        final int originatingUid;
15899
15900        /** UID of application requesting the install */
15901        final int installerUid;
15902
15903        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15904            this.originatingUri = originatingUri;
15905            this.referrer = referrer;
15906            this.originatingUid = originatingUid;
15907            this.installerUid = installerUid;
15908        }
15909    }
15910
15911    class InstallParams extends HandlerParams {
15912        final OriginInfo origin;
15913        final MoveInfo move;
15914        final IPackageInstallObserver2 observer;
15915        int installFlags;
15916        final String installerPackageName;
15917        final String volumeUuid;
15918        private InstallArgs mArgs;
15919        private int mRet;
15920        final String packageAbiOverride;
15921        final String[] grantedRuntimePermissions;
15922        final VerificationInfo verificationInfo;
15923        final Certificate[][] certificates;
15924        final int installReason;
15925
15926        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15927                int installFlags, String installerPackageName, String volumeUuid,
15928                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15929                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15930            super(user);
15931            this.origin = origin;
15932            this.move = move;
15933            this.observer = observer;
15934            this.installFlags = installFlags;
15935            this.installerPackageName = installerPackageName;
15936            this.volumeUuid = volumeUuid;
15937            this.verificationInfo = verificationInfo;
15938            this.packageAbiOverride = packageAbiOverride;
15939            this.grantedRuntimePermissions = grantedPermissions;
15940            this.certificates = certificates;
15941            this.installReason = installReason;
15942        }
15943
15944        @Override
15945        public String toString() {
15946            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15947                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15948        }
15949
15950        private int installLocationPolicy(PackageInfoLite pkgLite) {
15951            String packageName = pkgLite.packageName;
15952            int installLocation = pkgLite.installLocation;
15953            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15954            // reader
15955            synchronized (mPackages) {
15956                // Currently installed package which the new package is attempting to replace or
15957                // null if no such package is installed.
15958                PackageParser.Package installedPkg = mPackages.get(packageName);
15959                // Package which currently owns the data which the new package will own if installed.
15960                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15961                // will be null whereas dataOwnerPkg will contain information about the package
15962                // which was uninstalled while keeping its data.
15963                PackageParser.Package dataOwnerPkg = installedPkg;
15964                if (dataOwnerPkg  == null) {
15965                    PackageSetting ps = mSettings.mPackages.get(packageName);
15966                    if (ps != null) {
15967                        dataOwnerPkg = ps.pkg;
15968                    }
15969                }
15970
15971                if (dataOwnerPkg != null) {
15972                    // If installed, the package will get access to data left on the device by its
15973                    // predecessor. As a security measure, this is permited only if this is not a
15974                    // version downgrade or if the predecessor package is marked as debuggable and
15975                    // a downgrade is explicitly requested.
15976                    //
15977                    // On debuggable platform builds, downgrades are permitted even for
15978                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15979                    // not offer security guarantees and thus it's OK to disable some security
15980                    // mechanisms to make debugging/testing easier on those builds. However, even on
15981                    // debuggable builds downgrades of packages are permitted only if requested via
15982                    // installFlags. This is because we aim to keep the behavior of debuggable
15983                    // platform builds as close as possible to the behavior of non-debuggable
15984                    // platform builds.
15985                    final boolean downgradeRequested =
15986                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15987                    final boolean packageDebuggable =
15988                                (dataOwnerPkg.applicationInfo.flags
15989                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15990                    final boolean downgradePermitted =
15991                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15992                    if (!downgradePermitted) {
15993                        try {
15994                            checkDowngrade(dataOwnerPkg, pkgLite);
15995                        } catch (PackageManagerException e) {
15996                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15997                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15998                        }
15999                    }
16000                }
16001
16002                if (installedPkg != null) {
16003                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16004                        // Check for updated system application.
16005                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16006                            if (onSd) {
16007                                Slog.w(TAG, "Cannot install update to system app on sdcard");
16008                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16009                            }
16010                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16011                        } else {
16012                            if (onSd) {
16013                                // Install flag overrides everything.
16014                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16015                            }
16016                            // If current upgrade specifies particular preference
16017                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16018                                // Application explicitly specified internal.
16019                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16020                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16021                                // App explictly prefers external. Let policy decide
16022                            } else {
16023                                // Prefer previous location
16024                                if (isExternal(installedPkg)) {
16025                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16026                                }
16027                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16028                            }
16029                        }
16030                    } else {
16031                        // Invalid install. Return error code
16032                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16033                    }
16034                }
16035            }
16036            // All the special cases have been taken care of.
16037            // Return result based on recommended install location.
16038            if (onSd) {
16039                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16040            }
16041            return pkgLite.recommendedInstallLocation;
16042        }
16043
16044        /*
16045         * Invoke remote method to get package information and install
16046         * location values. Override install location based on default
16047         * policy if needed and then create install arguments based
16048         * on the install location.
16049         */
16050        public void handleStartCopy() throws RemoteException {
16051            int ret = PackageManager.INSTALL_SUCCEEDED;
16052
16053            // If we're already staged, we've firmly committed to an install location
16054            if (origin.staged) {
16055                if (origin.file != null) {
16056                    installFlags |= PackageManager.INSTALL_INTERNAL;
16057                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16058                } else if (origin.cid != null) {
16059                    installFlags |= PackageManager.INSTALL_EXTERNAL;
16060                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
16061                } else {
16062                    throw new IllegalStateException("Invalid stage location");
16063                }
16064            }
16065
16066            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16067            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16068            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16069            PackageInfoLite pkgLite = null;
16070
16071            if (onInt && onSd) {
16072                // Check if both bits are set.
16073                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16074                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16075            } else if (onSd && ephemeral) {
16076                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16077                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16078            } else {
16079                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16080                        packageAbiOverride);
16081
16082                if (DEBUG_EPHEMERAL && ephemeral) {
16083                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
16084                }
16085
16086                /*
16087                 * If we have too little free space, try to free cache
16088                 * before giving up.
16089                 */
16090                if (!origin.staged && pkgLite.recommendedInstallLocation
16091                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16092                    // TODO: focus freeing disk space on the target device
16093                    final StorageManager storage = StorageManager.from(mContext);
16094                    final long lowThreshold = storage.getStorageLowBytes(
16095                            Environment.getDataDirectory());
16096
16097                    final long sizeBytes = mContainerService.calculateInstalledSize(
16098                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16099
16100                    try {
16101                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16102                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16103                                installFlags, packageAbiOverride);
16104                    } catch (InstallerException e) {
16105                        Slog.w(TAG, "Failed to free cache", e);
16106                    }
16107
16108                    /*
16109                     * The cache free must have deleted the file we
16110                     * downloaded to install.
16111                     *
16112                     * TODO: fix the "freeCache" call to not delete
16113                     *       the file we care about.
16114                     */
16115                    if (pkgLite.recommendedInstallLocation
16116                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16117                        pkgLite.recommendedInstallLocation
16118                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16119                    }
16120                }
16121            }
16122
16123            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16124                int loc = pkgLite.recommendedInstallLocation;
16125                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16126                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16127                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16128                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16129                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16130                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16131                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16132                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16133                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16134                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16135                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16136                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16137                } else {
16138                    // Override with defaults if needed.
16139                    loc = installLocationPolicy(pkgLite);
16140                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16141                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16142                    } else if (!onSd && !onInt) {
16143                        // Override install location with flags
16144                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16145                            // Set the flag to install on external media.
16146                            installFlags |= PackageManager.INSTALL_EXTERNAL;
16147                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
16148                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16149                            if (DEBUG_EPHEMERAL) {
16150                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16151                            }
16152                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
16153                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16154                                    |PackageManager.INSTALL_INTERNAL);
16155                        } else {
16156                            // Make sure the flag for installing on external
16157                            // media is unset
16158                            installFlags |= PackageManager.INSTALL_INTERNAL;
16159                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16160                        }
16161                    }
16162                }
16163            }
16164
16165            final InstallArgs args = createInstallArgs(this);
16166            mArgs = args;
16167
16168            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16169                // TODO: http://b/22976637
16170                // Apps installed for "all" users use the device owner to verify the app
16171                UserHandle verifierUser = getUser();
16172                if (verifierUser == UserHandle.ALL) {
16173                    verifierUser = UserHandle.SYSTEM;
16174                }
16175
16176                /*
16177                 * Determine if we have any installed package verifiers. If we
16178                 * do, then we'll defer to them to verify the packages.
16179                 */
16180                final int requiredUid = mRequiredVerifierPackage == null ? -1
16181                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16182                                verifierUser.getIdentifier());
16183                final int installerUid =
16184                        verificationInfo == null ? -1 : verificationInfo.installerUid;
16185                if (!origin.existing && requiredUid != -1
16186                        && isVerificationEnabled(
16187                                verifierUser.getIdentifier(), installFlags, installerUid)) {
16188                    final Intent verification = new Intent(
16189                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16190                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16191                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16192                            PACKAGE_MIME_TYPE);
16193                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16194
16195                    // Query all live verifiers based on current user state
16196                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16197                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
16198
16199                    if (DEBUG_VERIFY) {
16200                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16201                                + verification.toString() + " with " + pkgLite.verifiers.length
16202                                + " optional verifiers");
16203                    }
16204
16205                    final int verificationId = mPendingVerificationToken++;
16206
16207                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16208
16209                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16210                            installerPackageName);
16211
16212                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16213                            installFlags);
16214
16215                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16216                            pkgLite.packageName);
16217
16218                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16219                            pkgLite.versionCode);
16220
16221                    if (verificationInfo != null) {
16222                        if (verificationInfo.originatingUri != null) {
16223                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16224                                    verificationInfo.originatingUri);
16225                        }
16226                        if (verificationInfo.referrer != null) {
16227                            verification.putExtra(Intent.EXTRA_REFERRER,
16228                                    verificationInfo.referrer);
16229                        }
16230                        if (verificationInfo.originatingUid >= 0) {
16231                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16232                                    verificationInfo.originatingUid);
16233                        }
16234                        if (verificationInfo.installerUid >= 0) {
16235                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16236                                    verificationInfo.installerUid);
16237                        }
16238                    }
16239
16240                    final PackageVerificationState verificationState = new PackageVerificationState(
16241                            requiredUid, args);
16242
16243                    mPendingVerification.append(verificationId, verificationState);
16244
16245                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16246                            receivers, verificationState);
16247
16248                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
16249                    final long idleDuration = getVerificationTimeout();
16250
16251                    /*
16252                     * If any sufficient verifiers were listed in the package
16253                     * manifest, attempt to ask them.
16254                     */
16255                    if (sufficientVerifiers != null) {
16256                        final int N = sufficientVerifiers.size();
16257                        if (N == 0) {
16258                            Slog.i(TAG, "Additional verifiers required, but none installed.");
16259                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16260                        } else {
16261                            for (int i = 0; i < N; i++) {
16262                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
16263                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16264                                        verifierComponent.getPackageName(), idleDuration,
16265                                        verifierUser.getIdentifier(), false, "package verifier");
16266
16267                                final Intent sufficientIntent = new Intent(verification);
16268                                sufficientIntent.setComponent(verifierComponent);
16269                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16270                            }
16271                        }
16272                    }
16273
16274                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16275                            mRequiredVerifierPackage, receivers);
16276                    if (ret == PackageManager.INSTALL_SUCCEEDED
16277                            && mRequiredVerifierPackage != null) {
16278                        Trace.asyncTraceBegin(
16279                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16280                        /*
16281                         * Send the intent to the required verification agent,
16282                         * but only start the verification timeout after the
16283                         * target BroadcastReceivers have run.
16284                         */
16285                        verification.setComponent(requiredVerifierComponent);
16286                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16287                                mRequiredVerifierPackage, idleDuration,
16288                                verifierUser.getIdentifier(), false, "package verifier");
16289                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16290                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16291                                new BroadcastReceiver() {
16292                                    @Override
16293                                    public void onReceive(Context context, Intent intent) {
16294                                        final Message msg = mHandler
16295                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
16296                                        msg.arg1 = verificationId;
16297                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16298                                    }
16299                                }, null, 0, null, null);
16300
16301                        /*
16302                         * We don't want the copy to proceed until verification
16303                         * succeeds, so null out this field.
16304                         */
16305                        mArgs = null;
16306                    }
16307                } else {
16308                    /*
16309                     * No package verification is enabled, so immediately start
16310                     * the remote call to initiate copy using temporary file.
16311                     */
16312                    ret = args.copyApk(mContainerService, true);
16313                }
16314            }
16315
16316            mRet = ret;
16317        }
16318
16319        @Override
16320        void handleReturnCode() {
16321            // If mArgs is null, then MCS couldn't be reached. When it
16322            // reconnects, it will try again to install. At that point, this
16323            // will succeed.
16324            if (mArgs != null) {
16325                processPendingInstall(mArgs, mRet);
16326            }
16327        }
16328
16329        @Override
16330        void handleServiceError() {
16331            mArgs = createInstallArgs(this);
16332            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16333        }
16334
16335        public boolean isForwardLocked() {
16336            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16337        }
16338    }
16339
16340    /**
16341     * Used during creation of InstallArgs
16342     *
16343     * @param installFlags package installation flags
16344     * @return true if should be installed on external storage
16345     */
16346    private static boolean installOnExternalAsec(int installFlags) {
16347        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16348            return false;
16349        }
16350        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16351            return true;
16352        }
16353        return false;
16354    }
16355
16356    /**
16357     * Used during creation of InstallArgs
16358     *
16359     * @param installFlags package installation flags
16360     * @return true if should be installed as forward locked
16361     */
16362    private static boolean installForwardLocked(int installFlags) {
16363        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16364    }
16365
16366    private InstallArgs createInstallArgs(InstallParams params) {
16367        if (params.move != null) {
16368            return new MoveInstallArgs(params);
16369        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16370            return new AsecInstallArgs(params);
16371        } else {
16372            return new FileInstallArgs(params);
16373        }
16374    }
16375
16376    /**
16377     * Create args that describe an existing installed package. Typically used
16378     * when cleaning up old installs, or used as a move source.
16379     */
16380    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16381            String resourcePath, String[] instructionSets) {
16382        final boolean isInAsec;
16383        if (installOnExternalAsec(installFlags)) {
16384            /* Apps on SD card are always in ASEC containers. */
16385            isInAsec = true;
16386        } else if (installForwardLocked(installFlags)
16387                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16388            /*
16389             * Forward-locked apps are only in ASEC containers if they're the
16390             * new style
16391             */
16392            isInAsec = true;
16393        } else {
16394            isInAsec = false;
16395        }
16396
16397        if (isInAsec) {
16398            return new AsecInstallArgs(codePath, instructionSets,
16399                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16400        } else {
16401            return new FileInstallArgs(codePath, resourcePath, instructionSets);
16402        }
16403    }
16404
16405    static abstract class InstallArgs {
16406        /** @see InstallParams#origin */
16407        final OriginInfo origin;
16408        /** @see InstallParams#move */
16409        final MoveInfo move;
16410
16411        final IPackageInstallObserver2 observer;
16412        // Always refers to PackageManager flags only
16413        final int installFlags;
16414        final String installerPackageName;
16415        final String volumeUuid;
16416        final UserHandle user;
16417        final String abiOverride;
16418        final String[] installGrantPermissions;
16419        /** If non-null, drop an async trace when the install completes */
16420        final String traceMethod;
16421        final int traceCookie;
16422        final Certificate[][] certificates;
16423        final int installReason;
16424
16425        // The list of instruction sets supported by this app. This is currently
16426        // only used during the rmdex() phase to clean up resources. We can get rid of this
16427        // if we move dex files under the common app path.
16428        /* nullable */ String[] instructionSets;
16429
16430        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16431                int installFlags, String installerPackageName, String volumeUuid,
16432                UserHandle user, String[] instructionSets,
16433                String abiOverride, String[] installGrantPermissions,
16434                String traceMethod, int traceCookie, Certificate[][] certificates,
16435                int installReason) {
16436            this.origin = origin;
16437            this.move = move;
16438            this.installFlags = installFlags;
16439            this.observer = observer;
16440            this.installerPackageName = installerPackageName;
16441            this.volumeUuid = volumeUuid;
16442            this.user = user;
16443            this.instructionSets = instructionSets;
16444            this.abiOverride = abiOverride;
16445            this.installGrantPermissions = installGrantPermissions;
16446            this.traceMethod = traceMethod;
16447            this.traceCookie = traceCookie;
16448            this.certificates = certificates;
16449            this.installReason = installReason;
16450        }
16451
16452        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16453        abstract int doPreInstall(int status);
16454
16455        /**
16456         * Rename package into final resting place. All paths on the given
16457         * scanned package should be updated to reflect the rename.
16458         */
16459        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16460        abstract int doPostInstall(int status, int uid);
16461
16462        /** @see PackageSettingBase#codePathString */
16463        abstract String getCodePath();
16464        /** @see PackageSettingBase#resourcePathString */
16465        abstract String getResourcePath();
16466
16467        // Need installer lock especially for dex file removal.
16468        abstract void cleanUpResourcesLI();
16469        abstract boolean doPostDeleteLI(boolean delete);
16470
16471        /**
16472         * Called before the source arguments are copied. This is used mostly
16473         * for MoveParams when it needs to read the source file to put it in the
16474         * destination.
16475         */
16476        int doPreCopy() {
16477            return PackageManager.INSTALL_SUCCEEDED;
16478        }
16479
16480        /**
16481         * Called after the source arguments are copied. This is used mostly for
16482         * MoveParams when it needs to read the source file to put it in the
16483         * destination.
16484         */
16485        int doPostCopy(int uid) {
16486            return PackageManager.INSTALL_SUCCEEDED;
16487        }
16488
16489        protected boolean isFwdLocked() {
16490            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16491        }
16492
16493        protected boolean isExternalAsec() {
16494            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16495        }
16496
16497        protected boolean isEphemeral() {
16498            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16499        }
16500
16501        UserHandle getUser() {
16502            return user;
16503        }
16504    }
16505
16506    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16507        if (!allCodePaths.isEmpty()) {
16508            if (instructionSets == null) {
16509                throw new IllegalStateException("instructionSet == null");
16510            }
16511            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16512            for (String codePath : allCodePaths) {
16513                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16514                    try {
16515                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16516                    } catch (InstallerException ignored) {
16517                    }
16518                }
16519            }
16520        }
16521    }
16522
16523    /**
16524     * Logic to handle installation of non-ASEC applications, including copying
16525     * and renaming logic.
16526     */
16527    class FileInstallArgs extends InstallArgs {
16528        private File codeFile;
16529        private File resourceFile;
16530
16531        // Example topology:
16532        // /data/app/com.example/base.apk
16533        // /data/app/com.example/split_foo.apk
16534        // /data/app/com.example/lib/arm/libfoo.so
16535        // /data/app/com.example/lib/arm64/libfoo.so
16536        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16537
16538        /** New install */
16539        FileInstallArgs(InstallParams params) {
16540            super(params.origin, params.move, params.observer, params.installFlags,
16541                    params.installerPackageName, params.volumeUuid,
16542                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16543                    params.grantedRuntimePermissions,
16544                    params.traceMethod, params.traceCookie, params.certificates,
16545                    params.installReason);
16546            if (isFwdLocked()) {
16547                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16548            }
16549        }
16550
16551        /** Existing install */
16552        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16553            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16554                    null, null, null, 0, null /*certificates*/,
16555                    PackageManager.INSTALL_REASON_UNKNOWN);
16556            this.codeFile = (codePath != null) ? new File(codePath) : null;
16557            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16558        }
16559
16560        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16561            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16562            try {
16563                return doCopyApk(imcs, temp);
16564            } finally {
16565                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16566            }
16567        }
16568
16569        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16570            if (origin.staged) {
16571                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16572                codeFile = origin.file;
16573                resourceFile = origin.file;
16574                return PackageManager.INSTALL_SUCCEEDED;
16575            }
16576
16577            try {
16578                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16579                final File tempDir =
16580                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16581                codeFile = tempDir;
16582                resourceFile = tempDir;
16583            } catch (IOException e) {
16584                Slog.w(TAG, "Failed to create copy file: " + e);
16585                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16586            }
16587
16588            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16589                @Override
16590                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16591                    if (!FileUtils.isValidExtFilename(name)) {
16592                        throw new IllegalArgumentException("Invalid filename: " + name);
16593                    }
16594                    try {
16595                        final File file = new File(codeFile, name);
16596                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16597                                O_RDWR | O_CREAT, 0644);
16598                        Os.chmod(file.getAbsolutePath(), 0644);
16599                        return new ParcelFileDescriptor(fd);
16600                    } catch (ErrnoException e) {
16601                        throw new RemoteException("Failed to open: " + e.getMessage());
16602                    }
16603                }
16604            };
16605
16606            int ret = PackageManager.INSTALL_SUCCEEDED;
16607            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16608            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16609                Slog.e(TAG, "Failed to copy package");
16610                return ret;
16611            }
16612
16613            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16614            NativeLibraryHelper.Handle handle = null;
16615            try {
16616                handle = NativeLibraryHelper.Handle.create(codeFile);
16617                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16618                        abiOverride);
16619            } catch (IOException e) {
16620                Slog.e(TAG, "Copying native libraries failed", e);
16621                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16622            } finally {
16623                IoUtils.closeQuietly(handle);
16624            }
16625
16626            return ret;
16627        }
16628
16629        int doPreInstall(int status) {
16630            if (status != PackageManager.INSTALL_SUCCEEDED) {
16631                cleanUp();
16632            }
16633            return status;
16634        }
16635
16636        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16637            if (status != PackageManager.INSTALL_SUCCEEDED) {
16638                cleanUp();
16639                return false;
16640            }
16641
16642            final File targetDir = codeFile.getParentFile();
16643            final File beforeCodeFile = codeFile;
16644            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16645
16646            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16647            try {
16648                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16649            } catch (ErrnoException e) {
16650                Slog.w(TAG, "Failed to rename", e);
16651                return false;
16652            }
16653
16654            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16655                Slog.w(TAG, "Failed to restorecon");
16656                return false;
16657            }
16658
16659            // Reflect the rename internally
16660            codeFile = afterCodeFile;
16661            resourceFile = afterCodeFile;
16662
16663            // Reflect the rename in scanned details
16664            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16665            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16666                    afterCodeFile, pkg.baseCodePath));
16667            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16668                    afterCodeFile, pkg.splitCodePaths));
16669
16670            // Reflect the rename in app info
16671            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16672            pkg.setApplicationInfoCodePath(pkg.codePath);
16673            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16674            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16675            pkg.setApplicationInfoResourcePath(pkg.codePath);
16676            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16677            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16678
16679            return true;
16680        }
16681
16682        int doPostInstall(int status, int uid) {
16683            if (status != PackageManager.INSTALL_SUCCEEDED) {
16684                cleanUp();
16685            }
16686            return status;
16687        }
16688
16689        @Override
16690        String getCodePath() {
16691            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16692        }
16693
16694        @Override
16695        String getResourcePath() {
16696            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16697        }
16698
16699        private boolean cleanUp() {
16700            if (codeFile == null || !codeFile.exists()) {
16701                return false;
16702            }
16703
16704            removeCodePathLI(codeFile);
16705
16706            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16707                resourceFile.delete();
16708            }
16709
16710            return true;
16711        }
16712
16713        void cleanUpResourcesLI() {
16714            // Try enumerating all code paths before deleting
16715            List<String> allCodePaths = Collections.EMPTY_LIST;
16716            if (codeFile != null && codeFile.exists()) {
16717                try {
16718                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16719                    allCodePaths = pkg.getAllCodePaths();
16720                } catch (PackageParserException e) {
16721                    // Ignored; we tried our best
16722                }
16723            }
16724
16725            cleanUp();
16726            removeDexFiles(allCodePaths, instructionSets);
16727        }
16728
16729        boolean doPostDeleteLI(boolean delete) {
16730            // XXX err, shouldn't we respect the delete flag?
16731            cleanUpResourcesLI();
16732            return true;
16733        }
16734    }
16735
16736    private boolean isAsecExternal(String cid) {
16737        final String asecPath = PackageHelper.getSdFilesystem(cid);
16738        return !asecPath.startsWith(mAsecInternalPath);
16739    }
16740
16741    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16742            PackageManagerException {
16743        if (copyRet < 0) {
16744            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16745                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16746                throw new PackageManagerException(copyRet, message);
16747            }
16748        }
16749    }
16750
16751    /**
16752     * Extract the StorageManagerService "container ID" from the full code path of an
16753     * .apk.
16754     */
16755    static String cidFromCodePath(String fullCodePath) {
16756        int eidx = fullCodePath.lastIndexOf("/");
16757        String subStr1 = fullCodePath.substring(0, eidx);
16758        int sidx = subStr1.lastIndexOf("/");
16759        return subStr1.substring(sidx+1, eidx);
16760    }
16761
16762    /**
16763     * Logic to handle installation of ASEC applications, including copying and
16764     * renaming logic.
16765     */
16766    class AsecInstallArgs extends InstallArgs {
16767        static final String RES_FILE_NAME = "pkg.apk";
16768        static final String PUBLIC_RES_FILE_NAME = "res.zip";
16769
16770        String cid;
16771        String packagePath;
16772        String resourcePath;
16773
16774        /** New install */
16775        AsecInstallArgs(InstallParams params) {
16776            super(params.origin, params.move, params.observer, params.installFlags,
16777                    params.installerPackageName, params.volumeUuid,
16778                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16779                    params.grantedRuntimePermissions,
16780                    params.traceMethod, params.traceCookie, params.certificates,
16781                    params.installReason);
16782        }
16783
16784        /** Existing install */
16785        AsecInstallArgs(String fullCodePath, String[] instructionSets,
16786                        boolean isExternal, boolean isForwardLocked) {
16787            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
16788                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16789                    instructionSets, null, null, null, 0, null /*certificates*/,
16790                    PackageManager.INSTALL_REASON_UNKNOWN);
16791            // Hackily pretend we're still looking at a full code path
16792            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
16793                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
16794            }
16795
16796            // Extract cid from fullCodePath
16797            int eidx = fullCodePath.lastIndexOf("/");
16798            String subStr1 = fullCodePath.substring(0, eidx);
16799            int sidx = subStr1.lastIndexOf("/");
16800            cid = subStr1.substring(sidx+1, eidx);
16801            setMountPath(subStr1);
16802        }
16803
16804        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
16805            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
16806                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16807                    instructionSets, null, null, null, 0, null /*certificates*/,
16808                    PackageManager.INSTALL_REASON_UNKNOWN);
16809            this.cid = cid;
16810            setMountPath(PackageHelper.getSdDir(cid));
16811        }
16812
16813        void createCopyFile() {
16814            cid = mInstallerService.allocateExternalStageCidLegacy();
16815        }
16816
16817        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16818            if (origin.staged && origin.cid != null) {
16819                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
16820                cid = origin.cid;
16821                setMountPath(PackageHelper.getSdDir(cid));
16822                return PackageManager.INSTALL_SUCCEEDED;
16823            }
16824
16825            if (temp) {
16826                createCopyFile();
16827            } else {
16828                /*
16829                 * Pre-emptively destroy the container since it's destroyed if
16830                 * copying fails due to it existing anyway.
16831                 */
16832                PackageHelper.destroySdDir(cid);
16833            }
16834
16835            final String newMountPath = imcs.copyPackageToContainer(
16836                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
16837                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
16838
16839            if (newMountPath != null) {
16840                setMountPath(newMountPath);
16841                return PackageManager.INSTALL_SUCCEEDED;
16842            } else {
16843                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16844            }
16845        }
16846
16847        @Override
16848        String getCodePath() {
16849            return packagePath;
16850        }
16851
16852        @Override
16853        String getResourcePath() {
16854            return resourcePath;
16855        }
16856
16857        int doPreInstall(int status) {
16858            if (status != PackageManager.INSTALL_SUCCEEDED) {
16859                // Destroy container
16860                PackageHelper.destroySdDir(cid);
16861            } else {
16862                boolean mounted = PackageHelper.isContainerMounted(cid);
16863                if (!mounted) {
16864                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
16865                            Process.SYSTEM_UID);
16866                    if (newMountPath != null) {
16867                        setMountPath(newMountPath);
16868                    } else {
16869                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16870                    }
16871                }
16872            }
16873            return status;
16874        }
16875
16876        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16877            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
16878            String newMountPath = null;
16879            if (PackageHelper.isContainerMounted(cid)) {
16880                // Unmount the container
16881                if (!PackageHelper.unMountSdDir(cid)) {
16882                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
16883                    return false;
16884                }
16885            }
16886            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16887                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
16888                        " which might be stale. Will try to clean up.");
16889                // Clean up the stale container and proceed to recreate.
16890                if (!PackageHelper.destroySdDir(newCacheId)) {
16891                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
16892                    return false;
16893                }
16894                // Successfully cleaned up stale container. Try to rename again.
16895                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16896                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
16897                            + " inspite of cleaning it up.");
16898                    return false;
16899                }
16900            }
16901            if (!PackageHelper.isContainerMounted(newCacheId)) {
16902                Slog.w(TAG, "Mounting container " + newCacheId);
16903                newMountPath = PackageHelper.mountSdDir(newCacheId,
16904                        getEncryptKey(), Process.SYSTEM_UID);
16905            } else {
16906                newMountPath = PackageHelper.getSdDir(newCacheId);
16907            }
16908            if (newMountPath == null) {
16909                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
16910                return false;
16911            }
16912            Log.i(TAG, "Succesfully renamed " + cid +
16913                    " to " + newCacheId +
16914                    " at new path: " + newMountPath);
16915            cid = newCacheId;
16916
16917            final File beforeCodeFile = new File(packagePath);
16918            setMountPath(newMountPath);
16919            final File afterCodeFile = new File(packagePath);
16920
16921            // Reflect the rename in scanned details
16922            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16923            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16924                    afterCodeFile, pkg.baseCodePath));
16925            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16926                    afterCodeFile, pkg.splitCodePaths));
16927
16928            // Reflect the rename in app info
16929            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16930            pkg.setApplicationInfoCodePath(pkg.codePath);
16931            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16932            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16933            pkg.setApplicationInfoResourcePath(pkg.codePath);
16934            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16935            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16936
16937            return true;
16938        }
16939
16940        private void setMountPath(String mountPath) {
16941            final File mountFile = new File(mountPath);
16942
16943            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16944            if (monolithicFile.exists()) {
16945                packagePath = monolithicFile.getAbsolutePath();
16946                if (isFwdLocked()) {
16947                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16948                } else {
16949                    resourcePath = packagePath;
16950                }
16951            } else {
16952                packagePath = mountFile.getAbsolutePath();
16953                resourcePath = packagePath;
16954            }
16955        }
16956
16957        int doPostInstall(int status, int uid) {
16958            if (status != PackageManager.INSTALL_SUCCEEDED) {
16959                cleanUp();
16960            } else {
16961                final int groupOwner;
16962                final String protectedFile;
16963                if (isFwdLocked()) {
16964                    groupOwner = UserHandle.getSharedAppGid(uid);
16965                    protectedFile = RES_FILE_NAME;
16966                } else {
16967                    groupOwner = -1;
16968                    protectedFile = null;
16969                }
16970
16971                if (uid < Process.FIRST_APPLICATION_UID
16972                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16973                    Slog.e(TAG, "Failed to finalize " + cid);
16974                    PackageHelper.destroySdDir(cid);
16975                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16976                }
16977
16978                boolean mounted = PackageHelper.isContainerMounted(cid);
16979                if (!mounted) {
16980                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16981                }
16982            }
16983            return status;
16984        }
16985
16986        private void cleanUp() {
16987            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16988
16989            // Destroy secure container
16990            PackageHelper.destroySdDir(cid);
16991        }
16992
16993        private List<String> getAllCodePaths() {
16994            final File codeFile = new File(getCodePath());
16995            if (codeFile != null && codeFile.exists()) {
16996                try {
16997                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16998                    return pkg.getAllCodePaths();
16999                } catch (PackageParserException e) {
17000                    // Ignored; we tried our best
17001                }
17002            }
17003            return Collections.EMPTY_LIST;
17004        }
17005
17006        void cleanUpResourcesLI() {
17007            // Enumerate all code paths before deleting
17008            cleanUpResourcesLI(getAllCodePaths());
17009        }
17010
17011        private void cleanUpResourcesLI(List<String> allCodePaths) {
17012            cleanUp();
17013            removeDexFiles(allCodePaths, instructionSets);
17014        }
17015
17016        String getPackageName() {
17017            return getAsecPackageName(cid);
17018        }
17019
17020        boolean doPostDeleteLI(boolean delete) {
17021            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17022            final List<String> allCodePaths = getAllCodePaths();
17023            boolean mounted = PackageHelper.isContainerMounted(cid);
17024            if (mounted) {
17025                // Unmount first
17026                if (PackageHelper.unMountSdDir(cid)) {
17027                    mounted = false;
17028                }
17029            }
17030            if (!mounted && delete) {
17031                cleanUpResourcesLI(allCodePaths);
17032            }
17033            return !mounted;
17034        }
17035
17036        @Override
17037        int doPreCopy() {
17038            if (isFwdLocked()) {
17039                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17040                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17041                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17042                }
17043            }
17044
17045            return PackageManager.INSTALL_SUCCEEDED;
17046        }
17047
17048        @Override
17049        int doPostCopy(int uid) {
17050            if (isFwdLocked()) {
17051                if (uid < Process.FIRST_APPLICATION_UID
17052                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17053                                RES_FILE_NAME)) {
17054                    Slog.e(TAG, "Failed to finalize " + cid);
17055                    PackageHelper.destroySdDir(cid);
17056                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17057                }
17058            }
17059
17060            return PackageManager.INSTALL_SUCCEEDED;
17061        }
17062    }
17063
17064    /**
17065     * Logic to handle movement of existing installed applications.
17066     */
17067    class MoveInstallArgs extends InstallArgs {
17068        private File codeFile;
17069        private File resourceFile;
17070
17071        /** New install */
17072        MoveInstallArgs(InstallParams params) {
17073            super(params.origin, params.move, params.observer, params.installFlags,
17074                    params.installerPackageName, params.volumeUuid,
17075                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17076                    params.grantedRuntimePermissions,
17077                    params.traceMethod, params.traceCookie, params.certificates,
17078                    params.installReason);
17079        }
17080
17081        int copyApk(IMediaContainerService imcs, boolean temp) {
17082            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17083                    + move.fromUuid + " to " + move.toUuid);
17084            synchronized (mInstaller) {
17085                try {
17086                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17087                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17088                } catch (InstallerException e) {
17089                    Slog.w(TAG, "Failed to move app", e);
17090                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17091                }
17092            }
17093
17094            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17095            resourceFile = codeFile;
17096            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17097
17098            return PackageManager.INSTALL_SUCCEEDED;
17099        }
17100
17101        int doPreInstall(int status) {
17102            if (status != PackageManager.INSTALL_SUCCEEDED) {
17103                cleanUp(move.toUuid);
17104            }
17105            return status;
17106        }
17107
17108        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17109            if (status != PackageManager.INSTALL_SUCCEEDED) {
17110                cleanUp(move.toUuid);
17111                return false;
17112            }
17113
17114            // Reflect the move in app info
17115            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17116            pkg.setApplicationInfoCodePath(pkg.codePath);
17117            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17118            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17119            pkg.setApplicationInfoResourcePath(pkg.codePath);
17120            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17121            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17122
17123            return true;
17124        }
17125
17126        int doPostInstall(int status, int uid) {
17127            if (status == PackageManager.INSTALL_SUCCEEDED) {
17128                cleanUp(move.fromUuid);
17129            } else {
17130                cleanUp(move.toUuid);
17131            }
17132            return status;
17133        }
17134
17135        @Override
17136        String getCodePath() {
17137            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17138        }
17139
17140        @Override
17141        String getResourcePath() {
17142            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17143        }
17144
17145        private boolean cleanUp(String volumeUuid) {
17146            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17147                    move.dataAppName);
17148            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17149            final int[] userIds = sUserManager.getUserIds();
17150            synchronized (mInstallLock) {
17151                // Clean up both app data and code
17152                // All package moves are frozen until finished
17153                for (int userId : userIds) {
17154                    try {
17155                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17156                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17157                    } catch (InstallerException e) {
17158                        Slog.w(TAG, String.valueOf(e));
17159                    }
17160                }
17161                removeCodePathLI(codeFile);
17162            }
17163            return true;
17164        }
17165
17166        void cleanUpResourcesLI() {
17167            throw new UnsupportedOperationException();
17168        }
17169
17170        boolean doPostDeleteLI(boolean delete) {
17171            throw new UnsupportedOperationException();
17172        }
17173    }
17174
17175    static String getAsecPackageName(String packageCid) {
17176        int idx = packageCid.lastIndexOf("-");
17177        if (idx == -1) {
17178            return packageCid;
17179        }
17180        return packageCid.substring(0, idx);
17181    }
17182
17183    // Utility method used to create code paths based on package name and available index.
17184    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17185        String idxStr = "";
17186        int idx = 1;
17187        // Fall back to default value of idx=1 if prefix is not
17188        // part of oldCodePath
17189        if (oldCodePath != null) {
17190            String subStr = oldCodePath;
17191            // Drop the suffix right away
17192            if (suffix != null && subStr.endsWith(suffix)) {
17193                subStr = subStr.substring(0, subStr.length() - suffix.length());
17194            }
17195            // If oldCodePath already contains prefix find out the
17196            // ending index to either increment or decrement.
17197            int sidx = subStr.lastIndexOf(prefix);
17198            if (sidx != -1) {
17199                subStr = subStr.substring(sidx + prefix.length());
17200                if (subStr != null) {
17201                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17202                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17203                    }
17204                    try {
17205                        idx = Integer.parseInt(subStr);
17206                        if (idx <= 1) {
17207                            idx++;
17208                        } else {
17209                            idx--;
17210                        }
17211                    } catch(NumberFormatException e) {
17212                    }
17213                }
17214            }
17215        }
17216        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17217        return prefix + idxStr;
17218    }
17219
17220    private File getNextCodePath(File targetDir, String packageName) {
17221        File result;
17222        SecureRandom random = new SecureRandom();
17223        byte[] bytes = new byte[16];
17224        do {
17225            random.nextBytes(bytes);
17226            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17227            result = new File(targetDir, packageName + "-" + suffix);
17228        } while (result.exists());
17229        return result;
17230    }
17231
17232    // Utility method that returns the relative package path with respect
17233    // to the installation directory. Like say for /data/data/com.test-1.apk
17234    // string com.test-1 is returned.
17235    static String deriveCodePathName(String codePath) {
17236        if (codePath == null) {
17237            return null;
17238        }
17239        final File codeFile = new File(codePath);
17240        final String name = codeFile.getName();
17241        if (codeFile.isDirectory()) {
17242            return name;
17243        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17244            final int lastDot = name.lastIndexOf('.');
17245            return name.substring(0, lastDot);
17246        } else {
17247            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17248            return null;
17249        }
17250    }
17251
17252    static class PackageInstalledInfo {
17253        String name;
17254        int uid;
17255        // The set of users that originally had this package installed.
17256        int[] origUsers;
17257        // The set of users that now have this package installed.
17258        int[] newUsers;
17259        PackageParser.Package pkg;
17260        int returnCode;
17261        String returnMsg;
17262        PackageRemovedInfo removedInfo;
17263        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17264
17265        public void setError(int code, String msg) {
17266            setReturnCode(code);
17267            setReturnMessage(msg);
17268            Slog.w(TAG, msg);
17269        }
17270
17271        public void setError(String msg, PackageParserException e) {
17272            setReturnCode(e.error);
17273            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17274            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17275            for (int i = 0; i < childCount; i++) {
17276                addedChildPackages.valueAt(i).setError(msg, e);
17277            }
17278            Slog.w(TAG, msg, e);
17279        }
17280
17281        public void setError(String msg, PackageManagerException e) {
17282            returnCode = e.error;
17283            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17284            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17285            for (int i = 0; i < childCount; i++) {
17286                addedChildPackages.valueAt(i).setError(msg, e);
17287            }
17288            Slog.w(TAG, msg, e);
17289        }
17290
17291        public void setReturnCode(int returnCode) {
17292            this.returnCode = returnCode;
17293            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17294            for (int i = 0; i < childCount; i++) {
17295                addedChildPackages.valueAt(i).returnCode = returnCode;
17296            }
17297        }
17298
17299        private void setReturnMessage(String returnMsg) {
17300            this.returnMsg = returnMsg;
17301            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17302            for (int i = 0; i < childCount; i++) {
17303                addedChildPackages.valueAt(i).returnMsg = returnMsg;
17304            }
17305        }
17306
17307        // In some error cases we want to convey more info back to the observer
17308        String origPackage;
17309        String origPermission;
17310    }
17311
17312    /*
17313     * Install a non-existing package.
17314     */
17315    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17316            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17317            PackageInstalledInfo res, int installReason) {
17318        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17319
17320        // Remember this for later, in case we need to rollback this install
17321        String pkgName = pkg.packageName;
17322
17323        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17324
17325        synchronized(mPackages) {
17326            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17327            if (renamedPackage != null) {
17328                // A package with the same name is already installed, though
17329                // it has been renamed to an older name.  The package we
17330                // are trying to install should be installed as an update to
17331                // the existing one, but that has not been requested, so bail.
17332                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17333                        + " without first uninstalling package running as "
17334                        + renamedPackage);
17335                return;
17336            }
17337            if (mPackages.containsKey(pkgName)) {
17338                // Don't allow installation over an existing package with the same name.
17339                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17340                        + " without first uninstalling.");
17341                return;
17342            }
17343        }
17344
17345        try {
17346            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17347                    System.currentTimeMillis(), user);
17348
17349            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17350
17351            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17352                prepareAppDataAfterInstallLIF(newPackage);
17353
17354            } else {
17355                // Remove package from internal structures, but keep around any
17356                // data that might have already existed
17357                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17358                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17359            }
17360        } catch (PackageManagerException e) {
17361            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17362        }
17363
17364        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17365    }
17366
17367    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17368        // Can't rotate keys during boot or if sharedUser.
17369        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17370                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17371            return false;
17372        }
17373        // app is using upgradeKeySets; make sure all are valid
17374        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17375        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17376        for (int i = 0; i < upgradeKeySets.length; i++) {
17377            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17378                Slog.wtf(TAG, "Package "
17379                         + (oldPs.name != null ? oldPs.name : "<null>")
17380                         + " contains upgrade-key-set reference to unknown key-set: "
17381                         + upgradeKeySets[i]
17382                         + " reverting to signatures check.");
17383                return false;
17384            }
17385        }
17386        return true;
17387    }
17388
17389    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17390        // Upgrade keysets are being used.  Determine if new package has a superset of the
17391        // required keys.
17392        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17393        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17394        for (int i = 0; i < upgradeKeySets.length; i++) {
17395            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17396            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17397                return true;
17398            }
17399        }
17400        return false;
17401    }
17402
17403    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17404        try (DigestInputStream digestStream =
17405                new DigestInputStream(new FileInputStream(file), digest)) {
17406            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17407        }
17408    }
17409
17410    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17411            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17412            int installReason) {
17413        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17414
17415        final PackageParser.Package oldPackage;
17416        final PackageSetting ps;
17417        final String pkgName = pkg.packageName;
17418        final int[] allUsers;
17419        final int[] installedUsers;
17420
17421        synchronized(mPackages) {
17422            oldPackage = mPackages.get(pkgName);
17423            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17424
17425            // don't allow upgrade to target a release SDK from a pre-release SDK
17426            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17427                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17428            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17429                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17430            if (oldTargetsPreRelease
17431                    && !newTargetsPreRelease
17432                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17433                Slog.w(TAG, "Can't install package targeting released sdk");
17434                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17435                return;
17436            }
17437
17438            ps = mSettings.mPackages.get(pkgName);
17439
17440            // verify signatures are valid
17441            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17442                if (!checkUpgradeKeySetLP(ps, pkg)) {
17443                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17444                            "New package not signed by keys specified by upgrade-keysets: "
17445                                    + pkgName);
17446                    return;
17447                }
17448            } else {
17449                // default to original signature matching
17450                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17451                        != PackageManager.SIGNATURE_MATCH) {
17452                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17453                            "New package has a different signature: " + pkgName);
17454                    return;
17455                }
17456            }
17457
17458            // don't allow a system upgrade unless the upgrade hash matches
17459            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17460                byte[] digestBytes = null;
17461                try {
17462                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17463                    updateDigest(digest, new File(pkg.baseCodePath));
17464                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17465                        for (String path : pkg.splitCodePaths) {
17466                            updateDigest(digest, new File(path));
17467                        }
17468                    }
17469                    digestBytes = digest.digest();
17470                } catch (NoSuchAlgorithmException | IOException e) {
17471                    res.setError(INSTALL_FAILED_INVALID_APK,
17472                            "Could not compute hash: " + pkgName);
17473                    return;
17474                }
17475                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17476                    res.setError(INSTALL_FAILED_INVALID_APK,
17477                            "New package fails restrict-update check: " + pkgName);
17478                    return;
17479                }
17480                // retain upgrade restriction
17481                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17482            }
17483
17484            // Check for shared user id changes
17485            String invalidPackageName =
17486                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17487            if (invalidPackageName != null) {
17488                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17489                        "Package " + invalidPackageName + " tried to change user "
17490                                + oldPackage.mSharedUserId);
17491                return;
17492            }
17493
17494            // In case of rollback, remember per-user/profile install state
17495            allUsers = sUserManager.getUserIds();
17496            installedUsers = ps.queryInstalledUsers(allUsers, true);
17497
17498            // don't allow an upgrade from full to ephemeral
17499            if (isInstantApp) {
17500                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17501                    for (int currentUser : allUsers) {
17502                        if (!ps.getInstantApp(currentUser)) {
17503                            // can't downgrade from full to instant
17504                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17505                                    + " for user: " + currentUser);
17506                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17507                            return;
17508                        }
17509                    }
17510                } else if (!ps.getInstantApp(user.getIdentifier())) {
17511                    // can't downgrade from full to instant
17512                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17513                            + " for user: " + user.getIdentifier());
17514                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17515                    return;
17516                }
17517            }
17518        }
17519
17520        // Update what is removed
17521        res.removedInfo = new PackageRemovedInfo(this);
17522        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17523        res.removedInfo.removedPackage = oldPackage.packageName;
17524        res.removedInfo.installerPackageName = ps.installerPackageName;
17525        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17526        res.removedInfo.isUpdate = true;
17527        res.removedInfo.origUsers = installedUsers;
17528        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17529        for (int i = 0; i < installedUsers.length; i++) {
17530            final int userId = installedUsers[i];
17531            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17532        }
17533
17534        final int childCount = (oldPackage.childPackages != null)
17535                ? oldPackage.childPackages.size() : 0;
17536        for (int i = 0; i < childCount; i++) {
17537            boolean childPackageUpdated = false;
17538            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17539            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17540            if (res.addedChildPackages != null) {
17541                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17542                if (childRes != null) {
17543                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17544                    childRes.removedInfo.removedPackage = childPkg.packageName;
17545                    if (childPs != null) {
17546                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17547                    }
17548                    childRes.removedInfo.isUpdate = true;
17549                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17550                    childPackageUpdated = true;
17551                }
17552            }
17553            if (!childPackageUpdated) {
17554                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17555                childRemovedRes.removedPackage = childPkg.packageName;
17556                if (childPs != null) {
17557                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17558                }
17559                childRemovedRes.isUpdate = false;
17560                childRemovedRes.dataRemoved = true;
17561                synchronized (mPackages) {
17562                    if (childPs != null) {
17563                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17564                    }
17565                }
17566                if (res.removedInfo.removedChildPackages == null) {
17567                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17568                }
17569                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17570            }
17571        }
17572
17573        boolean sysPkg = (isSystemApp(oldPackage));
17574        if (sysPkg) {
17575            // Set the system/privileged flags as needed
17576            final boolean privileged =
17577                    (oldPackage.applicationInfo.privateFlags
17578                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17579            final int systemPolicyFlags = policyFlags
17580                    | PackageParser.PARSE_IS_SYSTEM
17581                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17582
17583            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17584                    user, allUsers, installerPackageName, res, installReason);
17585        } else {
17586            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17587                    user, allUsers, installerPackageName, res, installReason);
17588        }
17589    }
17590
17591    @Override
17592    public List<String> getPreviousCodePaths(String packageName) {
17593        final int callingUid = Binder.getCallingUid();
17594        final List<String> result = new ArrayList<>();
17595        if (getInstantAppPackageName(callingUid) != null) {
17596            return result;
17597        }
17598        final PackageSetting ps = mSettings.mPackages.get(packageName);
17599        if (ps != null
17600                && ps.oldCodePaths != null
17601                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17602            result.addAll(ps.oldCodePaths);
17603        }
17604        return result;
17605    }
17606
17607    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17608            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17609            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17610            int installReason) {
17611        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17612                + deletedPackage);
17613
17614        String pkgName = deletedPackage.packageName;
17615        boolean deletedPkg = true;
17616        boolean addedPkg = false;
17617        boolean updatedSettings = false;
17618        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17619        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17620                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17621
17622        final long origUpdateTime = (pkg.mExtras != null)
17623                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17624
17625        // First delete the existing package while retaining the data directory
17626        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17627                res.removedInfo, true, pkg)) {
17628            // If the existing package wasn't successfully deleted
17629            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17630            deletedPkg = false;
17631        } else {
17632            // Successfully deleted the old package; proceed with replace.
17633
17634            // If deleted package lived in a container, give users a chance to
17635            // relinquish resources before killing.
17636            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17637                if (DEBUG_INSTALL) {
17638                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17639                }
17640                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17641                final ArrayList<String> pkgList = new ArrayList<String>(1);
17642                pkgList.add(deletedPackage.applicationInfo.packageName);
17643                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17644            }
17645
17646            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17647                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17648            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17649
17650            try {
17651                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17652                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17653                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17654                        installReason);
17655
17656                // Update the in-memory copy of the previous code paths.
17657                PackageSetting ps = mSettings.mPackages.get(pkgName);
17658                if (!killApp) {
17659                    if (ps.oldCodePaths == null) {
17660                        ps.oldCodePaths = new ArraySet<>();
17661                    }
17662                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17663                    if (deletedPackage.splitCodePaths != null) {
17664                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17665                    }
17666                } else {
17667                    ps.oldCodePaths = null;
17668                }
17669                if (ps.childPackageNames != null) {
17670                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17671                        final String childPkgName = ps.childPackageNames.get(i);
17672                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17673                        childPs.oldCodePaths = ps.oldCodePaths;
17674                    }
17675                }
17676                // set instant app status, but, only if it's explicitly specified
17677                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17678                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17679                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17680                prepareAppDataAfterInstallLIF(newPackage);
17681                addedPkg = true;
17682                mDexManager.notifyPackageUpdated(newPackage.packageName,
17683                        newPackage.baseCodePath, newPackage.splitCodePaths);
17684            } catch (PackageManagerException e) {
17685                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17686            }
17687        }
17688
17689        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17690            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17691
17692            // Revert all internal state mutations and added folders for the failed install
17693            if (addedPkg) {
17694                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17695                        res.removedInfo, true, null);
17696            }
17697
17698            // Restore the old package
17699            if (deletedPkg) {
17700                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17701                File restoreFile = new File(deletedPackage.codePath);
17702                // Parse old package
17703                boolean oldExternal = isExternal(deletedPackage);
17704                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17705                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17706                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17707                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17708                try {
17709                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17710                            null);
17711                } catch (PackageManagerException e) {
17712                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17713                            + e.getMessage());
17714                    return;
17715                }
17716
17717                synchronized (mPackages) {
17718                    // Ensure the installer package name up to date
17719                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17720
17721                    // Update permissions for restored package
17722                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17723
17724                    mSettings.writeLPr();
17725                }
17726
17727                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17728            }
17729        } else {
17730            synchronized (mPackages) {
17731                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17732                if (ps != null) {
17733                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17734                    if (res.removedInfo.removedChildPackages != null) {
17735                        final int childCount = res.removedInfo.removedChildPackages.size();
17736                        // Iterate in reverse as we may modify the collection
17737                        for (int i = childCount - 1; i >= 0; i--) {
17738                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17739                            if (res.addedChildPackages.containsKey(childPackageName)) {
17740                                res.removedInfo.removedChildPackages.removeAt(i);
17741                            } else {
17742                                PackageRemovedInfo childInfo = res.removedInfo
17743                                        .removedChildPackages.valueAt(i);
17744                                childInfo.removedForAllUsers = mPackages.get(
17745                                        childInfo.removedPackage) == null;
17746                            }
17747                        }
17748                    }
17749                }
17750            }
17751        }
17752    }
17753
17754    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17755            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17756            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17757            int installReason) {
17758        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17759                + ", old=" + deletedPackage);
17760
17761        final boolean disabledSystem;
17762
17763        // Remove existing system package
17764        removePackageLI(deletedPackage, true);
17765
17766        synchronized (mPackages) {
17767            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17768        }
17769        if (!disabledSystem) {
17770            // We didn't need to disable the .apk as a current system package,
17771            // which means we are replacing another update that is already
17772            // installed.  We need to make sure to delete the older one's .apk.
17773            res.removedInfo.args = createInstallArgsForExisting(0,
17774                    deletedPackage.applicationInfo.getCodePath(),
17775                    deletedPackage.applicationInfo.getResourcePath(),
17776                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17777        } else {
17778            res.removedInfo.args = null;
17779        }
17780
17781        // Successfully disabled the old package. Now proceed with re-installation
17782        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17783                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17784        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17785
17786        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17787        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17788                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17789
17790        PackageParser.Package newPackage = null;
17791        try {
17792            // Add the package to the internal data structures
17793            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17794
17795            // Set the update and install times
17796            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17797            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17798                    System.currentTimeMillis());
17799
17800            // Update the package dynamic state if succeeded
17801            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17802                // Now that the install succeeded make sure we remove data
17803                // directories for any child package the update removed.
17804                final int deletedChildCount = (deletedPackage.childPackages != null)
17805                        ? deletedPackage.childPackages.size() : 0;
17806                final int newChildCount = (newPackage.childPackages != null)
17807                        ? newPackage.childPackages.size() : 0;
17808                for (int i = 0; i < deletedChildCount; i++) {
17809                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
17810                    boolean childPackageDeleted = true;
17811                    for (int j = 0; j < newChildCount; j++) {
17812                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
17813                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
17814                            childPackageDeleted = false;
17815                            break;
17816                        }
17817                    }
17818                    if (childPackageDeleted) {
17819                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
17820                                deletedChildPkg.packageName);
17821                        if (ps != null && res.removedInfo.removedChildPackages != null) {
17822                            PackageRemovedInfo removedChildRes = res.removedInfo
17823                                    .removedChildPackages.get(deletedChildPkg.packageName);
17824                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
17825                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
17826                        }
17827                    }
17828                }
17829
17830                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17831                        installReason);
17832                prepareAppDataAfterInstallLIF(newPackage);
17833
17834                mDexManager.notifyPackageUpdated(newPackage.packageName,
17835                            newPackage.baseCodePath, newPackage.splitCodePaths);
17836            }
17837        } catch (PackageManagerException e) {
17838            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
17839            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17840        }
17841
17842        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17843            // Re installation failed. Restore old information
17844            // Remove new pkg information
17845            if (newPackage != null) {
17846                removeInstalledPackageLI(newPackage, true);
17847            }
17848            // Add back the old system package
17849            try {
17850                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
17851            } catch (PackageManagerException e) {
17852                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
17853            }
17854
17855            synchronized (mPackages) {
17856                if (disabledSystem) {
17857                    enableSystemPackageLPw(deletedPackage);
17858                }
17859
17860                // Ensure the installer package name up to date
17861                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17862
17863                // Update permissions for restored package
17864                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17865
17866                mSettings.writeLPr();
17867            }
17868
17869            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
17870                    + " after failed upgrade");
17871        }
17872    }
17873
17874    /**
17875     * Checks whether the parent or any of the child packages have a change shared
17876     * user. For a package to be a valid update the shred users of the parent and
17877     * the children should match. We may later support changing child shared users.
17878     * @param oldPkg The updated package.
17879     * @param newPkg The update package.
17880     * @return The shared user that change between the versions.
17881     */
17882    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
17883            PackageParser.Package newPkg) {
17884        // Check parent shared user
17885        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
17886            return newPkg.packageName;
17887        }
17888        // Check child shared users
17889        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17890        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17891        for (int i = 0; i < newChildCount; i++) {
17892            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17893            // If this child was present, did it have the same shared user?
17894            for (int j = 0; j < oldChildCount; j++) {
17895                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17896                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17897                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17898                    return newChildPkg.packageName;
17899                }
17900            }
17901        }
17902        return null;
17903    }
17904
17905    private void removeNativeBinariesLI(PackageSetting ps) {
17906        // Remove the lib path for the parent package
17907        if (ps != null) {
17908            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17909            // Remove the lib path for the child packages
17910            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17911            for (int i = 0; i < childCount; i++) {
17912                PackageSetting childPs = null;
17913                synchronized (mPackages) {
17914                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17915                }
17916                if (childPs != null) {
17917                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17918                            .legacyNativeLibraryPathString);
17919                }
17920            }
17921        }
17922    }
17923
17924    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17925        // Enable the parent package
17926        mSettings.enableSystemPackageLPw(pkg.packageName);
17927        // Enable the child packages
17928        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17929        for (int i = 0; i < childCount; i++) {
17930            PackageParser.Package childPkg = pkg.childPackages.get(i);
17931            mSettings.enableSystemPackageLPw(childPkg.packageName);
17932        }
17933    }
17934
17935    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17936            PackageParser.Package newPkg) {
17937        // Disable the parent package (parent always replaced)
17938        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17939        // Disable the child packages
17940        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17941        for (int i = 0; i < childCount; i++) {
17942            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17943            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17944            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17945        }
17946        return disabled;
17947    }
17948
17949    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17950            String installerPackageName) {
17951        // Enable the parent package
17952        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17953        // Enable the child packages
17954        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17955        for (int i = 0; i < childCount; i++) {
17956            PackageParser.Package childPkg = pkg.childPackages.get(i);
17957            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17958        }
17959    }
17960
17961    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17962        // Collect all used permissions in the UID
17963        ArraySet<String> usedPermissions = new ArraySet<>();
17964        final int packageCount = su.packages.size();
17965        for (int i = 0; i < packageCount; i++) {
17966            PackageSetting ps = su.packages.valueAt(i);
17967            if (ps.pkg == null) {
17968                continue;
17969            }
17970            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17971            for (int j = 0; j < requestedPermCount; j++) {
17972                String permission = ps.pkg.requestedPermissions.get(j);
17973                BasePermission bp = mSettings.mPermissions.get(permission);
17974                if (bp != null) {
17975                    usedPermissions.add(permission);
17976                }
17977            }
17978        }
17979
17980        PermissionsState permissionsState = su.getPermissionsState();
17981        // Prune install permissions
17982        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17983        final int installPermCount = installPermStates.size();
17984        for (int i = installPermCount - 1; i >= 0;  i--) {
17985            PermissionState permissionState = installPermStates.get(i);
17986            if (!usedPermissions.contains(permissionState.getName())) {
17987                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17988                if (bp != null) {
17989                    permissionsState.revokeInstallPermission(bp);
17990                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17991                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17992                }
17993            }
17994        }
17995
17996        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17997
17998        // Prune runtime permissions
17999        for (int userId : allUserIds) {
18000            List<PermissionState> runtimePermStates = permissionsState
18001                    .getRuntimePermissionStates(userId);
18002            final int runtimePermCount = runtimePermStates.size();
18003            for (int i = runtimePermCount - 1; i >= 0; i--) {
18004                PermissionState permissionState = runtimePermStates.get(i);
18005                if (!usedPermissions.contains(permissionState.getName())) {
18006                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18007                    if (bp != null) {
18008                        permissionsState.revokeRuntimePermission(bp, userId);
18009                        permissionsState.updatePermissionFlags(bp, userId,
18010                                PackageManager.MASK_PERMISSION_FLAGS, 0);
18011                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
18012                                runtimePermissionChangedUserIds, userId);
18013                    }
18014                }
18015            }
18016        }
18017
18018        return runtimePermissionChangedUserIds;
18019    }
18020
18021    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18022            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18023        // Update the parent package setting
18024        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18025                res, user, installReason);
18026        // Update the child packages setting
18027        final int childCount = (newPackage.childPackages != null)
18028                ? newPackage.childPackages.size() : 0;
18029        for (int i = 0; i < childCount; i++) {
18030            PackageParser.Package childPackage = newPackage.childPackages.get(i);
18031            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18032            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18033                    childRes.origUsers, childRes, user, installReason);
18034        }
18035    }
18036
18037    private void updateSettingsInternalLI(PackageParser.Package newPackage,
18038            String installerPackageName, int[] allUsers, int[] installedForUsers,
18039            PackageInstalledInfo res, UserHandle user, int installReason) {
18040        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18041
18042        String pkgName = newPackage.packageName;
18043        synchronized (mPackages) {
18044            //write settings. the installStatus will be incomplete at this stage.
18045            //note that the new package setting would have already been
18046            //added to mPackages. It hasn't been persisted yet.
18047            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18048            // TODO: Remove this write? It's also written at the end of this method
18049            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18050            mSettings.writeLPr();
18051            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18052        }
18053
18054        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18055        synchronized (mPackages) {
18056            updatePermissionsLPw(newPackage.packageName, newPackage,
18057                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18058                            ? UPDATE_PERMISSIONS_ALL : 0));
18059            // For system-bundled packages, we assume that installing an upgraded version
18060            // of the package implies that the user actually wants to run that new code,
18061            // so we enable the package.
18062            PackageSetting ps = mSettings.mPackages.get(pkgName);
18063            final int userId = user.getIdentifier();
18064            if (ps != null) {
18065                if (isSystemApp(newPackage)) {
18066                    if (DEBUG_INSTALL) {
18067                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18068                    }
18069                    // Enable system package for requested users
18070                    if (res.origUsers != null) {
18071                        for (int origUserId : res.origUsers) {
18072                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
18073                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18074                                        origUserId, installerPackageName);
18075                            }
18076                        }
18077                    }
18078                    // Also convey the prior install/uninstall state
18079                    if (allUsers != null && installedForUsers != null) {
18080                        for (int currentUserId : allUsers) {
18081                            final boolean installed = ArrayUtils.contains(
18082                                    installedForUsers, currentUserId);
18083                            if (DEBUG_INSTALL) {
18084                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
18085                            }
18086                            ps.setInstalled(installed, currentUserId);
18087                        }
18088                        // these install state changes will be persisted in the
18089                        // upcoming call to mSettings.writeLPr().
18090                    }
18091                }
18092                // It's implied that when a user requests installation, they want the app to be
18093                // installed and enabled.
18094                if (userId != UserHandle.USER_ALL) {
18095                    ps.setInstalled(true, userId);
18096                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18097                }
18098
18099                // When replacing an existing package, preserve the original install reason for all
18100                // users that had the package installed before.
18101                final Set<Integer> previousUserIds = new ArraySet<>();
18102                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18103                    final int installReasonCount = res.removedInfo.installReasons.size();
18104                    for (int i = 0; i < installReasonCount; i++) {
18105                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18106                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18107                        ps.setInstallReason(previousInstallReason, previousUserId);
18108                        previousUserIds.add(previousUserId);
18109                    }
18110                }
18111
18112                // Set install reason for users that are having the package newly installed.
18113                if (userId == UserHandle.USER_ALL) {
18114                    for (int currentUserId : sUserManager.getUserIds()) {
18115                        if (!previousUserIds.contains(currentUserId)) {
18116                            ps.setInstallReason(installReason, currentUserId);
18117                        }
18118                    }
18119                } else if (!previousUserIds.contains(userId)) {
18120                    ps.setInstallReason(installReason, userId);
18121                }
18122                mSettings.writeKernelMappingLPr(ps);
18123            }
18124            res.name = pkgName;
18125            res.uid = newPackage.applicationInfo.uid;
18126            res.pkg = newPackage;
18127            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18128            mSettings.setInstallerPackageName(pkgName, installerPackageName);
18129            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18130            //to update install status
18131            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18132            mSettings.writeLPr();
18133            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18134        }
18135
18136        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18137    }
18138
18139    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18140        try {
18141            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18142            installPackageLI(args, res);
18143        } finally {
18144            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18145        }
18146    }
18147
18148    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18149        final int installFlags = args.installFlags;
18150        final String installerPackageName = args.installerPackageName;
18151        final String volumeUuid = args.volumeUuid;
18152        final File tmpPackageFile = new File(args.getCodePath());
18153        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18154        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18155                || (args.volumeUuid != null));
18156        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18157        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18158        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18159        boolean replace = false;
18160        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18161        if (args.move != null) {
18162            // moving a complete application; perform an initial scan on the new install location
18163            scanFlags |= SCAN_INITIAL;
18164        }
18165        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18166            scanFlags |= SCAN_DONT_KILL_APP;
18167        }
18168        if (instantApp) {
18169            scanFlags |= SCAN_AS_INSTANT_APP;
18170        }
18171        if (fullApp) {
18172            scanFlags |= SCAN_AS_FULL_APP;
18173        }
18174
18175        // Result object to be returned
18176        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18177
18178        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18179
18180        // Sanity check
18181        if (instantApp && (forwardLocked || onExternal)) {
18182            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18183                    + " external=" + onExternal);
18184            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18185            return;
18186        }
18187
18188        // Retrieve PackageSettings and parse package
18189        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18190                | PackageParser.PARSE_ENFORCE_CODE
18191                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18192                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18193                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18194                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18195        PackageParser pp = new PackageParser();
18196        pp.setSeparateProcesses(mSeparateProcesses);
18197        pp.setDisplayMetrics(mMetrics);
18198        pp.setCallback(mPackageParserCallback);
18199
18200        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18201        final PackageParser.Package pkg;
18202        try {
18203            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18204        } catch (PackageParserException e) {
18205            res.setError("Failed parse during installPackageLI", e);
18206            return;
18207        } finally {
18208            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18209        }
18210
18211        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18212        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18213            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18214            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18215                    "Instant app package must target O");
18216            return;
18217        }
18218        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18219            Slog.w(TAG, "Instant app package " + pkg.packageName
18220                    + " does not target targetSandboxVersion 2");
18221            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18222                    "Instant app package must use targetSanboxVersion 2");
18223            return;
18224        }
18225
18226        if (pkg.applicationInfo.isStaticSharedLibrary()) {
18227            // Static shared libraries have synthetic package names
18228            renameStaticSharedLibraryPackage(pkg);
18229
18230            // No static shared libs on external storage
18231            if (onExternal) {
18232                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18233                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18234                        "Packages declaring static-shared libs cannot be updated");
18235                return;
18236            }
18237        }
18238
18239        // If we are installing a clustered package add results for the children
18240        if (pkg.childPackages != null) {
18241            synchronized (mPackages) {
18242                final int childCount = pkg.childPackages.size();
18243                for (int i = 0; i < childCount; i++) {
18244                    PackageParser.Package childPkg = pkg.childPackages.get(i);
18245                    PackageInstalledInfo childRes = new PackageInstalledInfo();
18246                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18247                    childRes.pkg = childPkg;
18248                    childRes.name = childPkg.packageName;
18249                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18250                    if (childPs != null) {
18251                        childRes.origUsers = childPs.queryInstalledUsers(
18252                                sUserManager.getUserIds(), true);
18253                    }
18254                    if ((mPackages.containsKey(childPkg.packageName))) {
18255                        childRes.removedInfo = new PackageRemovedInfo(this);
18256                        childRes.removedInfo.removedPackage = childPkg.packageName;
18257                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18258                    }
18259                    if (res.addedChildPackages == null) {
18260                        res.addedChildPackages = new ArrayMap<>();
18261                    }
18262                    res.addedChildPackages.put(childPkg.packageName, childRes);
18263                }
18264            }
18265        }
18266
18267        // If package doesn't declare API override, mark that we have an install
18268        // time CPU ABI override.
18269        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18270            pkg.cpuAbiOverride = args.abiOverride;
18271        }
18272
18273        String pkgName = res.name = pkg.packageName;
18274        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18275            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18276                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18277                return;
18278            }
18279        }
18280
18281        try {
18282            // either use what we've been given or parse directly from the APK
18283            if (args.certificates != null) {
18284                try {
18285                    PackageParser.populateCertificates(pkg, args.certificates);
18286                } catch (PackageParserException e) {
18287                    // there was something wrong with the certificates we were given;
18288                    // try to pull them from the APK
18289                    PackageParser.collectCertificates(pkg, parseFlags);
18290                }
18291            } else {
18292                PackageParser.collectCertificates(pkg, parseFlags);
18293            }
18294        } catch (PackageParserException e) {
18295            res.setError("Failed collect during installPackageLI", e);
18296            return;
18297        }
18298
18299        // Get rid of all references to package scan path via parser.
18300        pp = null;
18301        String oldCodePath = null;
18302        boolean systemApp = false;
18303        synchronized (mPackages) {
18304            // Check if installing already existing package
18305            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18306                String oldName = mSettings.getRenamedPackageLPr(pkgName);
18307                if (pkg.mOriginalPackages != null
18308                        && pkg.mOriginalPackages.contains(oldName)
18309                        && mPackages.containsKey(oldName)) {
18310                    // This package is derived from an original package,
18311                    // and this device has been updating from that original
18312                    // name.  We must continue using the original name, so
18313                    // rename the new package here.
18314                    pkg.setPackageName(oldName);
18315                    pkgName = pkg.packageName;
18316                    replace = true;
18317                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18318                            + oldName + " pkgName=" + pkgName);
18319                } else if (mPackages.containsKey(pkgName)) {
18320                    // This package, under its official name, already exists
18321                    // on the device; we should replace it.
18322                    replace = true;
18323                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18324                }
18325
18326                // Child packages are installed through the parent package
18327                if (pkg.parentPackage != null) {
18328                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18329                            "Package " + pkg.packageName + " is child of package "
18330                                    + pkg.parentPackage.parentPackage + ". Child packages "
18331                                    + "can be updated only through the parent package.");
18332                    return;
18333                }
18334
18335                if (replace) {
18336                    // Prevent apps opting out from runtime permissions
18337                    PackageParser.Package oldPackage = mPackages.get(pkgName);
18338                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18339                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18340                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18341                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18342                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18343                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18344                                        + " doesn't support runtime permissions but the old"
18345                                        + " target SDK " + oldTargetSdk + " does.");
18346                        return;
18347                    }
18348                    // Prevent apps from downgrading their targetSandbox.
18349                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18350                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18351                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18352                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18353                                "Package " + pkg.packageName + " new target sandbox "
18354                                + newTargetSandbox + " is incompatible with the previous value of"
18355                                + oldTargetSandbox + ".");
18356                        return;
18357                    }
18358
18359                    // Prevent installing of child packages
18360                    if (oldPackage.parentPackage != null) {
18361                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18362                                "Package " + pkg.packageName + " is child of package "
18363                                        + oldPackage.parentPackage + ". Child packages "
18364                                        + "can be updated only through the parent package.");
18365                        return;
18366                    }
18367                }
18368            }
18369
18370            PackageSetting ps = mSettings.mPackages.get(pkgName);
18371            if (ps != null) {
18372                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18373
18374                // Static shared libs have same package with different versions where
18375                // we internally use a synthetic package name to allow multiple versions
18376                // of the same package, therefore we need to compare signatures against
18377                // the package setting for the latest library version.
18378                PackageSetting signatureCheckPs = ps;
18379                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18380                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18381                    if (libraryEntry != null) {
18382                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18383                    }
18384                }
18385
18386                // Quick sanity check that we're signed correctly if updating;
18387                // we'll check this again later when scanning, but we want to
18388                // bail early here before tripping over redefined permissions.
18389                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18390                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18391                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18392                                + pkg.packageName + " upgrade keys do not match the "
18393                                + "previously installed version");
18394                        return;
18395                    }
18396                } else {
18397                    try {
18398                        verifySignaturesLP(signatureCheckPs, pkg);
18399                    } catch (PackageManagerException e) {
18400                        res.setError(e.error, e.getMessage());
18401                        return;
18402                    }
18403                }
18404
18405                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18406                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18407                    systemApp = (ps.pkg.applicationInfo.flags &
18408                            ApplicationInfo.FLAG_SYSTEM) != 0;
18409                }
18410                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18411            }
18412
18413            int N = pkg.permissions.size();
18414            for (int i = N-1; i >= 0; i--) {
18415                PackageParser.Permission perm = pkg.permissions.get(i);
18416                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18417
18418                // Don't allow anyone but the system to define ephemeral permissions.
18419                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
18420                        && !systemApp) {
18421                    Slog.w(TAG, "Non-System package " + pkg.packageName
18422                            + " attempting to delcare ephemeral permission "
18423                            + perm.info.name + "; Removing ephemeral.");
18424                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
18425                }
18426                // Check whether the newly-scanned package wants to define an already-defined perm
18427                if (bp != null) {
18428                    // If the defining package is signed with our cert, it's okay.  This
18429                    // also includes the "updating the same package" case, of course.
18430                    // "updating same package" could also involve key-rotation.
18431                    final boolean sigsOk;
18432                    if (bp.sourcePackage.equals(pkg.packageName)
18433                            && (bp.packageSetting instanceof PackageSetting)
18434                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18435                                    scanFlags))) {
18436                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18437                    } else {
18438                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18439                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18440                    }
18441                    if (!sigsOk) {
18442                        // If the owning package is the system itself, we log but allow
18443                        // install to proceed; we fail the install on all other permission
18444                        // redefinitions.
18445                        if (!bp.sourcePackage.equals("android")) {
18446                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18447                                    + pkg.packageName + " attempting to redeclare permission "
18448                                    + perm.info.name + " already owned by " + bp.sourcePackage);
18449                            res.origPermission = perm.info.name;
18450                            res.origPackage = bp.sourcePackage;
18451                            return;
18452                        } else {
18453                            Slog.w(TAG, "Package " + pkg.packageName
18454                                    + " attempting to redeclare system permission "
18455                                    + perm.info.name + "; ignoring new declaration");
18456                            pkg.permissions.remove(i);
18457                        }
18458                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18459                        // Prevent apps to change protection level to dangerous from any other
18460                        // type as this would allow a privilege escalation where an app adds a
18461                        // normal/signature permission in other app's group and later redefines
18462                        // it as dangerous leading to the group auto-grant.
18463                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18464                                == PermissionInfo.PROTECTION_DANGEROUS) {
18465                            if (bp != null && !bp.isRuntime()) {
18466                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18467                                        + "non-runtime permission " + perm.info.name
18468                                        + " to runtime; keeping old protection level");
18469                                perm.info.protectionLevel = bp.protectionLevel;
18470                            }
18471                        }
18472                    }
18473                }
18474            }
18475        }
18476
18477        if (systemApp) {
18478            if (onExternal) {
18479                // Abort update; system app can't be replaced with app on sdcard
18480                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18481                        "Cannot install updates to system apps on sdcard");
18482                return;
18483            } else if (instantApp) {
18484                // Abort update; system app can't be replaced with an instant app
18485                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18486                        "Cannot update a system app with an instant app");
18487                return;
18488            }
18489        }
18490
18491        if (args.move != null) {
18492            // We did an in-place move, so dex is ready to roll
18493            scanFlags |= SCAN_NO_DEX;
18494            scanFlags |= SCAN_MOVE;
18495
18496            synchronized (mPackages) {
18497                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18498                if (ps == null) {
18499                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18500                            "Missing settings for moved package " + pkgName);
18501                }
18502
18503                // We moved the entire application as-is, so bring over the
18504                // previously derived ABI information.
18505                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18506                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18507            }
18508
18509        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18510            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18511            scanFlags |= SCAN_NO_DEX;
18512
18513            try {
18514                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18515                    args.abiOverride : pkg.cpuAbiOverride);
18516                final boolean extractNativeLibs = !pkg.isLibrary();
18517                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18518                        extractNativeLibs, mAppLib32InstallDir);
18519            } catch (PackageManagerException pme) {
18520                Slog.e(TAG, "Error deriving application ABI", pme);
18521                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18522                return;
18523            }
18524
18525            // Shared libraries for the package need to be updated.
18526            synchronized (mPackages) {
18527                try {
18528                    updateSharedLibrariesLPr(pkg, null);
18529                } catch (PackageManagerException e) {
18530                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18531                }
18532            }
18533
18534            // dexopt can take some time to complete, so, for instant apps, we skip this
18535            // step during installation. Instead, we'll take extra time the first time the
18536            // instant app starts. It's preferred to do it this way to provide continuous
18537            // progress to the user instead of mysteriously blocking somewhere in the
18538            // middle of running an instant app. The default behaviour can be overridden
18539            // via gservices.
18540            if (!instantApp || Global.getInt(
18541                        mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) {
18542                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18543                // Do not run PackageDexOptimizer through the local performDexOpt
18544                // method because `pkg` may not be in `mPackages` yet.
18545                //
18546                // Also, don't fail application installs if the dexopt step fails.
18547                DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18548                        REASON_INSTALL,
18549                        DexoptOptions.DEXOPT_BOOT_COMPLETE);
18550                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18551                        null /* instructionSets */,
18552                        getOrCreateCompilerPackageStats(pkg),
18553                        mDexManager.isUsedByOtherApps(pkg.packageName),
18554                        dexoptOptions);
18555                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18556            }
18557
18558            // Notify BackgroundDexOptService that the package has been changed.
18559            // If this is an update of a package which used to fail to compile,
18560            // BDOS will remove it from its blacklist.
18561            // TODO: Layering violation
18562            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18563        }
18564
18565        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18566            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18567            return;
18568        }
18569
18570        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18571
18572        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18573                "installPackageLI")) {
18574            if (replace) {
18575                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18576                    // Static libs have a synthetic package name containing the version
18577                    // and cannot be updated as an update would get a new package name,
18578                    // unless this is the exact same version code which is useful for
18579                    // development.
18580                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18581                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18582                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18583                                + "static-shared libs cannot be updated");
18584                        return;
18585                    }
18586                }
18587                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18588                        installerPackageName, res, args.installReason);
18589            } else {
18590                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18591                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18592            }
18593        }
18594
18595        synchronized (mPackages) {
18596            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18597            if (ps != null) {
18598                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18599                ps.setUpdateAvailable(false /*updateAvailable*/);
18600            }
18601
18602            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18603            for (int i = 0; i < childCount; i++) {
18604                PackageParser.Package childPkg = pkg.childPackages.get(i);
18605                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18606                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18607                if (childPs != null) {
18608                    childRes.newUsers = childPs.queryInstalledUsers(
18609                            sUserManager.getUserIds(), true);
18610                }
18611            }
18612
18613            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18614                updateSequenceNumberLP(ps, res.newUsers);
18615                updateInstantAppInstallerLocked(pkgName);
18616            }
18617        }
18618    }
18619
18620    private void startIntentFilterVerifications(int userId, boolean replacing,
18621            PackageParser.Package pkg) {
18622        if (mIntentFilterVerifierComponent == null) {
18623            Slog.w(TAG, "No IntentFilter verification will not be done as "
18624                    + "there is no IntentFilterVerifier available!");
18625            return;
18626        }
18627
18628        final int verifierUid = getPackageUid(
18629                mIntentFilterVerifierComponent.getPackageName(),
18630                MATCH_DEBUG_TRIAGED_MISSING,
18631                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18632
18633        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18634        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18635        mHandler.sendMessage(msg);
18636
18637        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18638        for (int i = 0; i < childCount; i++) {
18639            PackageParser.Package childPkg = pkg.childPackages.get(i);
18640            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18641            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18642            mHandler.sendMessage(msg);
18643        }
18644    }
18645
18646    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18647            PackageParser.Package pkg) {
18648        int size = pkg.activities.size();
18649        if (size == 0) {
18650            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18651                    "No activity, so no need to verify any IntentFilter!");
18652            return;
18653        }
18654
18655        final boolean hasDomainURLs = hasDomainURLs(pkg);
18656        if (!hasDomainURLs) {
18657            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18658                    "No domain URLs, so no need to verify any IntentFilter!");
18659            return;
18660        }
18661
18662        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18663                + " if any IntentFilter from the " + size
18664                + " Activities needs verification ...");
18665
18666        int count = 0;
18667        final String packageName = pkg.packageName;
18668
18669        synchronized (mPackages) {
18670            // If this is a new install and we see that we've already run verification for this
18671            // package, we have nothing to do: it means the state was restored from backup.
18672            if (!replacing) {
18673                IntentFilterVerificationInfo ivi =
18674                        mSettings.getIntentFilterVerificationLPr(packageName);
18675                if (ivi != null) {
18676                    if (DEBUG_DOMAIN_VERIFICATION) {
18677                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18678                                + ivi.getStatusString());
18679                    }
18680                    return;
18681                }
18682            }
18683
18684            // If any filters need to be verified, then all need to be.
18685            boolean needToVerify = false;
18686            for (PackageParser.Activity a : pkg.activities) {
18687                for (ActivityIntentInfo filter : a.intents) {
18688                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18689                        if (DEBUG_DOMAIN_VERIFICATION) {
18690                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18691                        }
18692                        needToVerify = true;
18693                        break;
18694                    }
18695                }
18696            }
18697
18698            if (needToVerify) {
18699                final int verificationId = mIntentFilterVerificationToken++;
18700                for (PackageParser.Activity a : pkg.activities) {
18701                    for (ActivityIntentInfo filter : a.intents) {
18702                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18703                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18704                                    "Verification needed for IntentFilter:" + filter.toString());
18705                            mIntentFilterVerifier.addOneIntentFilterVerification(
18706                                    verifierUid, userId, verificationId, filter, packageName);
18707                            count++;
18708                        }
18709                    }
18710                }
18711            }
18712        }
18713
18714        if (count > 0) {
18715            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18716                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18717                    +  " for userId:" + userId);
18718            mIntentFilterVerifier.startVerifications(userId);
18719        } else {
18720            if (DEBUG_DOMAIN_VERIFICATION) {
18721                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18722            }
18723        }
18724    }
18725
18726    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18727        final ComponentName cn  = filter.activity.getComponentName();
18728        final String packageName = cn.getPackageName();
18729
18730        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18731                packageName);
18732        if (ivi == null) {
18733            return true;
18734        }
18735        int status = ivi.getStatus();
18736        switch (status) {
18737            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18738            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18739                return true;
18740
18741            default:
18742                // Nothing to do
18743                return false;
18744        }
18745    }
18746
18747    private static boolean isMultiArch(ApplicationInfo info) {
18748        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18749    }
18750
18751    private static boolean isExternal(PackageParser.Package pkg) {
18752        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18753    }
18754
18755    private static boolean isExternal(PackageSetting ps) {
18756        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18757    }
18758
18759    private static boolean isSystemApp(PackageParser.Package pkg) {
18760        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18761    }
18762
18763    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18764        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18765    }
18766
18767    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18768        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18769    }
18770
18771    private static boolean isSystemApp(PackageSetting ps) {
18772        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18773    }
18774
18775    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18776        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18777    }
18778
18779    private int packageFlagsToInstallFlags(PackageSetting ps) {
18780        int installFlags = 0;
18781        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18782            // This existing package was an external ASEC install when we have
18783            // the external flag without a UUID
18784            installFlags |= PackageManager.INSTALL_EXTERNAL;
18785        }
18786        if (ps.isForwardLocked()) {
18787            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
18788        }
18789        return installFlags;
18790    }
18791
18792    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
18793        if (isExternal(pkg)) {
18794            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18795                return StorageManager.UUID_PRIMARY_PHYSICAL;
18796            } else {
18797                return pkg.volumeUuid;
18798            }
18799        } else {
18800            return StorageManager.UUID_PRIVATE_INTERNAL;
18801        }
18802    }
18803
18804    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18805        if (isExternal(pkg)) {
18806            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18807                return mSettings.getExternalVersion();
18808            } else {
18809                return mSettings.findOrCreateVersion(pkg.volumeUuid);
18810            }
18811        } else {
18812            return mSettings.getInternalVersion();
18813        }
18814    }
18815
18816    private void deleteTempPackageFiles() {
18817        final FilenameFilter filter = new FilenameFilter() {
18818            public boolean accept(File dir, String name) {
18819                return name.startsWith("vmdl") && name.endsWith(".tmp");
18820            }
18821        };
18822        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
18823            file.delete();
18824        }
18825    }
18826
18827    @Override
18828    public void deletePackageAsUser(String packageName, int versionCode,
18829            IPackageDeleteObserver observer, int userId, int flags) {
18830        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18831                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18832    }
18833
18834    @Override
18835    public void deletePackageVersioned(VersionedPackage versionedPackage,
18836            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18837        final int callingUid = Binder.getCallingUid();
18838        mContext.enforceCallingOrSelfPermission(
18839                android.Manifest.permission.DELETE_PACKAGES, null);
18840        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
18841        Preconditions.checkNotNull(versionedPackage);
18842        Preconditions.checkNotNull(observer);
18843        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
18844                PackageManager.VERSION_CODE_HIGHEST,
18845                Integer.MAX_VALUE, "versionCode must be >= -1");
18846
18847        final String packageName = versionedPackage.getPackageName();
18848        final int versionCode = versionedPackage.getVersionCode();
18849        final String internalPackageName;
18850        synchronized (mPackages) {
18851            // Normalize package name to handle renamed packages and static libs
18852            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
18853                    versionedPackage.getVersionCode());
18854        }
18855
18856        final int uid = Binder.getCallingUid();
18857        if (!isOrphaned(internalPackageName)
18858                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18859            try {
18860                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18861                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18862                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18863                observer.onUserActionRequired(intent);
18864            } catch (RemoteException re) {
18865            }
18866            return;
18867        }
18868        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18869        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18870        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18871            mContext.enforceCallingOrSelfPermission(
18872                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18873                    "deletePackage for user " + userId);
18874        }
18875
18876        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18877            try {
18878                observer.onPackageDeleted(packageName,
18879                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18880            } catch (RemoteException re) {
18881            }
18882            return;
18883        }
18884
18885        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18886            try {
18887                observer.onPackageDeleted(packageName,
18888                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18889            } catch (RemoteException re) {
18890            }
18891            return;
18892        }
18893
18894        if (DEBUG_REMOVE) {
18895            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18896                    + " deleteAllUsers: " + deleteAllUsers + " version="
18897                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18898                    ? "VERSION_CODE_HIGHEST" : versionCode));
18899        }
18900        // Queue up an async operation since the package deletion may take a little while.
18901        mHandler.post(new Runnable() {
18902            public void run() {
18903                mHandler.removeCallbacks(this);
18904                int returnCode;
18905                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18906                boolean doDeletePackage = true;
18907                if (ps != null) {
18908                    final boolean targetIsInstantApp =
18909                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18910                    doDeletePackage = !targetIsInstantApp
18911                            || canViewInstantApps;
18912                }
18913                if (doDeletePackage) {
18914                    if (!deleteAllUsers) {
18915                        returnCode = deletePackageX(internalPackageName, versionCode,
18916                                userId, deleteFlags);
18917                    } else {
18918                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
18919                                internalPackageName, users);
18920                        // If nobody is blocking uninstall, proceed with delete for all users
18921                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18922                            returnCode = deletePackageX(internalPackageName, versionCode,
18923                                    userId, deleteFlags);
18924                        } else {
18925                            // Otherwise uninstall individually for users with blockUninstalls=false
18926                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18927                            for (int userId : users) {
18928                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18929                                    returnCode = deletePackageX(internalPackageName, versionCode,
18930                                            userId, userFlags);
18931                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18932                                        Slog.w(TAG, "Package delete failed for user " + userId
18933                                                + ", returnCode " + returnCode);
18934                                    }
18935                                }
18936                            }
18937                            // The app has only been marked uninstalled for certain users.
18938                            // We still need to report that delete was blocked
18939                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18940                        }
18941                    }
18942                } else {
18943                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18944                }
18945                try {
18946                    observer.onPackageDeleted(packageName, returnCode, null);
18947                } catch (RemoteException e) {
18948                    Log.i(TAG, "Observer no longer exists.");
18949                } //end catch
18950            } //end run
18951        });
18952    }
18953
18954    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18955        if (pkg.staticSharedLibName != null) {
18956            return pkg.manifestPackageName;
18957        }
18958        return pkg.packageName;
18959    }
18960
18961    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18962        // Handle renamed packages
18963        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18964        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18965
18966        // Is this a static library?
18967        SparseArray<SharedLibraryEntry> versionedLib =
18968                mStaticLibsByDeclaringPackage.get(packageName);
18969        if (versionedLib == null || versionedLib.size() <= 0) {
18970            return packageName;
18971        }
18972
18973        // Figure out which lib versions the caller can see
18974        SparseIntArray versionsCallerCanSee = null;
18975        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18976        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18977                && callingAppId != Process.ROOT_UID) {
18978            versionsCallerCanSee = new SparseIntArray();
18979            String libName = versionedLib.valueAt(0).info.getName();
18980            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18981            if (uidPackages != null) {
18982                for (String uidPackage : uidPackages) {
18983                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18984                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18985                    if (libIdx >= 0) {
18986                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18987                        versionsCallerCanSee.append(libVersion, libVersion);
18988                    }
18989                }
18990            }
18991        }
18992
18993        // Caller can see nothing - done
18994        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18995            return packageName;
18996        }
18997
18998        // Find the version the caller can see and the app version code
18999        SharedLibraryEntry highestVersion = null;
19000        final int versionCount = versionedLib.size();
19001        for (int i = 0; i < versionCount; i++) {
19002            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
19003            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
19004                    libEntry.info.getVersion()) < 0) {
19005                continue;
19006            }
19007            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
19008            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
19009                if (libVersionCode == versionCode) {
19010                    return libEntry.apk;
19011                }
19012            } else if (highestVersion == null) {
19013                highestVersion = libEntry;
19014            } else if (libVersionCode  > highestVersion.info
19015                    .getDeclaringPackage().getVersionCode()) {
19016                highestVersion = libEntry;
19017            }
19018        }
19019
19020        if (highestVersion != null) {
19021            return highestVersion.apk;
19022        }
19023
19024        return packageName;
19025    }
19026
19027    boolean isCallerVerifier(int callingUid) {
19028        final int callingUserId = UserHandle.getUserId(callingUid);
19029        return mRequiredVerifierPackage != null &&
19030                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19031    }
19032
19033    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19034        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19035              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19036            return true;
19037        }
19038        final int callingUserId = UserHandle.getUserId(callingUid);
19039        // If the caller installed the pkgName, then allow it to silently uninstall.
19040        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19041            return true;
19042        }
19043
19044        // Allow package verifier to silently uninstall.
19045        if (mRequiredVerifierPackage != null &&
19046                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19047            return true;
19048        }
19049
19050        // Allow package uninstaller to silently uninstall.
19051        if (mRequiredUninstallerPackage != null &&
19052                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19053            return true;
19054        }
19055
19056        // Allow storage manager to silently uninstall.
19057        if (mStorageManagerPackage != null &&
19058                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19059            return true;
19060        }
19061
19062        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19063        // uninstall for device owner provisioning.
19064        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19065                == PERMISSION_GRANTED) {
19066            return true;
19067        }
19068
19069        return false;
19070    }
19071
19072    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19073        int[] result = EMPTY_INT_ARRAY;
19074        for (int userId : userIds) {
19075            if (getBlockUninstallForUser(packageName, userId)) {
19076                result = ArrayUtils.appendInt(result, userId);
19077            }
19078        }
19079        return result;
19080    }
19081
19082    @Override
19083    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19084        final int callingUid = Binder.getCallingUid();
19085        if (getInstantAppPackageName(callingUid) != null
19086                && !isCallerSameApp(packageName, callingUid)) {
19087            return false;
19088        }
19089        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19090    }
19091
19092    private boolean isPackageDeviceAdmin(String packageName, int userId) {
19093        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19094                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19095        try {
19096            if (dpm != null) {
19097                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19098                        /* callingUserOnly =*/ false);
19099                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19100                        : deviceOwnerComponentName.getPackageName();
19101                // Does the package contains the device owner?
19102                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
19103                // this check is probably not needed, since DO should be registered as a device
19104                // admin on some user too. (Original bug for this: b/17657954)
19105                if (packageName.equals(deviceOwnerPackageName)) {
19106                    return true;
19107                }
19108                // Does it contain a device admin for any user?
19109                int[] users;
19110                if (userId == UserHandle.USER_ALL) {
19111                    users = sUserManager.getUserIds();
19112                } else {
19113                    users = new int[]{userId};
19114                }
19115                for (int i = 0; i < users.length; ++i) {
19116                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19117                        return true;
19118                    }
19119                }
19120            }
19121        } catch (RemoteException e) {
19122        }
19123        return false;
19124    }
19125
19126    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19127        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19128    }
19129
19130    /**
19131     *  This method is an internal method that could be get invoked either
19132     *  to delete an installed package or to clean up a failed installation.
19133     *  After deleting an installed package, a broadcast is sent to notify any
19134     *  listeners that the package has been removed. For cleaning up a failed
19135     *  installation, the broadcast is not necessary since the package's
19136     *  installation wouldn't have sent the initial broadcast either
19137     *  The key steps in deleting a package are
19138     *  deleting the package information in internal structures like mPackages,
19139     *  deleting the packages base directories through installd
19140     *  updating mSettings to reflect current status
19141     *  persisting settings for later use
19142     *  sending a broadcast if necessary
19143     */
19144    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19145        final PackageRemovedInfo info = new PackageRemovedInfo(this);
19146        final boolean res;
19147
19148        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19149                ? UserHandle.USER_ALL : userId;
19150
19151        if (isPackageDeviceAdmin(packageName, removeUser)) {
19152            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19153            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19154        }
19155
19156        PackageSetting uninstalledPs = null;
19157        PackageParser.Package pkg = null;
19158
19159        // for the uninstall-updates case and restricted profiles, remember the per-
19160        // user handle installed state
19161        int[] allUsers;
19162        synchronized (mPackages) {
19163            uninstalledPs = mSettings.mPackages.get(packageName);
19164            if (uninstalledPs == null) {
19165                Slog.w(TAG, "Not removing non-existent package " + packageName);
19166                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19167            }
19168
19169            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19170                    && uninstalledPs.versionCode != versionCode) {
19171                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19172                        + uninstalledPs.versionCode + " != " + versionCode);
19173                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19174            }
19175
19176            // Static shared libs can be declared by any package, so let us not
19177            // allow removing a package if it provides a lib others depend on.
19178            pkg = mPackages.get(packageName);
19179
19180            allUsers = sUserManager.getUserIds();
19181
19182            if (pkg != null && pkg.staticSharedLibName != null) {
19183                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19184                        pkg.staticSharedLibVersion);
19185                if (libEntry != null) {
19186                    for (int currUserId : allUsers) {
19187                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19188                            continue;
19189                        }
19190                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19191                                libEntry.info, 0, currUserId);
19192                        if (!ArrayUtils.isEmpty(libClientPackages)) {
19193                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19194                                    + " hosting lib " + libEntry.info.getName() + " version "
19195                                    + libEntry.info.getVersion() + " used by " + libClientPackages
19196                                    + " for user " + currUserId);
19197                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19198                        }
19199                    }
19200                }
19201            }
19202
19203            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19204        }
19205
19206        final int freezeUser;
19207        if (isUpdatedSystemApp(uninstalledPs)
19208                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19209            // We're downgrading a system app, which will apply to all users, so
19210            // freeze them all during the downgrade
19211            freezeUser = UserHandle.USER_ALL;
19212        } else {
19213            freezeUser = removeUser;
19214        }
19215
19216        synchronized (mInstallLock) {
19217            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19218            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19219                    deleteFlags, "deletePackageX")) {
19220                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19221                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19222            }
19223            synchronized (mPackages) {
19224                if (res) {
19225                    if (pkg != null) {
19226                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19227                    }
19228                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19229                    updateInstantAppInstallerLocked(packageName);
19230                }
19231            }
19232        }
19233
19234        if (res) {
19235            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19236            info.sendPackageRemovedBroadcasts(killApp);
19237            info.sendSystemPackageUpdatedBroadcasts();
19238            info.sendSystemPackageAppearedBroadcasts();
19239        }
19240        // Force a gc here.
19241        Runtime.getRuntime().gc();
19242        // Delete the resources here after sending the broadcast to let
19243        // other processes clean up before deleting resources.
19244        if (info.args != null) {
19245            synchronized (mInstallLock) {
19246                info.args.doPostDeleteLI(true);
19247            }
19248        }
19249
19250        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19251    }
19252
19253    static class PackageRemovedInfo {
19254        final PackageSender packageSender;
19255        String removedPackage;
19256        String installerPackageName;
19257        int uid = -1;
19258        int removedAppId = -1;
19259        int[] origUsers;
19260        int[] removedUsers = null;
19261        int[] broadcastUsers = null;
19262        SparseArray<Integer> installReasons;
19263        boolean isRemovedPackageSystemUpdate = false;
19264        boolean isUpdate;
19265        boolean dataRemoved;
19266        boolean removedForAllUsers;
19267        boolean isStaticSharedLib;
19268        // Clean up resources deleted packages.
19269        InstallArgs args = null;
19270        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19271        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19272
19273        PackageRemovedInfo(PackageSender packageSender) {
19274            this.packageSender = packageSender;
19275        }
19276
19277        void sendPackageRemovedBroadcasts(boolean killApp) {
19278            sendPackageRemovedBroadcastInternal(killApp);
19279            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19280            for (int i = 0; i < childCount; i++) {
19281                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19282                childInfo.sendPackageRemovedBroadcastInternal(killApp);
19283            }
19284        }
19285
19286        void sendSystemPackageUpdatedBroadcasts() {
19287            if (isRemovedPackageSystemUpdate) {
19288                sendSystemPackageUpdatedBroadcastsInternal();
19289                final int childCount = (removedChildPackages != null)
19290                        ? removedChildPackages.size() : 0;
19291                for (int i = 0; i < childCount; i++) {
19292                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19293                    if (childInfo.isRemovedPackageSystemUpdate) {
19294                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19295                    }
19296                }
19297            }
19298        }
19299
19300        void sendSystemPackageAppearedBroadcasts() {
19301            final int packageCount = (appearedChildPackages != null)
19302                    ? appearedChildPackages.size() : 0;
19303            for (int i = 0; i < packageCount; i++) {
19304                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19305                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19306                    true /*sendBootCompleted*/, false /*startReceiver*/,
19307                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19308            }
19309        }
19310
19311        private void sendSystemPackageUpdatedBroadcastsInternal() {
19312            Bundle extras = new Bundle(2);
19313            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19314            extras.putBoolean(Intent.EXTRA_REPLACING, true);
19315            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19316                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19317            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19318                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19319            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19320                null, null, 0, removedPackage, null, null);
19321            if (installerPackageName != null) {
19322                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19323                        removedPackage, extras, 0 /*flags*/,
19324                        installerPackageName, null, null);
19325                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19326                        removedPackage, extras, 0 /*flags*/,
19327                        installerPackageName, null, null);
19328            }
19329        }
19330
19331        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19332            // Don't send static shared library removal broadcasts as these
19333            // libs are visible only the the apps that depend on them an one
19334            // cannot remove the library if it has a dependency.
19335            if (isStaticSharedLib) {
19336                return;
19337            }
19338            Bundle extras = new Bundle(2);
19339            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19340            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19341            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19342            if (isUpdate || isRemovedPackageSystemUpdate) {
19343                extras.putBoolean(Intent.EXTRA_REPLACING, true);
19344            }
19345            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19346            if (removedPackage != null) {
19347                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19348                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19349                if (installerPackageName != null) {
19350                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19351                            removedPackage, extras, 0 /*flags*/,
19352                            installerPackageName, null, broadcastUsers);
19353                }
19354                if (dataRemoved && !isRemovedPackageSystemUpdate) {
19355                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19356                        removedPackage, extras,
19357                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19358                        null, null, broadcastUsers);
19359                }
19360            }
19361            if (removedAppId >= 0) {
19362                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19363                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19364                    null, null, broadcastUsers);
19365            }
19366        }
19367
19368        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19369            removedUsers = userIds;
19370            if (removedUsers == null) {
19371                broadcastUsers = null;
19372                return;
19373            }
19374
19375            broadcastUsers = EMPTY_INT_ARRAY;
19376            for (int i = userIds.length - 1; i >= 0; --i) {
19377                final int userId = userIds[i];
19378                if (deletedPackageSetting.getInstantApp(userId)) {
19379                    continue;
19380                }
19381                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19382            }
19383        }
19384    }
19385
19386    /*
19387     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19388     * flag is not set, the data directory is removed as well.
19389     * make sure this flag is set for partially installed apps. If not its meaningless to
19390     * delete a partially installed application.
19391     */
19392    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19393            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19394        String packageName = ps.name;
19395        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19396        // Retrieve object to delete permissions for shared user later on
19397        final PackageParser.Package deletedPkg;
19398        final PackageSetting deletedPs;
19399        // reader
19400        synchronized (mPackages) {
19401            deletedPkg = mPackages.get(packageName);
19402            deletedPs = mSettings.mPackages.get(packageName);
19403            if (outInfo != null) {
19404                outInfo.removedPackage = packageName;
19405                outInfo.installerPackageName = ps.installerPackageName;
19406                outInfo.isStaticSharedLib = deletedPkg != null
19407                        && deletedPkg.staticSharedLibName != null;
19408                outInfo.populateUsers(deletedPs == null ? null
19409                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19410            }
19411        }
19412
19413        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19414
19415        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19416            final PackageParser.Package resolvedPkg;
19417            if (deletedPkg != null) {
19418                resolvedPkg = deletedPkg;
19419            } else {
19420                // We don't have a parsed package when it lives on an ejected
19421                // adopted storage device, so fake something together
19422                resolvedPkg = new PackageParser.Package(ps.name);
19423                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19424            }
19425            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19426                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19427            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19428            if (outInfo != null) {
19429                outInfo.dataRemoved = true;
19430            }
19431            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19432        }
19433
19434        int removedAppId = -1;
19435
19436        // writer
19437        synchronized (mPackages) {
19438            boolean installedStateChanged = false;
19439            if (deletedPs != null) {
19440                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19441                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19442                    clearDefaultBrowserIfNeeded(packageName);
19443                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19444                    removedAppId = mSettings.removePackageLPw(packageName);
19445                    if (outInfo != null) {
19446                        outInfo.removedAppId = removedAppId;
19447                    }
19448                    updatePermissionsLPw(deletedPs.name, null, 0);
19449                    if (deletedPs.sharedUser != null) {
19450                        // Remove permissions associated with package. Since runtime
19451                        // permissions are per user we have to kill the removed package
19452                        // or packages running under the shared user of the removed
19453                        // package if revoking the permissions requested only by the removed
19454                        // package is successful and this causes a change in gids.
19455                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19456                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19457                                    userId);
19458                            if (userIdToKill == UserHandle.USER_ALL
19459                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19460                                // If gids changed for this user, kill all affected packages.
19461                                mHandler.post(new Runnable() {
19462                                    @Override
19463                                    public void run() {
19464                                        // This has to happen with no lock held.
19465                                        killApplication(deletedPs.name, deletedPs.appId,
19466                                                KILL_APP_REASON_GIDS_CHANGED);
19467                                    }
19468                                });
19469                                break;
19470                            }
19471                        }
19472                    }
19473                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19474                }
19475                // make sure to preserve per-user disabled state if this removal was just
19476                // a downgrade of a system app to the factory package
19477                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19478                    if (DEBUG_REMOVE) {
19479                        Slog.d(TAG, "Propagating install state across downgrade");
19480                    }
19481                    for (int userId : allUserHandles) {
19482                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19483                        if (DEBUG_REMOVE) {
19484                            Slog.d(TAG, "    user " + userId + " => " + installed);
19485                        }
19486                        if (installed != ps.getInstalled(userId)) {
19487                            installedStateChanged = true;
19488                        }
19489                        ps.setInstalled(installed, userId);
19490                    }
19491                }
19492            }
19493            // can downgrade to reader
19494            if (writeSettings) {
19495                // Save settings now
19496                mSettings.writeLPr();
19497            }
19498            if (installedStateChanged) {
19499                mSettings.writeKernelMappingLPr(ps);
19500            }
19501        }
19502        if (removedAppId != -1) {
19503            // A user ID was deleted here. Go through all users and remove it
19504            // from KeyStore.
19505            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19506        }
19507    }
19508
19509    static boolean locationIsPrivileged(File path) {
19510        try {
19511            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19512                    .getCanonicalPath();
19513            return path.getCanonicalPath().startsWith(privilegedAppDir);
19514        } catch (IOException e) {
19515            Slog.e(TAG, "Unable to access code path " + path);
19516        }
19517        return false;
19518    }
19519
19520    /*
19521     * Tries to delete system package.
19522     */
19523    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19524            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19525            boolean writeSettings) {
19526        if (deletedPs.parentPackageName != null) {
19527            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19528            return false;
19529        }
19530
19531        final boolean applyUserRestrictions
19532                = (allUserHandles != null) && (outInfo.origUsers != null);
19533        final PackageSetting disabledPs;
19534        // Confirm if the system package has been updated
19535        // An updated system app can be deleted. This will also have to restore
19536        // the system pkg from system partition
19537        // reader
19538        synchronized (mPackages) {
19539            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19540        }
19541
19542        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19543                + " disabledPs=" + disabledPs);
19544
19545        if (disabledPs == null) {
19546            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19547            return false;
19548        } else if (DEBUG_REMOVE) {
19549            Slog.d(TAG, "Deleting system pkg from data partition");
19550        }
19551
19552        if (DEBUG_REMOVE) {
19553            if (applyUserRestrictions) {
19554                Slog.d(TAG, "Remembering install states:");
19555                for (int userId : allUserHandles) {
19556                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19557                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19558                }
19559            }
19560        }
19561
19562        // Delete the updated package
19563        outInfo.isRemovedPackageSystemUpdate = true;
19564        if (outInfo.removedChildPackages != null) {
19565            final int childCount = (deletedPs.childPackageNames != null)
19566                    ? deletedPs.childPackageNames.size() : 0;
19567            for (int i = 0; i < childCount; i++) {
19568                String childPackageName = deletedPs.childPackageNames.get(i);
19569                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19570                        .contains(childPackageName)) {
19571                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19572                            childPackageName);
19573                    if (childInfo != null) {
19574                        childInfo.isRemovedPackageSystemUpdate = true;
19575                    }
19576                }
19577            }
19578        }
19579
19580        if (disabledPs.versionCode < deletedPs.versionCode) {
19581            // Delete data for downgrades
19582            flags &= ~PackageManager.DELETE_KEEP_DATA;
19583        } else {
19584            // Preserve data by setting flag
19585            flags |= PackageManager.DELETE_KEEP_DATA;
19586        }
19587
19588        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19589                outInfo, writeSettings, disabledPs.pkg);
19590        if (!ret) {
19591            return false;
19592        }
19593
19594        // writer
19595        synchronized (mPackages) {
19596            // Reinstate the old system package
19597            enableSystemPackageLPw(disabledPs.pkg);
19598            // Remove any native libraries from the upgraded package.
19599            removeNativeBinariesLI(deletedPs);
19600        }
19601
19602        // Install the system package
19603        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19604        int parseFlags = mDefParseFlags
19605                | PackageParser.PARSE_MUST_BE_APK
19606                | PackageParser.PARSE_IS_SYSTEM
19607                | PackageParser.PARSE_IS_SYSTEM_DIR;
19608        if (locationIsPrivileged(disabledPs.codePath)) {
19609            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
19610        }
19611
19612        final PackageParser.Package newPkg;
19613        try {
19614            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
19615                0 /* currentTime */, null);
19616        } catch (PackageManagerException e) {
19617            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19618                    + e.getMessage());
19619            return false;
19620        }
19621
19622        try {
19623            // update shared libraries for the newly re-installed system package
19624            updateSharedLibrariesLPr(newPkg, null);
19625        } catch (PackageManagerException e) {
19626            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19627        }
19628
19629        prepareAppDataAfterInstallLIF(newPkg);
19630
19631        // writer
19632        synchronized (mPackages) {
19633            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
19634
19635            // Propagate the permissions state as we do not want to drop on the floor
19636            // runtime permissions. The update permissions method below will take
19637            // care of removing obsolete permissions and grant install permissions.
19638            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
19639            updatePermissionsLPw(newPkg.packageName, newPkg,
19640                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
19641
19642            if (applyUserRestrictions) {
19643                boolean installedStateChanged = false;
19644                if (DEBUG_REMOVE) {
19645                    Slog.d(TAG, "Propagating install state across reinstall");
19646                }
19647                for (int userId : allUserHandles) {
19648                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19649                    if (DEBUG_REMOVE) {
19650                        Slog.d(TAG, "    user " + userId + " => " + installed);
19651                    }
19652                    if (installed != ps.getInstalled(userId)) {
19653                        installedStateChanged = true;
19654                    }
19655                    ps.setInstalled(installed, userId);
19656
19657                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19658                }
19659                // Regardless of writeSettings we need to ensure that this restriction
19660                // state propagation is persisted
19661                mSettings.writeAllUsersPackageRestrictionsLPr();
19662                if (installedStateChanged) {
19663                    mSettings.writeKernelMappingLPr(ps);
19664                }
19665            }
19666            // can downgrade to reader here
19667            if (writeSettings) {
19668                mSettings.writeLPr();
19669            }
19670        }
19671        return true;
19672    }
19673
19674    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19675            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19676            PackageRemovedInfo outInfo, boolean writeSettings,
19677            PackageParser.Package replacingPackage) {
19678        synchronized (mPackages) {
19679            if (outInfo != null) {
19680                outInfo.uid = ps.appId;
19681            }
19682
19683            if (outInfo != null && outInfo.removedChildPackages != null) {
19684                final int childCount = (ps.childPackageNames != null)
19685                        ? ps.childPackageNames.size() : 0;
19686                for (int i = 0; i < childCount; i++) {
19687                    String childPackageName = ps.childPackageNames.get(i);
19688                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19689                    if (childPs == null) {
19690                        return false;
19691                    }
19692                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19693                            childPackageName);
19694                    if (childInfo != null) {
19695                        childInfo.uid = childPs.appId;
19696                    }
19697                }
19698            }
19699        }
19700
19701        // Delete package data from internal structures and also remove data if flag is set
19702        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19703
19704        // Delete the child packages data
19705        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19706        for (int i = 0; i < childCount; i++) {
19707            PackageSetting childPs;
19708            synchronized (mPackages) {
19709                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19710            }
19711            if (childPs != null) {
19712                PackageRemovedInfo childOutInfo = (outInfo != null
19713                        && outInfo.removedChildPackages != null)
19714                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19715                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19716                        && (replacingPackage != null
19717                        && !replacingPackage.hasChildPackage(childPs.name))
19718                        ? flags & ~DELETE_KEEP_DATA : flags;
19719                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19720                        deleteFlags, writeSettings);
19721            }
19722        }
19723
19724        // Delete application code and resources only for parent packages
19725        if (ps.parentPackageName == null) {
19726            if (deleteCodeAndResources && (outInfo != null)) {
19727                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19728                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19729                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19730            }
19731        }
19732
19733        return true;
19734    }
19735
19736    @Override
19737    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19738            int userId) {
19739        mContext.enforceCallingOrSelfPermission(
19740                android.Manifest.permission.DELETE_PACKAGES, null);
19741        synchronized (mPackages) {
19742            // Cannot block uninstall of static shared libs as they are
19743            // considered a part of the using app (emulating static linking).
19744            // Also static libs are installed always on internal storage.
19745            PackageParser.Package pkg = mPackages.get(packageName);
19746            if (pkg != null && pkg.staticSharedLibName != null) {
19747                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19748                        + " providing static shared library: " + pkg.staticSharedLibName);
19749                return false;
19750            }
19751            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19752            mSettings.writePackageRestrictionsLPr(userId);
19753        }
19754        return true;
19755    }
19756
19757    @Override
19758    public boolean getBlockUninstallForUser(String packageName, int userId) {
19759        synchronized (mPackages) {
19760            final PackageSetting ps = mSettings.mPackages.get(packageName);
19761            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19762                return false;
19763            }
19764            return mSettings.getBlockUninstallLPr(userId, packageName);
19765        }
19766    }
19767
19768    @Override
19769    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19770        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19771        synchronized (mPackages) {
19772            PackageSetting ps = mSettings.mPackages.get(packageName);
19773            if (ps == null) {
19774                Log.w(TAG, "Package doesn't exist: " + packageName);
19775                return false;
19776            }
19777            if (systemUserApp) {
19778                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19779            } else {
19780                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19781            }
19782            mSettings.writeLPr();
19783        }
19784        return true;
19785    }
19786
19787    /*
19788     * This method handles package deletion in general
19789     */
19790    private boolean deletePackageLIF(String packageName, UserHandle user,
19791            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19792            PackageRemovedInfo outInfo, boolean writeSettings,
19793            PackageParser.Package replacingPackage) {
19794        if (packageName == null) {
19795            Slog.w(TAG, "Attempt to delete null packageName.");
19796            return false;
19797        }
19798
19799        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19800
19801        PackageSetting ps;
19802        synchronized (mPackages) {
19803            ps = mSettings.mPackages.get(packageName);
19804            if (ps == null) {
19805                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19806                return false;
19807            }
19808
19809            if (ps.parentPackageName != null && (!isSystemApp(ps)
19810                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19811                if (DEBUG_REMOVE) {
19812                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19813                            + ((user == null) ? UserHandle.USER_ALL : user));
19814                }
19815                final int removedUserId = (user != null) ? user.getIdentifier()
19816                        : UserHandle.USER_ALL;
19817                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19818                    return false;
19819                }
19820                markPackageUninstalledForUserLPw(ps, user);
19821                scheduleWritePackageRestrictionsLocked(user);
19822                return true;
19823            }
19824        }
19825
19826        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19827                && user.getIdentifier() != UserHandle.USER_ALL)) {
19828            // The caller is asking that the package only be deleted for a single
19829            // user.  To do this, we just mark its uninstalled state and delete
19830            // its data. If this is a system app, we only allow this to happen if
19831            // they have set the special DELETE_SYSTEM_APP which requests different
19832            // semantics than normal for uninstalling system apps.
19833            markPackageUninstalledForUserLPw(ps, user);
19834
19835            if (!isSystemApp(ps)) {
19836                // Do not uninstall the APK if an app should be cached
19837                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19838                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19839                    // Other user still have this package installed, so all
19840                    // we need to do is clear this user's data and save that
19841                    // it is uninstalled.
19842                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19843                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19844                        return false;
19845                    }
19846                    scheduleWritePackageRestrictionsLocked(user);
19847                    return true;
19848                } else {
19849                    // We need to set it back to 'installed' so the uninstall
19850                    // broadcasts will be sent correctly.
19851                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19852                    ps.setInstalled(true, user.getIdentifier());
19853                    mSettings.writeKernelMappingLPr(ps);
19854                }
19855            } else {
19856                // This is a system app, so we assume that the
19857                // other users still have this package installed, so all
19858                // we need to do is clear this user's data and save that
19859                // it is uninstalled.
19860                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19861                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19862                    return false;
19863                }
19864                scheduleWritePackageRestrictionsLocked(user);
19865                return true;
19866            }
19867        }
19868
19869        // If we are deleting a composite package for all users, keep track
19870        // of result for each child.
19871        if (ps.childPackageNames != null && outInfo != null) {
19872            synchronized (mPackages) {
19873                final int childCount = ps.childPackageNames.size();
19874                outInfo.removedChildPackages = new ArrayMap<>(childCount);
19875                for (int i = 0; i < childCount; i++) {
19876                    String childPackageName = ps.childPackageNames.get(i);
19877                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19878                    childInfo.removedPackage = childPackageName;
19879                    childInfo.installerPackageName = ps.installerPackageName;
19880                    outInfo.removedChildPackages.put(childPackageName, childInfo);
19881                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19882                    if (childPs != null) {
19883                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19884                    }
19885                }
19886            }
19887        }
19888
19889        boolean ret = false;
19890        if (isSystemApp(ps)) {
19891            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19892            // When an updated system application is deleted we delete the existing resources
19893            // as well and fall back to existing code in system partition
19894            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19895        } else {
19896            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19897            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19898                    outInfo, writeSettings, replacingPackage);
19899        }
19900
19901        // Take a note whether we deleted the package for all users
19902        if (outInfo != null) {
19903            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19904            if (outInfo.removedChildPackages != null) {
19905                synchronized (mPackages) {
19906                    final int childCount = outInfo.removedChildPackages.size();
19907                    for (int i = 0; i < childCount; i++) {
19908                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19909                        if (childInfo != null) {
19910                            childInfo.removedForAllUsers = mPackages.get(
19911                                    childInfo.removedPackage) == null;
19912                        }
19913                    }
19914                }
19915            }
19916            // If we uninstalled an update to a system app there may be some
19917            // child packages that appeared as they are declared in the system
19918            // app but were not declared in the update.
19919            if (isSystemApp(ps)) {
19920                synchronized (mPackages) {
19921                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19922                    final int childCount = (updatedPs.childPackageNames != null)
19923                            ? updatedPs.childPackageNames.size() : 0;
19924                    for (int i = 0; i < childCount; i++) {
19925                        String childPackageName = updatedPs.childPackageNames.get(i);
19926                        if (outInfo.removedChildPackages == null
19927                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19928                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19929                            if (childPs == null) {
19930                                continue;
19931                            }
19932                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19933                            installRes.name = childPackageName;
19934                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19935                            installRes.pkg = mPackages.get(childPackageName);
19936                            installRes.uid = childPs.pkg.applicationInfo.uid;
19937                            if (outInfo.appearedChildPackages == null) {
19938                                outInfo.appearedChildPackages = new ArrayMap<>();
19939                            }
19940                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19941                        }
19942                    }
19943                }
19944            }
19945        }
19946
19947        return ret;
19948    }
19949
19950    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19951        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19952                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19953        for (int nextUserId : userIds) {
19954            if (DEBUG_REMOVE) {
19955                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19956            }
19957            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19958                    false /*installed*/,
19959                    true /*stopped*/,
19960                    true /*notLaunched*/,
19961                    false /*hidden*/,
19962                    false /*suspended*/,
19963                    false /*instantApp*/,
19964                    null /*lastDisableAppCaller*/,
19965                    null /*enabledComponents*/,
19966                    null /*disabledComponents*/,
19967                    ps.readUserState(nextUserId).domainVerificationStatus,
19968                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19969        }
19970        mSettings.writeKernelMappingLPr(ps);
19971    }
19972
19973    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19974            PackageRemovedInfo outInfo) {
19975        final PackageParser.Package pkg;
19976        synchronized (mPackages) {
19977            pkg = mPackages.get(ps.name);
19978        }
19979
19980        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19981                : new int[] {userId};
19982        for (int nextUserId : userIds) {
19983            if (DEBUG_REMOVE) {
19984                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19985                        + nextUserId);
19986            }
19987
19988            destroyAppDataLIF(pkg, userId,
19989                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19990            destroyAppProfilesLIF(pkg, userId);
19991            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19992            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19993            schedulePackageCleaning(ps.name, nextUserId, false);
19994            synchronized (mPackages) {
19995                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19996                    scheduleWritePackageRestrictionsLocked(nextUserId);
19997                }
19998                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19999            }
20000        }
20001
20002        if (outInfo != null) {
20003            outInfo.removedPackage = ps.name;
20004            outInfo.installerPackageName = ps.installerPackageName;
20005            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
20006            outInfo.removedAppId = ps.appId;
20007            outInfo.removedUsers = userIds;
20008            outInfo.broadcastUsers = userIds;
20009        }
20010
20011        return true;
20012    }
20013
20014    private final class ClearStorageConnection implements ServiceConnection {
20015        IMediaContainerService mContainerService;
20016
20017        @Override
20018        public void onServiceConnected(ComponentName name, IBinder service) {
20019            synchronized (this) {
20020                mContainerService = IMediaContainerService.Stub
20021                        .asInterface(Binder.allowBlocking(service));
20022                notifyAll();
20023            }
20024        }
20025
20026        @Override
20027        public void onServiceDisconnected(ComponentName name) {
20028        }
20029    }
20030
20031    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20032        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20033
20034        final boolean mounted;
20035        if (Environment.isExternalStorageEmulated()) {
20036            mounted = true;
20037        } else {
20038            final String status = Environment.getExternalStorageState();
20039
20040            mounted = status.equals(Environment.MEDIA_MOUNTED)
20041                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20042        }
20043
20044        if (!mounted) {
20045            return;
20046        }
20047
20048        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20049        int[] users;
20050        if (userId == UserHandle.USER_ALL) {
20051            users = sUserManager.getUserIds();
20052        } else {
20053            users = new int[] { userId };
20054        }
20055        final ClearStorageConnection conn = new ClearStorageConnection();
20056        if (mContext.bindServiceAsUser(
20057                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20058            try {
20059                for (int curUser : users) {
20060                    long timeout = SystemClock.uptimeMillis() + 5000;
20061                    synchronized (conn) {
20062                        long now;
20063                        while (conn.mContainerService == null &&
20064                                (now = SystemClock.uptimeMillis()) < timeout) {
20065                            try {
20066                                conn.wait(timeout - now);
20067                            } catch (InterruptedException e) {
20068                            }
20069                        }
20070                    }
20071                    if (conn.mContainerService == null) {
20072                        return;
20073                    }
20074
20075                    final UserEnvironment userEnv = new UserEnvironment(curUser);
20076                    clearDirectory(conn.mContainerService,
20077                            userEnv.buildExternalStorageAppCacheDirs(packageName));
20078                    if (allData) {
20079                        clearDirectory(conn.mContainerService,
20080                                userEnv.buildExternalStorageAppDataDirs(packageName));
20081                        clearDirectory(conn.mContainerService,
20082                                userEnv.buildExternalStorageAppMediaDirs(packageName));
20083                    }
20084                }
20085            } finally {
20086                mContext.unbindService(conn);
20087            }
20088        }
20089    }
20090
20091    @Override
20092    public void clearApplicationProfileData(String packageName) {
20093        enforceSystemOrRoot("Only the system can clear all profile data");
20094
20095        final PackageParser.Package pkg;
20096        synchronized (mPackages) {
20097            pkg = mPackages.get(packageName);
20098        }
20099
20100        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20101            synchronized (mInstallLock) {
20102                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20103            }
20104        }
20105    }
20106
20107    @Override
20108    public void clearApplicationUserData(final String packageName,
20109            final IPackageDataObserver observer, final int userId) {
20110        mContext.enforceCallingOrSelfPermission(
20111                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20112
20113        final int callingUid = Binder.getCallingUid();
20114        enforceCrossUserPermission(callingUid, userId,
20115                true /* requireFullPermission */, false /* checkShell */, "clear application data");
20116
20117        final PackageSetting ps = mSettings.getPackageLPr(packageName);
20118        if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
20119            return;
20120        }
20121        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20122            throw new SecurityException("Cannot clear data for a protected package: "
20123                    + packageName);
20124        }
20125        // Queue up an async operation since the package deletion may take a little while.
20126        mHandler.post(new Runnable() {
20127            public void run() {
20128                mHandler.removeCallbacks(this);
20129                final boolean succeeded;
20130                try (PackageFreezer freezer = freezePackage(packageName,
20131                        "clearApplicationUserData")) {
20132                    synchronized (mInstallLock) {
20133                        succeeded = clearApplicationUserDataLIF(packageName, userId);
20134                    }
20135                    clearExternalStorageDataSync(packageName, userId, true);
20136                    synchronized (mPackages) {
20137                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20138                                packageName, userId);
20139                    }
20140                }
20141                if (succeeded) {
20142                    // invoke DeviceStorageMonitor's update method to clear any notifications
20143                    DeviceStorageMonitorInternal dsm = LocalServices
20144                            .getService(DeviceStorageMonitorInternal.class);
20145                    if (dsm != null) {
20146                        dsm.checkMemory();
20147                    }
20148                }
20149                if(observer != null) {
20150                    try {
20151                        observer.onRemoveCompleted(packageName, succeeded);
20152                    } catch (RemoteException e) {
20153                        Log.i(TAG, "Observer no longer exists.");
20154                    }
20155                } //end if observer
20156            } //end run
20157        });
20158    }
20159
20160    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20161        if (packageName == null) {
20162            Slog.w(TAG, "Attempt to delete null packageName.");
20163            return false;
20164        }
20165
20166        // Try finding details about the requested package
20167        PackageParser.Package pkg;
20168        synchronized (mPackages) {
20169            pkg = mPackages.get(packageName);
20170            if (pkg == null) {
20171                final PackageSetting ps = mSettings.mPackages.get(packageName);
20172                if (ps != null) {
20173                    pkg = ps.pkg;
20174                }
20175            }
20176
20177            if (pkg == null) {
20178                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20179                return false;
20180            }
20181
20182            PackageSetting ps = (PackageSetting) pkg.mExtras;
20183            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20184        }
20185
20186        clearAppDataLIF(pkg, userId,
20187                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20188
20189        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20190        removeKeystoreDataIfNeeded(userId, appId);
20191
20192        UserManagerInternal umInternal = getUserManagerInternal();
20193        final int flags;
20194        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20195            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20196        } else if (umInternal.isUserRunning(userId)) {
20197            flags = StorageManager.FLAG_STORAGE_DE;
20198        } else {
20199            flags = 0;
20200        }
20201        prepareAppDataContentsLIF(pkg, userId, flags);
20202
20203        return true;
20204    }
20205
20206    /**
20207     * Reverts user permission state changes (permissions and flags) in
20208     * all packages for a given user.
20209     *
20210     * @param userId The device user for which to do a reset.
20211     */
20212    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20213        final int packageCount = mPackages.size();
20214        for (int i = 0; i < packageCount; i++) {
20215            PackageParser.Package pkg = mPackages.valueAt(i);
20216            PackageSetting ps = (PackageSetting) pkg.mExtras;
20217            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20218        }
20219    }
20220
20221    private void resetNetworkPolicies(int userId) {
20222        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20223    }
20224
20225    /**
20226     * Reverts user permission state changes (permissions and flags).
20227     *
20228     * @param ps The package for which to reset.
20229     * @param userId The device user for which to do a reset.
20230     */
20231    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20232            final PackageSetting ps, final int userId) {
20233        if (ps.pkg == null) {
20234            return;
20235        }
20236
20237        // These are flags that can change base on user actions.
20238        final int userSettableMask = FLAG_PERMISSION_USER_SET
20239                | FLAG_PERMISSION_USER_FIXED
20240                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20241                | FLAG_PERMISSION_REVIEW_REQUIRED;
20242
20243        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20244                | FLAG_PERMISSION_POLICY_FIXED;
20245
20246        boolean writeInstallPermissions = false;
20247        boolean writeRuntimePermissions = false;
20248
20249        final int permissionCount = ps.pkg.requestedPermissions.size();
20250        for (int i = 0; i < permissionCount; i++) {
20251            String permission = ps.pkg.requestedPermissions.get(i);
20252
20253            BasePermission bp = mSettings.mPermissions.get(permission);
20254            if (bp == null) {
20255                continue;
20256            }
20257
20258            // If shared user we just reset the state to which only this app contributed.
20259            if (ps.sharedUser != null) {
20260                boolean used = false;
20261                final int packageCount = ps.sharedUser.packages.size();
20262                for (int j = 0; j < packageCount; j++) {
20263                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20264                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20265                            && pkg.pkg.requestedPermissions.contains(permission)) {
20266                        used = true;
20267                        break;
20268                    }
20269                }
20270                if (used) {
20271                    continue;
20272                }
20273            }
20274
20275            PermissionsState permissionsState = ps.getPermissionsState();
20276
20277            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20278
20279            // Always clear the user settable flags.
20280            final boolean hasInstallState = permissionsState.getInstallPermissionState(
20281                    bp.name) != null;
20282            // If permission review is enabled and this is a legacy app, mark the
20283            // permission as requiring a review as this is the initial state.
20284            int flags = 0;
20285            if (mPermissionReviewRequired
20286                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20287                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20288            }
20289            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20290                if (hasInstallState) {
20291                    writeInstallPermissions = true;
20292                } else {
20293                    writeRuntimePermissions = true;
20294                }
20295            }
20296
20297            // Below is only runtime permission handling.
20298            if (!bp.isRuntime()) {
20299                continue;
20300            }
20301
20302            // Never clobber system or policy.
20303            if ((oldFlags & policyOrSystemFlags) != 0) {
20304                continue;
20305            }
20306
20307            // If this permission was granted by default, make sure it is.
20308            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20309                if (permissionsState.grantRuntimePermission(bp, userId)
20310                        != PERMISSION_OPERATION_FAILURE) {
20311                    writeRuntimePermissions = true;
20312                }
20313            // If permission review is enabled the permissions for a legacy apps
20314            // are represented as constantly granted runtime ones, so don't revoke.
20315            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20316                // Otherwise, reset the permission.
20317                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20318                switch (revokeResult) {
20319                    case PERMISSION_OPERATION_SUCCESS:
20320                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20321                        writeRuntimePermissions = true;
20322                        final int appId = ps.appId;
20323                        mHandler.post(new Runnable() {
20324                            @Override
20325                            public void run() {
20326                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20327                            }
20328                        });
20329                    } break;
20330                }
20331            }
20332        }
20333
20334        // Synchronously write as we are taking permissions away.
20335        if (writeRuntimePermissions) {
20336            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20337        }
20338
20339        // Synchronously write as we are taking permissions away.
20340        if (writeInstallPermissions) {
20341            mSettings.writeLPr();
20342        }
20343    }
20344
20345    /**
20346     * Remove entries from the keystore daemon. Will only remove it if the
20347     * {@code appId} is valid.
20348     */
20349    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20350        if (appId < 0) {
20351            return;
20352        }
20353
20354        final KeyStore keyStore = KeyStore.getInstance();
20355        if (keyStore != null) {
20356            if (userId == UserHandle.USER_ALL) {
20357                for (final int individual : sUserManager.getUserIds()) {
20358                    keyStore.clearUid(UserHandle.getUid(individual, appId));
20359                }
20360            } else {
20361                keyStore.clearUid(UserHandle.getUid(userId, appId));
20362            }
20363        } else {
20364            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20365        }
20366    }
20367
20368    @Override
20369    public void deleteApplicationCacheFiles(final String packageName,
20370            final IPackageDataObserver observer) {
20371        final int userId = UserHandle.getCallingUserId();
20372        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20373    }
20374
20375    @Override
20376    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20377            final IPackageDataObserver observer) {
20378        final int callingUid = Binder.getCallingUid();
20379        mContext.enforceCallingOrSelfPermission(
20380                android.Manifest.permission.DELETE_CACHE_FILES, null);
20381        enforceCrossUserPermission(callingUid, userId,
20382                /* requireFullPermission= */ true, /* checkShell= */ false,
20383                "delete application cache files");
20384        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20385                android.Manifest.permission.ACCESS_INSTANT_APPS);
20386
20387        final PackageParser.Package pkg;
20388        synchronized (mPackages) {
20389            pkg = mPackages.get(packageName);
20390        }
20391
20392        // Queue up an async operation since the package deletion may take a little while.
20393        mHandler.post(new Runnable() {
20394            public void run() {
20395                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20396                boolean doClearData = true;
20397                if (ps != null) {
20398                    final boolean targetIsInstantApp =
20399                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20400                    doClearData = !targetIsInstantApp
20401                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20402                }
20403                if (doClearData) {
20404                    synchronized (mInstallLock) {
20405                        final int flags = StorageManager.FLAG_STORAGE_DE
20406                                | StorageManager.FLAG_STORAGE_CE;
20407                        // We're only clearing cache files, so we don't care if the
20408                        // app is unfrozen and still able to run
20409                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20410                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20411                    }
20412                    clearExternalStorageDataSync(packageName, userId, false);
20413                }
20414                if (observer != null) {
20415                    try {
20416                        observer.onRemoveCompleted(packageName, true);
20417                    } catch (RemoteException e) {
20418                        Log.i(TAG, "Observer no longer exists.");
20419                    }
20420                }
20421            }
20422        });
20423    }
20424
20425    @Override
20426    public void getPackageSizeInfo(final String packageName, int userHandle,
20427            final IPackageStatsObserver observer) {
20428        throw new UnsupportedOperationException(
20429                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20430    }
20431
20432    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20433        final PackageSetting ps;
20434        synchronized (mPackages) {
20435            ps = mSettings.mPackages.get(packageName);
20436            if (ps == null) {
20437                Slog.w(TAG, "Failed to find settings for " + packageName);
20438                return false;
20439            }
20440        }
20441
20442        final String[] packageNames = { packageName };
20443        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20444        final String[] codePaths = { ps.codePathString };
20445
20446        try {
20447            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20448                    ps.appId, ceDataInodes, codePaths, stats);
20449
20450            // For now, ignore code size of packages on system partition
20451            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20452                stats.codeSize = 0;
20453            }
20454
20455            // External clients expect these to be tracked separately
20456            stats.dataSize -= stats.cacheSize;
20457
20458        } catch (InstallerException e) {
20459            Slog.w(TAG, String.valueOf(e));
20460            return false;
20461        }
20462
20463        return true;
20464    }
20465
20466    private int getUidTargetSdkVersionLockedLPr(int uid) {
20467        Object obj = mSettings.getUserIdLPr(uid);
20468        if (obj instanceof SharedUserSetting) {
20469            final SharedUserSetting sus = (SharedUserSetting) obj;
20470            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20471            final Iterator<PackageSetting> it = sus.packages.iterator();
20472            while (it.hasNext()) {
20473                final PackageSetting ps = it.next();
20474                if (ps.pkg != null) {
20475                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20476                    if (v < vers) vers = v;
20477                }
20478            }
20479            return vers;
20480        } else if (obj instanceof PackageSetting) {
20481            final PackageSetting ps = (PackageSetting) obj;
20482            if (ps.pkg != null) {
20483                return ps.pkg.applicationInfo.targetSdkVersion;
20484            }
20485        }
20486        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20487    }
20488
20489    @Override
20490    public void addPreferredActivity(IntentFilter filter, int match,
20491            ComponentName[] set, ComponentName activity, int userId) {
20492        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20493                "Adding preferred");
20494    }
20495
20496    private void addPreferredActivityInternal(IntentFilter filter, int match,
20497            ComponentName[] set, ComponentName activity, boolean always, int userId,
20498            String opname) {
20499        // writer
20500        int callingUid = Binder.getCallingUid();
20501        enforceCrossUserPermission(callingUid, userId,
20502                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20503        if (filter.countActions() == 0) {
20504            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20505            return;
20506        }
20507        synchronized (mPackages) {
20508            if (mContext.checkCallingOrSelfPermission(
20509                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20510                    != PackageManager.PERMISSION_GRANTED) {
20511                if (getUidTargetSdkVersionLockedLPr(callingUid)
20512                        < Build.VERSION_CODES.FROYO) {
20513                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20514                            + callingUid);
20515                    return;
20516                }
20517                mContext.enforceCallingOrSelfPermission(
20518                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20519            }
20520
20521            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20522            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20523                    + userId + ":");
20524            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20525            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20526            scheduleWritePackageRestrictionsLocked(userId);
20527            postPreferredActivityChangedBroadcast(userId);
20528        }
20529    }
20530
20531    private void postPreferredActivityChangedBroadcast(int userId) {
20532        mHandler.post(() -> {
20533            final IActivityManager am = ActivityManager.getService();
20534            if (am == null) {
20535                return;
20536            }
20537
20538            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20539            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20540            try {
20541                am.broadcastIntent(null, intent, null, null,
20542                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20543                        null, false, false, userId);
20544            } catch (RemoteException e) {
20545            }
20546        });
20547    }
20548
20549    @Override
20550    public void replacePreferredActivity(IntentFilter filter, int match,
20551            ComponentName[] set, ComponentName activity, int userId) {
20552        if (filter.countActions() != 1) {
20553            throw new IllegalArgumentException(
20554                    "replacePreferredActivity expects filter to have only 1 action.");
20555        }
20556        if (filter.countDataAuthorities() != 0
20557                || filter.countDataPaths() != 0
20558                || filter.countDataSchemes() > 1
20559                || filter.countDataTypes() != 0) {
20560            throw new IllegalArgumentException(
20561                    "replacePreferredActivity expects filter to have no data authorities, " +
20562                    "paths, or types; and at most one scheme.");
20563        }
20564
20565        final int callingUid = Binder.getCallingUid();
20566        enforceCrossUserPermission(callingUid, userId,
20567                true /* requireFullPermission */, false /* checkShell */,
20568                "replace preferred activity");
20569        synchronized (mPackages) {
20570            if (mContext.checkCallingOrSelfPermission(
20571                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20572                    != PackageManager.PERMISSION_GRANTED) {
20573                if (getUidTargetSdkVersionLockedLPr(callingUid)
20574                        < Build.VERSION_CODES.FROYO) {
20575                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20576                            + Binder.getCallingUid());
20577                    return;
20578                }
20579                mContext.enforceCallingOrSelfPermission(
20580                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20581            }
20582
20583            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20584            if (pir != null) {
20585                // Get all of the existing entries that exactly match this filter.
20586                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20587                if (existing != null && existing.size() == 1) {
20588                    PreferredActivity cur = existing.get(0);
20589                    if (DEBUG_PREFERRED) {
20590                        Slog.i(TAG, "Checking replace of preferred:");
20591                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20592                        if (!cur.mPref.mAlways) {
20593                            Slog.i(TAG, "  -- CUR; not mAlways!");
20594                        } else {
20595                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20596                            Slog.i(TAG, "  -- CUR: mSet="
20597                                    + Arrays.toString(cur.mPref.mSetComponents));
20598                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20599                            Slog.i(TAG, "  -- NEW: mMatch="
20600                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20601                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20602                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20603                        }
20604                    }
20605                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20606                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20607                            && cur.mPref.sameSet(set)) {
20608                        // Setting the preferred activity to what it happens to be already
20609                        if (DEBUG_PREFERRED) {
20610                            Slog.i(TAG, "Replacing with same preferred activity "
20611                                    + cur.mPref.mShortComponent + " for user "
20612                                    + userId + ":");
20613                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20614                        }
20615                        return;
20616                    }
20617                }
20618
20619                if (existing != null) {
20620                    if (DEBUG_PREFERRED) {
20621                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
20622                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20623                    }
20624                    for (int i = 0; i < existing.size(); i++) {
20625                        PreferredActivity pa = existing.get(i);
20626                        if (DEBUG_PREFERRED) {
20627                            Slog.i(TAG, "Removing existing preferred activity "
20628                                    + pa.mPref.mComponent + ":");
20629                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
20630                        }
20631                        pir.removeFilter(pa);
20632                    }
20633                }
20634            }
20635            addPreferredActivityInternal(filter, match, set, activity, true, userId,
20636                    "Replacing preferred");
20637        }
20638    }
20639
20640    @Override
20641    public void clearPackagePreferredActivities(String packageName) {
20642        final int callingUid = Binder.getCallingUid();
20643        if (getInstantAppPackageName(callingUid) != null) {
20644            return;
20645        }
20646        // writer
20647        synchronized (mPackages) {
20648            PackageParser.Package pkg = mPackages.get(packageName);
20649            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
20650                if (mContext.checkCallingOrSelfPermission(
20651                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20652                        != PackageManager.PERMISSION_GRANTED) {
20653                    if (getUidTargetSdkVersionLockedLPr(callingUid)
20654                            < Build.VERSION_CODES.FROYO) {
20655                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20656                                + callingUid);
20657                        return;
20658                    }
20659                    mContext.enforceCallingOrSelfPermission(
20660                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20661                }
20662            }
20663            final PackageSetting ps = mSettings.getPackageLPr(packageName);
20664            if (ps != null
20665                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20666                return;
20667            }
20668            int user = UserHandle.getCallingUserId();
20669            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
20670                scheduleWritePackageRestrictionsLocked(user);
20671            }
20672        }
20673    }
20674
20675    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20676    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
20677        ArrayList<PreferredActivity> removed = null;
20678        boolean changed = false;
20679        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20680            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20681            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20682            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20683                continue;
20684            }
20685            Iterator<PreferredActivity> it = pir.filterIterator();
20686            while (it.hasNext()) {
20687                PreferredActivity pa = it.next();
20688                // Mark entry for removal only if it matches the package name
20689                // and the entry is of type "always".
20690                if (packageName == null ||
20691                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20692                                && pa.mPref.mAlways)) {
20693                    if (removed == null) {
20694                        removed = new ArrayList<PreferredActivity>();
20695                    }
20696                    removed.add(pa);
20697                }
20698            }
20699            if (removed != null) {
20700                for (int j=0; j<removed.size(); j++) {
20701                    PreferredActivity pa = removed.get(j);
20702                    pir.removeFilter(pa);
20703                }
20704                changed = true;
20705            }
20706        }
20707        if (changed) {
20708            postPreferredActivityChangedBroadcast(userId);
20709        }
20710        return changed;
20711    }
20712
20713    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20714    private void clearIntentFilterVerificationsLPw(int userId) {
20715        final int packageCount = mPackages.size();
20716        for (int i = 0; i < packageCount; i++) {
20717            PackageParser.Package pkg = mPackages.valueAt(i);
20718            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20719        }
20720    }
20721
20722    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20723    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20724        if (userId == UserHandle.USER_ALL) {
20725            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20726                    sUserManager.getUserIds())) {
20727                for (int oneUserId : sUserManager.getUserIds()) {
20728                    scheduleWritePackageRestrictionsLocked(oneUserId);
20729                }
20730            }
20731        } else {
20732            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20733                scheduleWritePackageRestrictionsLocked(userId);
20734            }
20735        }
20736    }
20737
20738    /** Clears state for all users, and touches intent filter verification policy */
20739    void clearDefaultBrowserIfNeeded(String packageName) {
20740        for (int oneUserId : sUserManager.getUserIds()) {
20741            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20742        }
20743    }
20744
20745    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20746        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20747        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20748            if (packageName.equals(defaultBrowserPackageName)) {
20749                setDefaultBrowserPackageName(null, userId);
20750            }
20751        }
20752    }
20753
20754    @Override
20755    public void resetApplicationPreferences(int userId) {
20756        mContext.enforceCallingOrSelfPermission(
20757                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20758        final long identity = Binder.clearCallingIdentity();
20759        // writer
20760        try {
20761            synchronized (mPackages) {
20762                clearPackagePreferredActivitiesLPw(null, userId);
20763                mSettings.applyDefaultPreferredAppsLPw(this, userId);
20764                // TODO: We have to reset the default SMS and Phone. This requires
20765                // significant refactoring to keep all default apps in the package
20766                // manager (cleaner but more work) or have the services provide
20767                // callbacks to the package manager to request a default app reset.
20768                applyFactoryDefaultBrowserLPw(userId);
20769                clearIntentFilterVerificationsLPw(userId);
20770                primeDomainVerificationsLPw(userId);
20771                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20772                scheduleWritePackageRestrictionsLocked(userId);
20773            }
20774            resetNetworkPolicies(userId);
20775        } finally {
20776            Binder.restoreCallingIdentity(identity);
20777        }
20778    }
20779
20780    @Override
20781    public int getPreferredActivities(List<IntentFilter> outFilters,
20782            List<ComponentName> outActivities, String packageName) {
20783        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20784            return 0;
20785        }
20786        int num = 0;
20787        final int userId = UserHandle.getCallingUserId();
20788        // reader
20789        synchronized (mPackages) {
20790            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20791            if (pir != null) {
20792                final Iterator<PreferredActivity> it = pir.filterIterator();
20793                while (it.hasNext()) {
20794                    final PreferredActivity pa = it.next();
20795                    if (packageName == null
20796                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
20797                                    && pa.mPref.mAlways)) {
20798                        if (outFilters != null) {
20799                            outFilters.add(new IntentFilter(pa));
20800                        }
20801                        if (outActivities != null) {
20802                            outActivities.add(pa.mPref.mComponent);
20803                        }
20804                    }
20805                }
20806            }
20807        }
20808
20809        return num;
20810    }
20811
20812    @Override
20813    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20814            int userId) {
20815        int callingUid = Binder.getCallingUid();
20816        if (callingUid != Process.SYSTEM_UID) {
20817            throw new SecurityException(
20818                    "addPersistentPreferredActivity can only be run by the system");
20819        }
20820        if (filter.countActions() == 0) {
20821            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20822            return;
20823        }
20824        synchronized (mPackages) {
20825            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20826                    ":");
20827            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20828            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20829                    new PersistentPreferredActivity(filter, activity));
20830            scheduleWritePackageRestrictionsLocked(userId);
20831            postPreferredActivityChangedBroadcast(userId);
20832        }
20833    }
20834
20835    @Override
20836    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20837        int callingUid = Binder.getCallingUid();
20838        if (callingUid != Process.SYSTEM_UID) {
20839            throw new SecurityException(
20840                    "clearPackagePersistentPreferredActivities can only be run by the system");
20841        }
20842        ArrayList<PersistentPreferredActivity> removed = null;
20843        boolean changed = false;
20844        synchronized (mPackages) {
20845            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20846                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20847                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20848                        .valueAt(i);
20849                if (userId != thisUserId) {
20850                    continue;
20851                }
20852                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20853                while (it.hasNext()) {
20854                    PersistentPreferredActivity ppa = it.next();
20855                    // Mark entry for removal only if it matches the package name.
20856                    if (ppa.mComponent.getPackageName().equals(packageName)) {
20857                        if (removed == null) {
20858                            removed = new ArrayList<PersistentPreferredActivity>();
20859                        }
20860                        removed.add(ppa);
20861                    }
20862                }
20863                if (removed != null) {
20864                    for (int j=0; j<removed.size(); j++) {
20865                        PersistentPreferredActivity ppa = removed.get(j);
20866                        ppir.removeFilter(ppa);
20867                    }
20868                    changed = true;
20869                }
20870            }
20871
20872            if (changed) {
20873                scheduleWritePackageRestrictionsLocked(userId);
20874                postPreferredActivityChangedBroadcast(userId);
20875            }
20876        }
20877    }
20878
20879    /**
20880     * Common machinery for picking apart a restored XML blob and passing
20881     * it to a caller-supplied functor to be applied to the running system.
20882     */
20883    private void restoreFromXml(XmlPullParser parser, int userId,
20884            String expectedStartTag, BlobXmlRestorer functor)
20885            throws IOException, XmlPullParserException {
20886        int type;
20887        while ((type = parser.next()) != XmlPullParser.START_TAG
20888                && type != XmlPullParser.END_DOCUMENT) {
20889        }
20890        if (type != XmlPullParser.START_TAG) {
20891            // oops didn't find a start tag?!
20892            if (DEBUG_BACKUP) {
20893                Slog.e(TAG, "Didn't find start tag during restore");
20894            }
20895            return;
20896        }
20897Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20898        // this is supposed to be TAG_PREFERRED_BACKUP
20899        if (!expectedStartTag.equals(parser.getName())) {
20900            if (DEBUG_BACKUP) {
20901                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20902            }
20903            return;
20904        }
20905
20906        // skip interfering stuff, then we're aligned with the backing implementation
20907        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20908Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20909        functor.apply(parser, userId);
20910    }
20911
20912    private interface BlobXmlRestorer {
20913        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20914    }
20915
20916    /**
20917     * Non-Binder method, support for the backup/restore mechanism: write the
20918     * full set of preferred activities in its canonical XML format.  Returns the
20919     * XML output as a byte array, or null if there is none.
20920     */
20921    @Override
20922    public byte[] getPreferredActivityBackup(int userId) {
20923        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20924            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20925        }
20926
20927        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20928        try {
20929            final XmlSerializer serializer = new FastXmlSerializer();
20930            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20931            serializer.startDocument(null, true);
20932            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20933
20934            synchronized (mPackages) {
20935                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20936            }
20937
20938            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20939            serializer.endDocument();
20940            serializer.flush();
20941        } catch (Exception e) {
20942            if (DEBUG_BACKUP) {
20943                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20944            }
20945            return null;
20946        }
20947
20948        return dataStream.toByteArray();
20949    }
20950
20951    @Override
20952    public void restorePreferredActivities(byte[] backup, int userId) {
20953        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20954            throw new SecurityException("Only the system may call restorePreferredActivities()");
20955        }
20956
20957        try {
20958            final XmlPullParser parser = Xml.newPullParser();
20959            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20960            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20961                    new BlobXmlRestorer() {
20962                        @Override
20963                        public void apply(XmlPullParser parser, int userId)
20964                                throws XmlPullParserException, IOException {
20965                            synchronized (mPackages) {
20966                                mSettings.readPreferredActivitiesLPw(parser, userId);
20967                            }
20968                        }
20969                    } );
20970        } catch (Exception e) {
20971            if (DEBUG_BACKUP) {
20972                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20973            }
20974        }
20975    }
20976
20977    /**
20978     * Non-Binder method, support for the backup/restore mechanism: write the
20979     * default browser (etc) settings in its canonical XML format.  Returns the default
20980     * browser XML representation as a byte array, or null if there is none.
20981     */
20982    @Override
20983    public byte[] getDefaultAppsBackup(int userId) {
20984        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20985            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20986        }
20987
20988        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20989        try {
20990            final XmlSerializer serializer = new FastXmlSerializer();
20991            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20992            serializer.startDocument(null, true);
20993            serializer.startTag(null, TAG_DEFAULT_APPS);
20994
20995            synchronized (mPackages) {
20996                mSettings.writeDefaultAppsLPr(serializer, userId);
20997            }
20998
20999            serializer.endTag(null, TAG_DEFAULT_APPS);
21000            serializer.endDocument();
21001            serializer.flush();
21002        } catch (Exception e) {
21003            if (DEBUG_BACKUP) {
21004                Slog.e(TAG, "Unable to write default apps for backup", e);
21005            }
21006            return null;
21007        }
21008
21009        return dataStream.toByteArray();
21010    }
21011
21012    @Override
21013    public void restoreDefaultApps(byte[] backup, int userId) {
21014        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21015            throw new SecurityException("Only the system may call restoreDefaultApps()");
21016        }
21017
21018        try {
21019            final XmlPullParser parser = Xml.newPullParser();
21020            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21021            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21022                    new BlobXmlRestorer() {
21023                        @Override
21024                        public void apply(XmlPullParser parser, int userId)
21025                                throws XmlPullParserException, IOException {
21026                            synchronized (mPackages) {
21027                                mSettings.readDefaultAppsLPw(parser, userId);
21028                            }
21029                        }
21030                    } );
21031        } catch (Exception e) {
21032            if (DEBUG_BACKUP) {
21033                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21034            }
21035        }
21036    }
21037
21038    @Override
21039    public byte[] getIntentFilterVerificationBackup(int userId) {
21040        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21041            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21042        }
21043
21044        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21045        try {
21046            final XmlSerializer serializer = new FastXmlSerializer();
21047            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21048            serializer.startDocument(null, true);
21049            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21050
21051            synchronized (mPackages) {
21052                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21053            }
21054
21055            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21056            serializer.endDocument();
21057            serializer.flush();
21058        } catch (Exception e) {
21059            if (DEBUG_BACKUP) {
21060                Slog.e(TAG, "Unable to write default apps for backup", e);
21061            }
21062            return null;
21063        }
21064
21065        return dataStream.toByteArray();
21066    }
21067
21068    @Override
21069    public void restoreIntentFilterVerification(byte[] backup, int userId) {
21070        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21071            throw new SecurityException("Only the system may call restorePreferredActivities()");
21072        }
21073
21074        try {
21075            final XmlPullParser parser = Xml.newPullParser();
21076            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21077            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21078                    new BlobXmlRestorer() {
21079                        @Override
21080                        public void apply(XmlPullParser parser, int userId)
21081                                throws XmlPullParserException, IOException {
21082                            synchronized (mPackages) {
21083                                mSettings.readAllDomainVerificationsLPr(parser, userId);
21084                                mSettings.writeLPr();
21085                            }
21086                        }
21087                    } );
21088        } catch (Exception e) {
21089            if (DEBUG_BACKUP) {
21090                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21091            }
21092        }
21093    }
21094
21095    @Override
21096    public byte[] getPermissionGrantBackup(int userId) {
21097        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21098            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21099        }
21100
21101        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21102        try {
21103            final XmlSerializer serializer = new FastXmlSerializer();
21104            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21105            serializer.startDocument(null, true);
21106            serializer.startTag(null, TAG_PERMISSION_BACKUP);
21107
21108            synchronized (mPackages) {
21109                serializeRuntimePermissionGrantsLPr(serializer, userId);
21110            }
21111
21112            serializer.endTag(null, TAG_PERMISSION_BACKUP);
21113            serializer.endDocument();
21114            serializer.flush();
21115        } catch (Exception e) {
21116            if (DEBUG_BACKUP) {
21117                Slog.e(TAG, "Unable to write default apps for backup", e);
21118            }
21119            return null;
21120        }
21121
21122        return dataStream.toByteArray();
21123    }
21124
21125    @Override
21126    public void restorePermissionGrants(byte[] backup, int userId) {
21127        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21128            throw new SecurityException("Only the system may call restorePermissionGrants()");
21129        }
21130
21131        try {
21132            final XmlPullParser parser = Xml.newPullParser();
21133            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21134            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21135                    new BlobXmlRestorer() {
21136                        @Override
21137                        public void apply(XmlPullParser parser, int userId)
21138                                throws XmlPullParserException, IOException {
21139                            synchronized (mPackages) {
21140                                processRestoredPermissionGrantsLPr(parser, userId);
21141                            }
21142                        }
21143                    } );
21144        } catch (Exception e) {
21145            if (DEBUG_BACKUP) {
21146                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21147            }
21148        }
21149    }
21150
21151    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21152            throws IOException {
21153        serializer.startTag(null, TAG_ALL_GRANTS);
21154
21155        final int N = mSettings.mPackages.size();
21156        for (int i = 0; i < N; i++) {
21157            final PackageSetting ps = mSettings.mPackages.valueAt(i);
21158            boolean pkgGrantsKnown = false;
21159
21160            PermissionsState packagePerms = ps.getPermissionsState();
21161
21162            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21163                final int grantFlags = state.getFlags();
21164                // only look at grants that are not system/policy fixed
21165                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21166                    final boolean isGranted = state.isGranted();
21167                    // And only back up the user-twiddled state bits
21168                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21169                        final String packageName = mSettings.mPackages.keyAt(i);
21170                        if (!pkgGrantsKnown) {
21171                            serializer.startTag(null, TAG_GRANT);
21172                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21173                            pkgGrantsKnown = true;
21174                        }
21175
21176                        final boolean userSet =
21177                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21178                        final boolean userFixed =
21179                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21180                        final boolean revoke =
21181                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21182
21183                        serializer.startTag(null, TAG_PERMISSION);
21184                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21185                        if (isGranted) {
21186                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
21187                        }
21188                        if (userSet) {
21189                            serializer.attribute(null, ATTR_USER_SET, "true");
21190                        }
21191                        if (userFixed) {
21192                            serializer.attribute(null, ATTR_USER_FIXED, "true");
21193                        }
21194                        if (revoke) {
21195                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21196                        }
21197                        serializer.endTag(null, TAG_PERMISSION);
21198                    }
21199                }
21200            }
21201
21202            if (pkgGrantsKnown) {
21203                serializer.endTag(null, TAG_GRANT);
21204            }
21205        }
21206
21207        serializer.endTag(null, TAG_ALL_GRANTS);
21208    }
21209
21210    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21211            throws XmlPullParserException, IOException {
21212        String pkgName = null;
21213        int outerDepth = parser.getDepth();
21214        int type;
21215        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21216                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21217            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21218                continue;
21219            }
21220
21221            final String tagName = parser.getName();
21222            if (tagName.equals(TAG_GRANT)) {
21223                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21224                if (DEBUG_BACKUP) {
21225                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21226                }
21227            } else if (tagName.equals(TAG_PERMISSION)) {
21228
21229                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21230                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21231
21232                int newFlagSet = 0;
21233                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21234                    newFlagSet |= FLAG_PERMISSION_USER_SET;
21235                }
21236                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21237                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21238                }
21239                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21240                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21241                }
21242                if (DEBUG_BACKUP) {
21243                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
21244                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21245                }
21246                final PackageSetting ps = mSettings.mPackages.get(pkgName);
21247                if (ps != null) {
21248                    // Already installed so we apply the grant immediately
21249                    if (DEBUG_BACKUP) {
21250                        Slog.v(TAG, "        + already installed; applying");
21251                    }
21252                    PermissionsState perms = ps.getPermissionsState();
21253                    BasePermission bp = mSettings.mPermissions.get(permName);
21254                    if (bp != null) {
21255                        if (isGranted) {
21256                            perms.grantRuntimePermission(bp, userId);
21257                        }
21258                        if (newFlagSet != 0) {
21259                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21260                        }
21261                    }
21262                } else {
21263                    // Need to wait for post-restore install to apply the grant
21264                    if (DEBUG_BACKUP) {
21265                        Slog.v(TAG, "        - not yet installed; saving for later");
21266                    }
21267                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21268                            isGranted, newFlagSet, userId);
21269                }
21270            } else {
21271                PackageManagerService.reportSettingsProblem(Log.WARN,
21272                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21273                XmlUtils.skipCurrentTag(parser);
21274            }
21275        }
21276
21277        scheduleWriteSettingsLocked();
21278        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21279    }
21280
21281    @Override
21282    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21283            int sourceUserId, int targetUserId, int flags) {
21284        mContext.enforceCallingOrSelfPermission(
21285                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21286        int callingUid = Binder.getCallingUid();
21287        enforceOwnerRights(ownerPackage, callingUid);
21288        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21289        if (intentFilter.countActions() == 0) {
21290            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21291            return;
21292        }
21293        synchronized (mPackages) {
21294            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21295                    ownerPackage, targetUserId, flags);
21296            CrossProfileIntentResolver resolver =
21297                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21298            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21299            // We have all those whose filter is equal. Now checking if the rest is equal as well.
21300            if (existing != null) {
21301                int size = existing.size();
21302                for (int i = 0; i < size; i++) {
21303                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21304                        return;
21305                    }
21306                }
21307            }
21308            resolver.addFilter(newFilter);
21309            scheduleWritePackageRestrictionsLocked(sourceUserId);
21310        }
21311    }
21312
21313    @Override
21314    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21315        mContext.enforceCallingOrSelfPermission(
21316                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21317        final int callingUid = Binder.getCallingUid();
21318        enforceOwnerRights(ownerPackage, callingUid);
21319        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21320        synchronized (mPackages) {
21321            CrossProfileIntentResolver resolver =
21322                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21323            ArraySet<CrossProfileIntentFilter> set =
21324                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21325            for (CrossProfileIntentFilter filter : set) {
21326                if (filter.getOwnerPackage().equals(ownerPackage)) {
21327                    resolver.removeFilter(filter);
21328                }
21329            }
21330            scheduleWritePackageRestrictionsLocked(sourceUserId);
21331        }
21332    }
21333
21334    // Enforcing that callingUid is owning pkg on userId
21335    private void enforceOwnerRights(String pkg, int callingUid) {
21336        // The system owns everything.
21337        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21338            return;
21339        }
21340        final int callingUserId = UserHandle.getUserId(callingUid);
21341        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21342        if (pi == null) {
21343            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21344                    + callingUserId);
21345        }
21346        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21347            throw new SecurityException("Calling uid " + callingUid
21348                    + " does not own package " + pkg);
21349        }
21350    }
21351
21352    @Override
21353    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21354        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21355            return null;
21356        }
21357        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21358    }
21359
21360    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21361        UserManagerService ums = UserManagerService.getInstance();
21362        if (ums != null) {
21363            final UserInfo parent = ums.getProfileParent(userId);
21364            final int launcherUid = (parent != null) ? parent.id : userId;
21365            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21366            if (launcherComponent != null) {
21367                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21368                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21369                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21370                        .setPackage(launcherComponent.getPackageName());
21371                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21372            }
21373        }
21374    }
21375
21376    /**
21377     * Report the 'Home' activity which is currently set as "always use this one". If non is set
21378     * then reports the most likely home activity or null if there are more than one.
21379     */
21380    private ComponentName getDefaultHomeActivity(int userId) {
21381        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21382        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21383        if (cn != null) {
21384            return cn;
21385        }
21386
21387        // Find the launcher with the highest priority and return that component if there are no
21388        // other home activity with the same priority.
21389        int lastPriority = Integer.MIN_VALUE;
21390        ComponentName lastComponent = null;
21391        final int size = allHomeCandidates.size();
21392        for (int i = 0; i < size; i++) {
21393            final ResolveInfo ri = allHomeCandidates.get(i);
21394            if (ri.priority > lastPriority) {
21395                lastComponent = ri.activityInfo.getComponentName();
21396                lastPriority = ri.priority;
21397            } else if (ri.priority == lastPriority) {
21398                // Two components found with same priority.
21399                lastComponent = null;
21400            }
21401        }
21402        return lastComponent;
21403    }
21404
21405    private Intent getHomeIntent() {
21406        Intent intent = new Intent(Intent.ACTION_MAIN);
21407        intent.addCategory(Intent.CATEGORY_HOME);
21408        intent.addCategory(Intent.CATEGORY_DEFAULT);
21409        return intent;
21410    }
21411
21412    private IntentFilter getHomeFilter() {
21413        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21414        filter.addCategory(Intent.CATEGORY_HOME);
21415        filter.addCategory(Intent.CATEGORY_DEFAULT);
21416        return filter;
21417    }
21418
21419    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21420            int userId) {
21421        Intent intent  = getHomeIntent();
21422        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21423                PackageManager.GET_META_DATA, userId);
21424        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21425                true, false, false, userId);
21426
21427        allHomeCandidates.clear();
21428        if (list != null) {
21429            for (ResolveInfo ri : list) {
21430                allHomeCandidates.add(ri);
21431            }
21432        }
21433        return (preferred == null || preferred.activityInfo == null)
21434                ? null
21435                : new ComponentName(preferred.activityInfo.packageName,
21436                        preferred.activityInfo.name);
21437    }
21438
21439    @Override
21440    public void setHomeActivity(ComponentName comp, int userId) {
21441        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21442            return;
21443        }
21444        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21445        getHomeActivitiesAsUser(homeActivities, userId);
21446
21447        boolean found = false;
21448
21449        final int size = homeActivities.size();
21450        final ComponentName[] set = new ComponentName[size];
21451        for (int i = 0; i < size; i++) {
21452            final ResolveInfo candidate = homeActivities.get(i);
21453            final ActivityInfo info = candidate.activityInfo;
21454            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21455            set[i] = activityName;
21456            if (!found && activityName.equals(comp)) {
21457                found = true;
21458            }
21459        }
21460        if (!found) {
21461            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21462                    + userId);
21463        }
21464        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21465                set, comp, userId);
21466    }
21467
21468    private @Nullable String getSetupWizardPackageName() {
21469        final Intent intent = new Intent(Intent.ACTION_MAIN);
21470        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21471
21472        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21473                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21474                        | MATCH_DISABLED_COMPONENTS,
21475                UserHandle.myUserId());
21476        if (matches.size() == 1) {
21477            return matches.get(0).getComponentInfo().packageName;
21478        } else {
21479            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21480                    + ": matches=" + matches);
21481            return null;
21482        }
21483    }
21484
21485    private @Nullable String getStorageManagerPackageName() {
21486        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21487
21488        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21489                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21490                        | MATCH_DISABLED_COMPONENTS,
21491                UserHandle.myUserId());
21492        if (matches.size() == 1) {
21493            return matches.get(0).getComponentInfo().packageName;
21494        } else {
21495            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21496                    + matches.size() + ": matches=" + matches);
21497            return null;
21498        }
21499    }
21500
21501    @Override
21502    public void setApplicationEnabledSetting(String appPackageName,
21503            int newState, int flags, int userId, String callingPackage) {
21504        if (!sUserManager.exists(userId)) return;
21505        if (callingPackage == null) {
21506            callingPackage = Integer.toString(Binder.getCallingUid());
21507        }
21508        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21509    }
21510
21511    @Override
21512    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21513        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21514        synchronized (mPackages) {
21515            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21516            if (pkgSetting != null) {
21517                pkgSetting.setUpdateAvailable(updateAvailable);
21518            }
21519        }
21520    }
21521
21522    @Override
21523    public void setComponentEnabledSetting(ComponentName componentName,
21524            int newState, int flags, int userId) {
21525        if (!sUserManager.exists(userId)) return;
21526        setEnabledSetting(componentName.getPackageName(),
21527                componentName.getClassName(), newState, flags, userId, null);
21528    }
21529
21530    private void setEnabledSetting(final String packageName, String className, int newState,
21531            final int flags, int userId, String callingPackage) {
21532        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21533              || newState == COMPONENT_ENABLED_STATE_ENABLED
21534              || newState == COMPONENT_ENABLED_STATE_DISABLED
21535              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21536              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21537            throw new IllegalArgumentException("Invalid new component state: "
21538                    + newState);
21539        }
21540        PackageSetting pkgSetting;
21541        final int callingUid = Binder.getCallingUid();
21542        final int permission;
21543        if (callingUid == Process.SYSTEM_UID) {
21544            permission = PackageManager.PERMISSION_GRANTED;
21545        } else {
21546            permission = mContext.checkCallingOrSelfPermission(
21547                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21548        }
21549        enforceCrossUserPermission(callingUid, userId,
21550                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21551        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21552        boolean sendNow = false;
21553        boolean isApp = (className == null);
21554        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21555        String componentName = isApp ? packageName : className;
21556        int packageUid = -1;
21557        ArrayList<String> components;
21558
21559        // reader
21560        synchronized (mPackages) {
21561            pkgSetting = mSettings.mPackages.get(packageName);
21562            if (pkgSetting == null) {
21563                if (!isCallerInstantApp) {
21564                    if (className == null) {
21565                        throw new IllegalArgumentException("Unknown package: " + packageName);
21566                    }
21567                    throw new IllegalArgumentException(
21568                            "Unknown component: " + packageName + "/" + className);
21569                } else {
21570                    // throw SecurityException to prevent leaking package information
21571                    throw new SecurityException(
21572                            "Attempt to change component state; "
21573                            + "pid=" + Binder.getCallingPid()
21574                            + ", uid=" + callingUid
21575                            + (className == null
21576                                    ? ", package=" + packageName
21577                                    : ", component=" + packageName + "/" + className));
21578                }
21579            }
21580        }
21581
21582        // Limit who can change which apps
21583        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21584            // Don't allow apps that don't have permission to modify other apps
21585            if (!allowedByPermission
21586                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21587                throw new SecurityException(
21588                        "Attempt to change component state; "
21589                        + "pid=" + Binder.getCallingPid()
21590                        + ", uid=" + callingUid
21591                        + (className == null
21592                                ? ", package=" + packageName
21593                                : ", component=" + packageName + "/" + className));
21594            }
21595            // Don't allow changing protected packages.
21596            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21597                throw new SecurityException("Cannot disable a protected package: " + packageName);
21598            }
21599        }
21600
21601        synchronized (mPackages) {
21602            if (callingUid == Process.SHELL_UID
21603                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21604                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21605                // unless it is a test package.
21606                int oldState = pkgSetting.getEnabled(userId);
21607                if (className == null
21608                    &&
21609                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21610                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21611                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21612                    &&
21613                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21614                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
21615                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21616                    // ok
21617                } else {
21618                    throw new SecurityException(
21619                            "Shell cannot change component state for " + packageName + "/"
21620                            + className + " to " + newState);
21621                }
21622            }
21623            if (className == null) {
21624                // We're dealing with an application/package level state change
21625                if (pkgSetting.getEnabled(userId) == newState) {
21626                    // Nothing to do
21627                    return;
21628                }
21629                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21630                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21631                    // Don't care about who enables an app.
21632                    callingPackage = null;
21633                }
21634                pkgSetting.setEnabled(newState, userId, callingPackage);
21635                // pkgSetting.pkg.mSetEnabled = newState;
21636            } else {
21637                // We're dealing with a component level state change
21638                // First, verify that this is a valid class name.
21639                PackageParser.Package pkg = pkgSetting.pkg;
21640                if (pkg == null || !pkg.hasComponentClassName(className)) {
21641                    if (pkg != null &&
21642                            pkg.applicationInfo.targetSdkVersion >=
21643                                    Build.VERSION_CODES.JELLY_BEAN) {
21644                        throw new IllegalArgumentException("Component class " + className
21645                                + " does not exist in " + packageName);
21646                    } else {
21647                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21648                                + className + " does not exist in " + packageName);
21649                    }
21650                }
21651                switch (newState) {
21652                case COMPONENT_ENABLED_STATE_ENABLED:
21653                    if (!pkgSetting.enableComponentLPw(className, userId)) {
21654                        return;
21655                    }
21656                    break;
21657                case COMPONENT_ENABLED_STATE_DISABLED:
21658                    if (!pkgSetting.disableComponentLPw(className, userId)) {
21659                        return;
21660                    }
21661                    break;
21662                case COMPONENT_ENABLED_STATE_DEFAULT:
21663                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
21664                        return;
21665                    }
21666                    break;
21667                default:
21668                    Slog.e(TAG, "Invalid new component state: " + newState);
21669                    return;
21670                }
21671            }
21672            scheduleWritePackageRestrictionsLocked(userId);
21673            updateSequenceNumberLP(pkgSetting, new int[] { userId });
21674            final long callingId = Binder.clearCallingIdentity();
21675            try {
21676                updateInstantAppInstallerLocked(packageName);
21677            } finally {
21678                Binder.restoreCallingIdentity(callingId);
21679            }
21680            components = mPendingBroadcasts.get(userId, packageName);
21681            final boolean newPackage = components == null;
21682            if (newPackage) {
21683                components = new ArrayList<String>();
21684            }
21685            if (!components.contains(componentName)) {
21686                components.add(componentName);
21687            }
21688            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21689                sendNow = true;
21690                // Purge entry from pending broadcast list if another one exists already
21691                // since we are sending one right away.
21692                mPendingBroadcasts.remove(userId, packageName);
21693            } else {
21694                if (newPackage) {
21695                    mPendingBroadcasts.put(userId, packageName, components);
21696                }
21697                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21698                    // Schedule a message
21699                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21700                }
21701            }
21702        }
21703
21704        long callingId = Binder.clearCallingIdentity();
21705        try {
21706            if (sendNow) {
21707                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21708                sendPackageChangedBroadcast(packageName,
21709                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21710            }
21711        } finally {
21712            Binder.restoreCallingIdentity(callingId);
21713        }
21714    }
21715
21716    @Override
21717    public void flushPackageRestrictionsAsUser(int userId) {
21718        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21719            return;
21720        }
21721        if (!sUserManager.exists(userId)) {
21722            return;
21723        }
21724        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21725                false /* checkShell */, "flushPackageRestrictions");
21726        synchronized (mPackages) {
21727            mSettings.writePackageRestrictionsLPr(userId);
21728            mDirtyUsers.remove(userId);
21729            if (mDirtyUsers.isEmpty()) {
21730                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21731            }
21732        }
21733    }
21734
21735    private void sendPackageChangedBroadcast(String packageName,
21736            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21737        if (DEBUG_INSTALL)
21738            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21739                    + componentNames);
21740        Bundle extras = new Bundle(4);
21741        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21742        String nameList[] = new String[componentNames.size()];
21743        componentNames.toArray(nameList);
21744        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21745        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21746        extras.putInt(Intent.EXTRA_UID, packageUid);
21747        // If this is not reporting a change of the overall package, then only send it
21748        // to registered receivers.  We don't want to launch a swath of apps for every
21749        // little component state change.
21750        final int flags = !componentNames.contains(packageName)
21751                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21752        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21753                new int[] {UserHandle.getUserId(packageUid)});
21754    }
21755
21756    @Override
21757    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21758        if (!sUserManager.exists(userId)) return;
21759        final int callingUid = Binder.getCallingUid();
21760        if (getInstantAppPackageName(callingUid) != null) {
21761            return;
21762        }
21763        final int permission = mContext.checkCallingOrSelfPermission(
21764                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21765        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21766        enforceCrossUserPermission(callingUid, userId,
21767                true /* requireFullPermission */, true /* checkShell */, "stop package");
21768        // writer
21769        synchronized (mPackages) {
21770            final PackageSetting ps = mSettings.mPackages.get(packageName);
21771            if (!filterAppAccessLPr(ps, callingUid, userId)
21772                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21773                            allowedByPermission, callingUid, userId)) {
21774                scheduleWritePackageRestrictionsLocked(userId);
21775            }
21776        }
21777    }
21778
21779    @Override
21780    public String getInstallerPackageName(String packageName) {
21781        final int callingUid = Binder.getCallingUid();
21782        if (getInstantAppPackageName(callingUid) != null) {
21783            return null;
21784        }
21785        // reader
21786        synchronized (mPackages) {
21787            final PackageSetting ps = mSettings.mPackages.get(packageName);
21788            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21789                return null;
21790            }
21791            return mSettings.getInstallerPackageNameLPr(packageName);
21792        }
21793    }
21794
21795    public boolean isOrphaned(String packageName) {
21796        // reader
21797        synchronized (mPackages) {
21798            return mSettings.isOrphaned(packageName);
21799        }
21800    }
21801
21802    @Override
21803    public int getApplicationEnabledSetting(String packageName, int userId) {
21804        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21805        int callingUid = Binder.getCallingUid();
21806        enforceCrossUserPermission(callingUid, userId,
21807                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21808        // reader
21809        synchronized (mPackages) {
21810            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21811                return COMPONENT_ENABLED_STATE_DISABLED;
21812            }
21813            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21814        }
21815    }
21816
21817    @Override
21818    public int getComponentEnabledSetting(ComponentName component, int userId) {
21819        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21820        int callingUid = Binder.getCallingUid();
21821        enforceCrossUserPermission(callingUid, userId,
21822                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21823        synchronized (mPackages) {
21824            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21825                    component, TYPE_UNKNOWN, userId)) {
21826                return COMPONENT_ENABLED_STATE_DISABLED;
21827            }
21828            return mSettings.getComponentEnabledSettingLPr(component, userId);
21829        }
21830    }
21831
21832    @Override
21833    public void enterSafeMode() {
21834        enforceSystemOrRoot("Only the system can request entering safe mode");
21835
21836        if (!mSystemReady) {
21837            mSafeMode = true;
21838        }
21839    }
21840
21841    @Override
21842    public void systemReady() {
21843        enforceSystemOrRoot("Only the system can claim the system is ready");
21844
21845        mSystemReady = true;
21846        final ContentResolver resolver = mContext.getContentResolver();
21847        ContentObserver co = new ContentObserver(mHandler) {
21848            @Override
21849            public void onChange(boolean selfChange) {
21850                mEphemeralAppsDisabled =
21851                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21852                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21853            }
21854        };
21855        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21856                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21857                false, co, UserHandle.USER_SYSTEM);
21858        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21859                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21860        co.onChange(true);
21861
21862        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21863        // disabled after already being started.
21864        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21865                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21866
21867        // Read the compatibilty setting when the system is ready.
21868        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21869                mContext.getContentResolver(),
21870                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21871        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21872        if (DEBUG_SETTINGS) {
21873            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21874        }
21875
21876        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21877
21878        synchronized (mPackages) {
21879            // Verify that all of the preferred activity components actually
21880            // exist.  It is possible for applications to be updated and at
21881            // that point remove a previously declared activity component that
21882            // had been set as a preferred activity.  We try to clean this up
21883            // the next time we encounter that preferred activity, but it is
21884            // possible for the user flow to never be able to return to that
21885            // situation so here we do a sanity check to make sure we haven't
21886            // left any junk around.
21887            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21888            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21889                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21890                removed.clear();
21891                for (PreferredActivity pa : pir.filterSet()) {
21892                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21893                        removed.add(pa);
21894                    }
21895                }
21896                if (removed.size() > 0) {
21897                    for (int r=0; r<removed.size(); r++) {
21898                        PreferredActivity pa = removed.get(r);
21899                        Slog.w(TAG, "Removing dangling preferred activity: "
21900                                + pa.mPref.mComponent);
21901                        pir.removeFilter(pa);
21902                    }
21903                    mSettings.writePackageRestrictionsLPr(
21904                            mSettings.mPreferredActivities.keyAt(i));
21905                }
21906            }
21907
21908            for (int userId : UserManagerService.getInstance().getUserIds()) {
21909                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21910                    grantPermissionsUserIds = ArrayUtils.appendInt(
21911                            grantPermissionsUserIds, userId);
21912                }
21913            }
21914        }
21915        sUserManager.systemReady();
21916
21917        // If we upgraded grant all default permissions before kicking off.
21918        for (int userId : grantPermissionsUserIds) {
21919            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21920        }
21921
21922        // If we did not grant default permissions, we preload from this the
21923        // default permission exceptions lazily to ensure we don't hit the
21924        // disk on a new user creation.
21925        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21926            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21927        }
21928
21929        // Kick off any messages waiting for system ready
21930        if (mPostSystemReadyMessages != null) {
21931            for (Message msg : mPostSystemReadyMessages) {
21932                msg.sendToTarget();
21933            }
21934            mPostSystemReadyMessages = null;
21935        }
21936
21937        // Watch for external volumes that come and go over time
21938        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21939        storage.registerListener(mStorageListener);
21940
21941        mInstallerService.systemReady();
21942        mPackageDexOptimizer.systemReady();
21943
21944        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21945                StorageManagerInternal.class);
21946        StorageManagerInternal.addExternalStoragePolicy(
21947                new StorageManagerInternal.ExternalStorageMountPolicy() {
21948            @Override
21949            public int getMountMode(int uid, String packageName) {
21950                if (Process.isIsolated(uid)) {
21951                    return Zygote.MOUNT_EXTERNAL_NONE;
21952                }
21953                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
21954                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21955                }
21956                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21957                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21958                }
21959                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21960                    return Zygote.MOUNT_EXTERNAL_READ;
21961                }
21962                return Zygote.MOUNT_EXTERNAL_WRITE;
21963            }
21964
21965            @Override
21966            public boolean hasExternalStorage(int uid, String packageName) {
21967                return true;
21968            }
21969        });
21970
21971        // Now that we're mostly running, clean up stale users and apps
21972        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21973        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21974
21975        if (mPrivappPermissionsViolations != null) {
21976            Slog.wtf(TAG,"Signature|privileged permissions not in "
21977                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21978            mPrivappPermissionsViolations = null;
21979        }
21980    }
21981
21982    public void waitForAppDataPrepared() {
21983        if (mPrepareAppDataFuture == null) {
21984            return;
21985        }
21986        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21987        mPrepareAppDataFuture = null;
21988    }
21989
21990    @Override
21991    public boolean isSafeMode() {
21992        // allow instant applications
21993        return mSafeMode;
21994    }
21995
21996    @Override
21997    public boolean hasSystemUidErrors() {
21998        // allow instant applications
21999        return mHasSystemUidErrors;
22000    }
22001
22002    static String arrayToString(int[] array) {
22003        StringBuffer buf = new StringBuffer(128);
22004        buf.append('[');
22005        if (array != null) {
22006            for (int i=0; i<array.length; i++) {
22007                if (i > 0) buf.append(", ");
22008                buf.append(array[i]);
22009            }
22010        }
22011        buf.append(']');
22012        return buf.toString();
22013    }
22014
22015    static class DumpState {
22016        public static final int DUMP_LIBS = 1 << 0;
22017        public static final int DUMP_FEATURES = 1 << 1;
22018        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
22019        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
22020        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22021        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22022        public static final int DUMP_PERMISSIONS = 1 << 6;
22023        public static final int DUMP_PACKAGES = 1 << 7;
22024        public static final int DUMP_SHARED_USERS = 1 << 8;
22025        public static final int DUMP_MESSAGES = 1 << 9;
22026        public static final int DUMP_PROVIDERS = 1 << 10;
22027        public static final int DUMP_VERIFIERS = 1 << 11;
22028        public static final int DUMP_PREFERRED = 1 << 12;
22029        public static final int DUMP_PREFERRED_XML = 1 << 13;
22030        public static final int DUMP_KEYSETS = 1 << 14;
22031        public static final int DUMP_VERSION = 1 << 15;
22032        public static final int DUMP_INSTALLS = 1 << 16;
22033        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22034        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22035        public static final int DUMP_FROZEN = 1 << 19;
22036        public static final int DUMP_DEXOPT = 1 << 20;
22037        public static final int DUMP_COMPILER_STATS = 1 << 21;
22038        public static final int DUMP_CHANGES = 1 << 22;
22039        public static final int DUMP_VOLUMES = 1 << 23;
22040
22041        public static final int OPTION_SHOW_FILTERS = 1 << 0;
22042
22043        private int mTypes;
22044
22045        private int mOptions;
22046
22047        private boolean mTitlePrinted;
22048
22049        private SharedUserSetting mSharedUser;
22050
22051        public boolean isDumping(int type) {
22052            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22053                return true;
22054            }
22055
22056            return (mTypes & type) != 0;
22057        }
22058
22059        public void setDump(int type) {
22060            mTypes |= type;
22061        }
22062
22063        public boolean isOptionEnabled(int option) {
22064            return (mOptions & option) != 0;
22065        }
22066
22067        public void setOptionEnabled(int option) {
22068            mOptions |= option;
22069        }
22070
22071        public boolean onTitlePrinted() {
22072            final boolean printed = mTitlePrinted;
22073            mTitlePrinted = true;
22074            return printed;
22075        }
22076
22077        public boolean getTitlePrinted() {
22078            return mTitlePrinted;
22079        }
22080
22081        public void setTitlePrinted(boolean enabled) {
22082            mTitlePrinted = enabled;
22083        }
22084
22085        public SharedUserSetting getSharedUser() {
22086            return mSharedUser;
22087        }
22088
22089        public void setSharedUser(SharedUserSetting user) {
22090            mSharedUser = user;
22091        }
22092    }
22093
22094    @Override
22095    public void onShellCommand(FileDescriptor in, FileDescriptor out,
22096            FileDescriptor err, String[] args, ShellCallback callback,
22097            ResultReceiver resultReceiver) {
22098        (new PackageManagerShellCommand(this)).exec(
22099                this, in, out, err, args, callback, resultReceiver);
22100    }
22101
22102    @Override
22103    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22104        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22105
22106        DumpState dumpState = new DumpState();
22107        boolean fullPreferred = false;
22108        boolean checkin = false;
22109
22110        String packageName = null;
22111        ArraySet<String> permissionNames = null;
22112
22113        int opti = 0;
22114        while (opti < args.length) {
22115            String opt = args[opti];
22116            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22117                break;
22118            }
22119            opti++;
22120
22121            if ("-a".equals(opt)) {
22122                // Right now we only know how to print all.
22123            } else if ("-h".equals(opt)) {
22124                pw.println("Package manager dump options:");
22125                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
22126                pw.println("    --checkin: dump for a checkin");
22127                pw.println("    -f: print details of intent filters");
22128                pw.println("    -h: print this help");
22129                pw.println("  cmd may be one of:");
22130                pw.println("    l[ibraries]: list known shared libraries");
22131                pw.println("    f[eatures]: list device features");
22132                pw.println("    k[eysets]: print known keysets");
22133                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22134                pw.println("    perm[issions]: dump permissions");
22135                pw.println("    permission [name ...]: dump declaration and use of given permission");
22136                pw.println("    pref[erred]: print preferred package settings");
22137                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
22138                pw.println("    prov[iders]: dump content providers");
22139                pw.println("    p[ackages]: dump installed packages");
22140                pw.println("    s[hared-users]: dump shared user IDs");
22141                pw.println("    m[essages]: print collected runtime messages");
22142                pw.println("    v[erifiers]: print package verifier info");
22143                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
22144                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22145                pw.println("    version: print database version info");
22146                pw.println("    write: write current settings now");
22147                pw.println("    installs: details about install sessions");
22148                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
22149                pw.println("    dexopt: dump dexopt state");
22150                pw.println("    compiler-stats: dump compiler statistics");
22151                pw.println("    enabled-overlays: dump list of enabled overlay packages");
22152                pw.println("    <package.name>: info about given package");
22153                return;
22154            } else if ("--checkin".equals(opt)) {
22155                checkin = true;
22156            } else if ("-f".equals(opt)) {
22157                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22158            } else if ("--proto".equals(opt)) {
22159                dumpProto(fd);
22160                return;
22161            } else {
22162                pw.println("Unknown argument: " + opt + "; use -h for help");
22163            }
22164        }
22165
22166        // Is the caller requesting to dump a particular piece of data?
22167        if (opti < args.length) {
22168            String cmd = args[opti];
22169            opti++;
22170            // Is this a package name?
22171            if ("android".equals(cmd) || cmd.contains(".")) {
22172                packageName = cmd;
22173                // When dumping a single package, we always dump all of its
22174                // filter information since the amount of data will be reasonable.
22175                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22176            } else if ("check-permission".equals(cmd)) {
22177                if (opti >= args.length) {
22178                    pw.println("Error: check-permission missing permission argument");
22179                    return;
22180                }
22181                String perm = args[opti];
22182                opti++;
22183                if (opti >= args.length) {
22184                    pw.println("Error: check-permission missing package argument");
22185                    return;
22186                }
22187
22188                String pkg = args[opti];
22189                opti++;
22190                int user = UserHandle.getUserId(Binder.getCallingUid());
22191                if (opti < args.length) {
22192                    try {
22193                        user = Integer.parseInt(args[opti]);
22194                    } catch (NumberFormatException e) {
22195                        pw.println("Error: check-permission user argument is not a number: "
22196                                + args[opti]);
22197                        return;
22198                    }
22199                }
22200
22201                // Normalize package name to handle renamed packages and static libs
22202                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22203
22204                pw.println(checkPermission(perm, pkg, user));
22205                return;
22206            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22207                dumpState.setDump(DumpState.DUMP_LIBS);
22208            } else if ("f".equals(cmd) || "features".equals(cmd)) {
22209                dumpState.setDump(DumpState.DUMP_FEATURES);
22210            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22211                if (opti >= args.length) {
22212                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22213                            | DumpState.DUMP_SERVICE_RESOLVERS
22214                            | DumpState.DUMP_RECEIVER_RESOLVERS
22215                            | DumpState.DUMP_CONTENT_RESOLVERS);
22216                } else {
22217                    while (opti < args.length) {
22218                        String name = args[opti];
22219                        if ("a".equals(name) || "activity".equals(name)) {
22220                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22221                        } else if ("s".equals(name) || "service".equals(name)) {
22222                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22223                        } else if ("r".equals(name) || "receiver".equals(name)) {
22224                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22225                        } else if ("c".equals(name) || "content".equals(name)) {
22226                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22227                        } else {
22228                            pw.println("Error: unknown resolver table type: " + name);
22229                            return;
22230                        }
22231                        opti++;
22232                    }
22233                }
22234            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22235                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22236            } else if ("permission".equals(cmd)) {
22237                if (opti >= args.length) {
22238                    pw.println("Error: permission requires permission name");
22239                    return;
22240                }
22241                permissionNames = new ArraySet<>();
22242                while (opti < args.length) {
22243                    permissionNames.add(args[opti]);
22244                    opti++;
22245                }
22246                dumpState.setDump(DumpState.DUMP_PERMISSIONS
22247                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22248            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22249                dumpState.setDump(DumpState.DUMP_PREFERRED);
22250            } else if ("preferred-xml".equals(cmd)) {
22251                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22252                if (opti < args.length && "--full".equals(args[opti])) {
22253                    fullPreferred = true;
22254                    opti++;
22255                }
22256            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22257                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22258            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22259                dumpState.setDump(DumpState.DUMP_PACKAGES);
22260            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22261                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22262            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22263                dumpState.setDump(DumpState.DUMP_PROVIDERS);
22264            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22265                dumpState.setDump(DumpState.DUMP_MESSAGES);
22266            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22267                dumpState.setDump(DumpState.DUMP_VERIFIERS);
22268            } else if ("i".equals(cmd) || "ifv".equals(cmd)
22269                    || "intent-filter-verifiers".equals(cmd)) {
22270                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22271            } else if ("version".equals(cmd)) {
22272                dumpState.setDump(DumpState.DUMP_VERSION);
22273            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22274                dumpState.setDump(DumpState.DUMP_KEYSETS);
22275            } else if ("installs".equals(cmd)) {
22276                dumpState.setDump(DumpState.DUMP_INSTALLS);
22277            } else if ("frozen".equals(cmd)) {
22278                dumpState.setDump(DumpState.DUMP_FROZEN);
22279            } else if ("volumes".equals(cmd)) {
22280                dumpState.setDump(DumpState.DUMP_VOLUMES);
22281            } else if ("dexopt".equals(cmd)) {
22282                dumpState.setDump(DumpState.DUMP_DEXOPT);
22283            } else if ("compiler-stats".equals(cmd)) {
22284                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22285            } else if ("changes".equals(cmd)) {
22286                dumpState.setDump(DumpState.DUMP_CHANGES);
22287            } else if ("write".equals(cmd)) {
22288                synchronized (mPackages) {
22289                    mSettings.writeLPr();
22290                    pw.println("Settings written.");
22291                    return;
22292                }
22293            }
22294        }
22295
22296        if (checkin) {
22297            pw.println("vers,1");
22298        }
22299
22300        // reader
22301        synchronized (mPackages) {
22302            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22303                if (!checkin) {
22304                    if (dumpState.onTitlePrinted())
22305                        pw.println();
22306                    pw.println("Database versions:");
22307                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22308                }
22309            }
22310
22311            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22312                if (!checkin) {
22313                    if (dumpState.onTitlePrinted())
22314                        pw.println();
22315                    pw.println("Verifiers:");
22316                    pw.print("  Required: ");
22317                    pw.print(mRequiredVerifierPackage);
22318                    pw.print(" (uid=");
22319                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22320                            UserHandle.USER_SYSTEM));
22321                    pw.println(")");
22322                } else if (mRequiredVerifierPackage != null) {
22323                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22324                    pw.print(",");
22325                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22326                            UserHandle.USER_SYSTEM));
22327                }
22328            }
22329
22330            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22331                    packageName == null) {
22332                if (mIntentFilterVerifierComponent != null) {
22333                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22334                    if (!checkin) {
22335                        if (dumpState.onTitlePrinted())
22336                            pw.println();
22337                        pw.println("Intent Filter Verifier:");
22338                        pw.print("  Using: ");
22339                        pw.print(verifierPackageName);
22340                        pw.print(" (uid=");
22341                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22342                                UserHandle.USER_SYSTEM));
22343                        pw.println(")");
22344                    } else if (verifierPackageName != null) {
22345                        pw.print("ifv,"); pw.print(verifierPackageName);
22346                        pw.print(",");
22347                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22348                                UserHandle.USER_SYSTEM));
22349                    }
22350                } else {
22351                    pw.println();
22352                    pw.println("No Intent Filter Verifier available!");
22353                }
22354            }
22355
22356            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22357                boolean printedHeader = false;
22358                final Iterator<String> it = mSharedLibraries.keySet().iterator();
22359                while (it.hasNext()) {
22360                    String libName = it.next();
22361                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22362                    if (versionedLib == null) {
22363                        continue;
22364                    }
22365                    final int versionCount = versionedLib.size();
22366                    for (int i = 0; i < versionCount; i++) {
22367                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22368                        if (!checkin) {
22369                            if (!printedHeader) {
22370                                if (dumpState.onTitlePrinted())
22371                                    pw.println();
22372                                pw.println("Libraries:");
22373                                printedHeader = true;
22374                            }
22375                            pw.print("  ");
22376                        } else {
22377                            pw.print("lib,");
22378                        }
22379                        pw.print(libEntry.info.getName());
22380                        if (libEntry.info.isStatic()) {
22381                            pw.print(" version=" + libEntry.info.getVersion());
22382                        }
22383                        if (!checkin) {
22384                            pw.print(" -> ");
22385                        }
22386                        if (libEntry.path != null) {
22387                            pw.print(" (jar) ");
22388                            pw.print(libEntry.path);
22389                        } else {
22390                            pw.print(" (apk) ");
22391                            pw.print(libEntry.apk);
22392                        }
22393                        pw.println();
22394                    }
22395                }
22396            }
22397
22398            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22399                if (dumpState.onTitlePrinted())
22400                    pw.println();
22401                if (!checkin) {
22402                    pw.println("Features:");
22403                }
22404
22405                synchronized (mAvailableFeatures) {
22406                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22407                        if (checkin) {
22408                            pw.print("feat,");
22409                            pw.print(feat.name);
22410                            pw.print(",");
22411                            pw.println(feat.version);
22412                        } else {
22413                            pw.print("  ");
22414                            pw.print(feat.name);
22415                            if (feat.version > 0) {
22416                                pw.print(" version=");
22417                                pw.print(feat.version);
22418                            }
22419                            pw.println();
22420                        }
22421                    }
22422                }
22423            }
22424
22425            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22426                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22427                        : "Activity Resolver Table:", "  ", packageName,
22428                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22429                    dumpState.setTitlePrinted(true);
22430                }
22431            }
22432            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22433                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22434                        : "Receiver Resolver Table:", "  ", packageName,
22435                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22436                    dumpState.setTitlePrinted(true);
22437                }
22438            }
22439            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22440                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22441                        : "Service Resolver Table:", "  ", packageName,
22442                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22443                    dumpState.setTitlePrinted(true);
22444                }
22445            }
22446            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22447                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22448                        : "Provider Resolver Table:", "  ", packageName,
22449                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22450                    dumpState.setTitlePrinted(true);
22451                }
22452            }
22453
22454            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22455                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22456                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22457                    int user = mSettings.mPreferredActivities.keyAt(i);
22458                    if (pir.dump(pw,
22459                            dumpState.getTitlePrinted()
22460                                ? "\nPreferred Activities User " + user + ":"
22461                                : "Preferred Activities User " + user + ":", "  ",
22462                            packageName, true, false)) {
22463                        dumpState.setTitlePrinted(true);
22464                    }
22465                }
22466            }
22467
22468            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22469                pw.flush();
22470                FileOutputStream fout = new FileOutputStream(fd);
22471                BufferedOutputStream str = new BufferedOutputStream(fout);
22472                XmlSerializer serializer = new FastXmlSerializer();
22473                try {
22474                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22475                    serializer.startDocument(null, true);
22476                    serializer.setFeature(
22477                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22478                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22479                    serializer.endDocument();
22480                    serializer.flush();
22481                } catch (IllegalArgumentException e) {
22482                    pw.println("Failed writing: " + e);
22483                } catch (IllegalStateException e) {
22484                    pw.println("Failed writing: " + e);
22485                } catch (IOException e) {
22486                    pw.println("Failed writing: " + e);
22487                }
22488            }
22489
22490            if (!checkin
22491                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22492                    && packageName == null) {
22493                pw.println();
22494                int count = mSettings.mPackages.size();
22495                if (count == 0) {
22496                    pw.println("No applications!");
22497                    pw.println();
22498                } else {
22499                    final String prefix = "  ";
22500                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22501                    if (allPackageSettings.size() == 0) {
22502                        pw.println("No domain preferred apps!");
22503                        pw.println();
22504                    } else {
22505                        pw.println("App verification status:");
22506                        pw.println();
22507                        count = 0;
22508                        for (PackageSetting ps : allPackageSettings) {
22509                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22510                            if (ivi == null || ivi.getPackageName() == null) continue;
22511                            pw.println(prefix + "Package: " + ivi.getPackageName());
22512                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
22513                            pw.println(prefix + "Status:  " + ivi.getStatusString());
22514                            pw.println();
22515                            count++;
22516                        }
22517                        if (count == 0) {
22518                            pw.println(prefix + "No app verification established.");
22519                            pw.println();
22520                        }
22521                        for (int userId : sUserManager.getUserIds()) {
22522                            pw.println("App linkages for user " + userId + ":");
22523                            pw.println();
22524                            count = 0;
22525                            for (PackageSetting ps : allPackageSettings) {
22526                                final long status = ps.getDomainVerificationStatusForUser(userId);
22527                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22528                                        && !DEBUG_DOMAIN_VERIFICATION) {
22529                                    continue;
22530                                }
22531                                pw.println(prefix + "Package: " + ps.name);
22532                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22533                                String statusStr = IntentFilterVerificationInfo.
22534                                        getStatusStringFromValue(status);
22535                                pw.println(prefix + "Status:  " + statusStr);
22536                                pw.println();
22537                                count++;
22538                            }
22539                            if (count == 0) {
22540                                pw.println(prefix + "No configured app linkages.");
22541                                pw.println();
22542                            }
22543                        }
22544                    }
22545                }
22546            }
22547
22548            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22549                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22550                if (packageName == null && permissionNames == null) {
22551                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
22552                        if (iperm == 0) {
22553                            if (dumpState.onTitlePrinted())
22554                                pw.println();
22555                            pw.println("AppOp Permissions:");
22556                        }
22557                        pw.print("  AppOp Permission ");
22558                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
22559                        pw.println(":");
22560                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
22561                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
22562                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
22563                        }
22564                    }
22565                }
22566            }
22567
22568            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22569                boolean printedSomething = false;
22570                for (PackageParser.Provider p : mProviders.mProviders.values()) {
22571                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22572                        continue;
22573                    }
22574                    if (!printedSomething) {
22575                        if (dumpState.onTitlePrinted())
22576                            pw.println();
22577                        pw.println("Registered ContentProviders:");
22578                        printedSomething = true;
22579                    }
22580                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
22581                    pw.print("    "); pw.println(p.toString());
22582                }
22583                printedSomething = false;
22584                for (Map.Entry<String, PackageParser.Provider> entry :
22585                        mProvidersByAuthority.entrySet()) {
22586                    PackageParser.Provider p = entry.getValue();
22587                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22588                        continue;
22589                    }
22590                    if (!printedSomething) {
22591                        if (dumpState.onTitlePrinted())
22592                            pw.println();
22593                        pw.println("ContentProvider Authorities:");
22594                        printedSomething = true;
22595                    }
22596                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
22597                    pw.print("    "); pw.println(p.toString());
22598                    if (p.info != null && p.info.applicationInfo != null) {
22599                        final String appInfo = p.info.applicationInfo.toString();
22600                        pw.print("      applicationInfo="); pw.println(appInfo);
22601                    }
22602                }
22603            }
22604
22605            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22606                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22607            }
22608
22609            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22610                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22611            }
22612
22613            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22614                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22615            }
22616
22617            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22618                if (dumpState.onTitlePrinted()) pw.println();
22619                pw.println("Package Changes:");
22620                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22621                final int K = mChangedPackages.size();
22622                for (int i = 0; i < K; i++) {
22623                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
22624                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22625                    final int N = changes.size();
22626                    if (N == 0) {
22627                        pw.print("    "); pw.println("No packages changed");
22628                    } else {
22629                        for (int j = 0; j < N; j++) {
22630                            final String pkgName = changes.valueAt(j);
22631                            final int sequenceNumber = changes.keyAt(j);
22632                            pw.print("    ");
22633                            pw.print("seq=");
22634                            pw.print(sequenceNumber);
22635                            pw.print(", package=");
22636                            pw.println(pkgName);
22637                        }
22638                    }
22639                }
22640            }
22641
22642            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
22643                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
22644            }
22645
22646            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
22647                // XXX should handle packageName != null by dumping only install data that
22648                // the given package is involved with.
22649                if (dumpState.onTitlePrinted()) pw.println();
22650
22651                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22652                ipw.println();
22653                ipw.println("Frozen packages:");
22654                ipw.increaseIndent();
22655                if (mFrozenPackages.size() == 0) {
22656                    ipw.println("(none)");
22657                } else {
22658                    for (int i = 0; i < mFrozenPackages.size(); i++) {
22659                        ipw.println(mFrozenPackages.valueAt(i));
22660                    }
22661                }
22662                ipw.decreaseIndent();
22663            }
22664
22665            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
22666                if (dumpState.onTitlePrinted()) pw.println();
22667
22668                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22669                ipw.println();
22670                ipw.println("Loaded volumes:");
22671                ipw.increaseIndent();
22672                if (mLoadedVolumes.size() == 0) {
22673                    ipw.println("(none)");
22674                } else {
22675                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
22676                        ipw.println(mLoadedVolumes.valueAt(i));
22677                    }
22678                }
22679                ipw.decreaseIndent();
22680            }
22681
22682            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22683                if (dumpState.onTitlePrinted()) pw.println();
22684                dumpDexoptStateLPr(pw, packageName);
22685            }
22686
22687            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22688                if (dumpState.onTitlePrinted()) pw.println();
22689                dumpCompilerStatsLPr(pw, packageName);
22690            }
22691
22692            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22693                if (dumpState.onTitlePrinted()) pw.println();
22694                mSettings.dumpReadMessagesLPr(pw, dumpState);
22695
22696                pw.println();
22697                pw.println("Package warning messages:");
22698                BufferedReader in = null;
22699                String line = null;
22700                try {
22701                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22702                    while ((line = in.readLine()) != null) {
22703                        if (line.contains("ignored: updated version")) continue;
22704                        pw.println(line);
22705                    }
22706                } catch (IOException ignored) {
22707                } finally {
22708                    IoUtils.closeQuietly(in);
22709                }
22710            }
22711
22712            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22713                BufferedReader in = null;
22714                String line = null;
22715                try {
22716                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22717                    while ((line = in.readLine()) != null) {
22718                        if (line.contains("ignored: updated version")) continue;
22719                        pw.print("msg,");
22720                        pw.println(line);
22721                    }
22722                } catch (IOException ignored) {
22723                } finally {
22724                    IoUtils.closeQuietly(in);
22725                }
22726            }
22727        }
22728
22729        // PackageInstaller should be called outside of mPackages lock
22730        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22731            // XXX should handle packageName != null by dumping only install data that
22732            // the given package is involved with.
22733            if (dumpState.onTitlePrinted()) pw.println();
22734            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
22735        }
22736    }
22737
22738    private void dumpProto(FileDescriptor fd) {
22739        final ProtoOutputStream proto = new ProtoOutputStream(fd);
22740
22741        synchronized (mPackages) {
22742            final long requiredVerifierPackageToken =
22743                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22744            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22745            proto.write(
22746                    PackageServiceDumpProto.PackageShortProto.UID,
22747                    getPackageUid(
22748                            mRequiredVerifierPackage,
22749                            MATCH_DEBUG_TRIAGED_MISSING,
22750                            UserHandle.USER_SYSTEM));
22751            proto.end(requiredVerifierPackageToken);
22752
22753            if (mIntentFilterVerifierComponent != null) {
22754                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22755                final long verifierPackageToken =
22756                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22757                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22758                proto.write(
22759                        PackageServiceDumpProto.PackageShortProto.UID,
22760                        getPackageUid(
22761                                verifierPackageName,
22762                                MATCH_DEBUG_TRIAGED_MISSING,
22763                                UserHandle.USER_SYSTEM));
22764                proto.end(verifierPackageToken);
22765            }
22766
22767            dumpSharedLibrariesProto(proto);
22768            dumpFeaturesProto(proto);
22769            mSettings.dumpPackagesProto(proto);
22770            mSettings.dumpSharedUsersProto(proto);
22771            dumpMessagesProto(proto);
22772        }
22773        proto.flush();
22774    }
22775
22776    private void dumpMessagesProto(ProtoOutputStream proto) {
22777        BufferedReader in = null;
22778        String line = null;
22779        try {
22780            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22781            while ((line = in.readLine()) != null) {
22782                if (line.contains("ignored: updated version")) continue;
22783                proto.write(PackageServiceDumpProto.MESSAGES, line);
22784            }
22785        } catch (IOException ignored) {
22786        } finally {
22787            IoUtils.closeQuietly(in);
22788        }
22789    }
22790
22791    private void dumpFeaturesProto(ProtoOutputStream proto) {
22792        synchronized (mAvailableFeatures) {
22793            final int count = mAvailableFeatures.size();
22794            for (int i = 0; i < count; i++) {
22795                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
22796                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
22797                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
22798                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
22799                proto.end(featureToken);
22800            }
22801        }
22802    }
22803
22804    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22805        final int count = mSharedLibraries.size();
22806        for (int i = 0; i < count; i++) {
22807            final String libName = mSharedLibraries.keyAt(i);
22808            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22809            if (versionedLib == null) {
22810                continue;
22811            }
22812            final int versionCount = versionedLib.size();
22813            for (int j = 0; j < versionCount; j++) {
22814                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22815                final long sharedLibraryToken =
22816                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22817                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22818                final boolean isJar = (libEntry.path != null);
22819                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22820                if (isJar) {
22821                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22822                } else {
22823                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22824                }
22825                proto.end(sharedLibraryToken);
22826            }
22827        }
22828    }
22829
22830    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22831        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22832        ipw.println();
22833        ipw.println("Dexopt state:");
22834        ipw.increaseIndent();
22835        Collection<PackageParser.Package> packages = null;
22836        if (packageName != null) {
22837            PackageParser.Package targetPackage = mPackages.get(packageName);
22838            if (targetPackage != null) {
22839                packages = Collections.singletonList(targetPackage);
22840            } else {
22841                ipw.println("Unable to find package: " + packageName);
22842                return;
22843            }
22844        } else {
22845            packages = mPackages.values();
22846        }
22847
22848        for (PackageParser.Package pkg : packages) {
22849            ipw.println("[" + pkg.packageName + "]");
22850            ipw.increaseIndent();
22851            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
22852            ipw.decreaseIndent();
22853        }
22854    }
22855
22856    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22857        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22858        ipw.println();
22859        ipw.println("Compiler stats:");
22860        ipw.increaseIndent();
22861        Collection<PackageParser.Package> packages = null;
22862        if (packageName != null) {
22863            PackageParser.Package targetPackage = mPackages.get(packageName);
22864            if (targetPackage != null) {
22865                packages = Collections.singletonList(targetPackage);
22866            } else {
22867                ipw.println("Unable to find package: " + packageName);
22868                return;
22869            }
22870        } else {
22871            packages = mPackages.values();
22872        }
22873
22874        for (PackageParser.Package pkg : packages) {
22875            ipw.println("[" + pkg.packageName + "]");
22876            ipw.increaseIndent();
22877
22878            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22879            if (stats == null) {
22880                ipw.println("(No recorded stats)");
22881            } else {
22882                stats.dump(ipw);
22883            }
22884            ipw.decreaseIndent();
22885        }
22886    }
22887
22888    private String dumpDomainString(String packageName) {
22889        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22890                .getList();
22891        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22892
22893        ArraySet<String> result = new ArraySet<>();
22894        if (iviList.size() > 0) {
22895            for (IntentFilterVerificationInfo ivi : iviList) {
22896                for (String host : ivi.getDomains()) {
22897                    result.add(host);
22898                }
22899            }
22900        }
22901        if (filters != null && filters.size() > 0) {
22902            for (IntentFilter filter : filters) {
22903                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22904                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22905                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22906                    result.addAll(filter.getHostsList());
22907                }
22908            }
22909        }
22910
22911        StringBuilder sb = new StringBuilder(result.size() * 16);
22912        for (String domain : result) {
22913            if (sb.length() > 0) sb.append(" ");
22914            sb.append(domain);
22915        }
22916        return sb.toString();
22917    }
22918
22919    // ------- apps on sdcard specific code -------
22920    static final boolean DEBUG_SD_INSTALL = false;
22921
22922    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22923
22924    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22925
22926    private boolean mMediaMounted = false;
22927
22928    static String getEncryptKey() {
22929        try {
22930            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22931                    SD_ENCRYPTION_KEYSTORE_NAME);
22932            if (sdEncKey == null) {
22933                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22934                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22935                if (sdEncKey == null) {
22936                    Slog.e(TAG, "Failed to create encryption keys");
22937                    return null;
22938                }
22939            }
22940            return sdEncKey;
22941        } catch (NoSuchAlgorithmException nsae) {
22942            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22943            return null;
22944        } catch (IOException ioe) {
22945            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22946            return null;
22947        }
22948    }
22949
22950    /*
22951     * Update media status on PackageManager.
22952     */
22953    @Override
22954    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
22955        enforceSystemOrRoot("Media status can only be updated by the system");
22956        // reader; this apparently protects mMediaMounted, but should probably
22957        // be a different lock in that case.
22958        synchronized (mPackages) {
22959            Log.i(TAG, "Updating external media status from "
22960                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
22961                    + (mediaStatus ? "mounted" : "unmounted"));
22962            if (DEBUG_SD_INSTALL)
22963                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
22964                        + ", mMediaMounted=" + mMediaMounted);
22965            if (mediaStatus == mMediaMounted) {
22966                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
22967                        : 0, -1);
22968                mHandler.sendMessage(msg);
22969                return;
22970            }
22971            mMediaMounted = mediaStatus;
22972        }
22973        // Queue up an async operation since the package installation may take a
22974        // little while.
22975        mHandler.post(new Runnable() {
22976            public void run() {
22977                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
22978            }
22979        });
22980    }
22981
22982    /**
22983     * Called by StorageManagerService when the initial ASECs to scan are available.
22984     * Should block until all the ASEC containers are finished being scanned.
22985     */
22986    public void scanAvailableAsecs() {
22987        updateExternalMediaStatusInner(true, false, false);
22988    }
22989
22990    /*
22991     * Collect information of applications on external media, map them against
22992     * existing containers and update information based on current mount status.
22993     * Please note that we always have to report status if reportStatus has been
22994     * set to true especially when unloading packages.
22995     */
22996    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
22997            boolean externalStorage) {
22998        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
22999        int[] uidArr = EmptyArray.INT;
23000
23001        final String[] list = PackageHelper.getSecureContainerList();
23002        if (ArrayUtils.isEmpty(list)) {
23003            Log.i(TAG, "No secure containers found");
23004        } else {
23005            // Process list of secure containers and categorize them
23006            // as active or stale based on their package internal state.
23007
23008            // reader
23009            synchronized (mPackages) {
23010                for (String cid : list) {
23011                    // Leave stages untouched for now; installer service owns them
23012                    if (PackageInstallerService.isStageName(cid)) continue;
23013
23014                    if (DEBUG_SD_INSTALL)
23015                        Log.i(TAG, "Processing container " + cid);
23016                    String pkgName = getAsecPackageName(cid);
23017                    if (pkgName == null) {
23018                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
23019                        continue;
23020                    }
23021                    if (DEBUG_SD_INSTALL)
23022                        Log.i(TAG, "Looking for pkg : " + pkgName);
23023
23024                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
23025                    if (ps == null) {
23026                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23027                        continue;
23028                    }
23029
23030                    /*
23031                     * Skip packages that are not external if we're unmounting
23032                     * external storage.
23033                     */
23034                    if (externalStorage && !isMounted && !isExternal(ps)) {
23035                        continue;
23036                    }
23037
23038                    final AsecInstallArgs args = new AsecInstallArgs(cid,
23039                            getAppDexInstructionSets(ps), ps.isForwardLocked());
23040                    // The package status is changed only if the code path
23041                    // matches between settings and the container id.
23042                    if (ps.codePathString != null
23043                            && ps.codePathString.startsWith(args.getCodePath())) {
23044                        if (DEBUG_SD_INSTALL) {
23045                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23046                                    + " at code path: " + ps.codePathString);
23047                        }
23048
23049                        // We do have a valid package installed on sdcard
23050                        processCids.put(args, ps.codePathString);
23051                        final int uid = ps.appId;
23052                        if (uid != -1) {
23053                            uidArr = ArrayUtils.appendInt(uidArr, uid);
23054                        }
23055                    } else {
23056                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23057                                + ps.codePathString);
23058                    }
23059                }
23060            }
23061
23062            Arrays.sort(uidArr);
23063        }
23064
23065        // Process packages with valid entries.
23066        if (isMounted) {
23067            if (DEBUG_SD_INSTALL)
23068                Log.i(TAG, "Loading packages");
23069            loadMediaPackages(processCids, uidArr, externalStorage);
23070            startCleaningPackages();
23071            mInstallerService.onSecureContainersAvailable();
23072        } else {
23073            if (DEBUG_SD_INSTALL)
23074                Log.i(TAG, "Unloading packages");
23075            unloadMediaPackages(processCids, uidArr, reportStatus);
23076        }
23077    }
23078
23079    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23080            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23081        final int size = infos.size();
23082        final String[] packageNames = new String[size];
23083        final int[] packageUids = new int[size];
23084        for (int i = 0; i < size; i++) {
23085            final ApplicationInfo info = infos.get(i);
23086            packageNames[i] = info.packageName;
23087            packageUids[i] = info.uid;
23088        }
23089        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23090                finishedReceiver);
23091    }
23092
23093    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23094            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23095        sendResourcesChangedBroadcast(mediaStatus, replacing,
23096                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23097    }
23098
23099    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23100            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23101        int size = pkgList.length;
23102        if (size > 0) {
23103            // Send broadcasts here
23104            Bundle extras = new Bundle();
23105            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23106            if (uidArr != null) {
23107                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23108            }
23109            if (replacing) {
23110                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23111            }
23112            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23113                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23114            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23115        }
23116    }
23117
23118   /*
23119     * Look at potentially valid container ids from processCids If package
23120     * information doesn't match the one on record or package scanning fails,
23121     * the cid is added to list of removeCids. We currently don't delete stale
23122     * containers.
23123     */
23124    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23125            boolean externalStorage) {
23126        ArrayList<String> pkgList = new ArrayList<String>();
23127        Set<AsecInstallArgs> keys = processCids.keySet();
23128
23129        for (AsecInstallArgs args : keys) {
23130            String codePath = processCids.get(args);
23131            if (DEBUG_SD_INSTALL)
23132                Log.i(TAG, "Loading container : " + args.cid);
23133            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23134            try {
23135                // Make sure there are no container errors first.
23136                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23137                    Slog.e(TAG, "Failed to mount cid : " + args.cid
23138                            + " when installing from sdcard");
23139                    continue;
23140                }
23141                // Check code path here.
23142                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23143                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23144                            + " does not match one in settings " + codePath);
23145                    continue;
23146                }
23147                // Parse package
23148                int parseFlags = mDefParseFlags;
23149                if (args.isExternalAsec()) {
23150                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23151                }
23152                if (args.isFwdLocked()) {
23153                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23154                }
23155
23156                synchronized (mInstallLock) {
23157                    PackageParser.Package pkg = null;
23158                    try {
23159                        // Sadly we don't know the package name yet to freeze it
23160                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23161                                SCAN_IGNORE_FROZEN, 0, null);
23162                    } catch (PackageManagerException e) {
23163                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23164                    }
23165                    // Scan the package
23166                    if (pkg != null) {
23167                        /*
23168                         * TODO why is the lock being held? doPostInstall is
23169                         * called in other places without the lock. This needs
23170                         * to be straightened out.
23171                         */
23172                        // writer
23173                        synchronized (mPackages) {
23174                            retCode = PackageManager.INSTALL_SUCCEEDED;
23175                            pkgList.add(pkg.packageName);
23176                            // Post process args
23177                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23178                                    pkg.applicationInfo.uid);
23179                        }
23180                    } else {
23181                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
23182                    }
23183                }
23184
23185            } finally {
23186                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23187                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23188                }
23189            }
23190        }
23191        // writer
23192        synchronized (mPackages) {
23193            // If the platform SDK has changed since the last time we booted,
23194            // we need to re-grant app permission to catch any new ones that
23195            // appear. This is really a hack, and means that apps can in some
23196            // cases get permissions that the user didn't initially explicitly
23197            // allow... it would be nice to have some better way to handle
23198            // this situation.
23199            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23200                    : mSettings.getInternalVersion();
23201            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23202                    : StorageManager.UUID_PRIVATE_INTERNAL;
23203
23204            int updateFlags = UPDATE_PERMISSIONS_ALL;
23205            if (ver.sdkVersion != mSdkVersion) {
23206                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23207                        + mSdkVersion + "; regranting permissions for external");
23208                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23209            }
23210            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23211
23212            // Yay, everything is now upgraded
23213            ver.forceCurrent();
23214
23215            // can downgrade to reader
23216            // Persist settings
23217            mSettings.writeLPr();
23218        }
23219        // Send a broadcast to let everyone know we are done processing
23220        if (pkgList.size() > 0) {
23221            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23222        }
23223    }
23224
23225   /*
23226     * Utility method to unload a list of specified containers
23227     */
23228    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23229        // Just unmount all valid containers.
23230        for (AsecInstallArgs arg : cidArgs) {
23231            synchronized (mInstallLock) {
23232                arg.doPostDeleteLI(false);
23233           }
23234       }
23235   }
23236
23237    /*
23238     * Unload packages mounted on external media. This involves deleting package
23239     * data from internal structures, sending broadcasts about disabled packages,
23240     * gc'ing to free up references, unmounting all secure containers
23241     * corresponding to packages on external media, and posting a
23242     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23243     * that we always have to post this message if status has been requested no
23244     * matter what.
23245     */
23246    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23247            final boolean reportStatus) {
23248        if (DEBUG_SD_INSTALL)
23249            Log.i(TAG, "unloading media packages");
23250        ArrayList<String> pkgList = new ArrayList<String>();
23251        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23252        final Set<AsecInstallArgs> keys = processCids.keySet();
23253        for (AsecInstallArgs args : keys) {
23254            String pkgName = args.getPackageName();
23255            if (DEBUG_SD_INSTALL)
23256                Log.i(TAG, "Trying to unload pkg : " + pkgName);
23257            // Delete package internally
23258            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23259            synchronized (mInstallLock) {
23260                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23261                final boolean res;
23262                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23263                        "unloadMediaPackages")) {
23264                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23265                            null);
23266                }
23267                if (res) {
23268                    pkgList.add(pkgName);
23269                } else {
23270                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23271                    failedList.add(args);
23272                }
23273            }
23274        }
23275
23276        // reader
23277        synchronized (mPackages) {
23278            // We didn't update the settings after removing each package;
23279            // write them now for all packages.
23280            mSettings.writeLPr();
23281        }
23282
23283        // We have to absolutely send UPDATED_MEDIA_STATUS only
23284        // after confirming that all the receivers processed the ordered
23285        // broadcast when packages get disabled, force a gc to clean things up.
23286        // and unload all the containers.
23287        if (pkgList.size() > 0) {
23288            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23289                    new IIntentReceiver.Stub() {
23290                public void performReceive(Intent intent, int resultCode, String data,
23291                        Bundle extras, boolean ordered, boolean sticky,
23292                        int sendingUser) throws RemoteException {
23293                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23294                            reportStatus ? 1 : 0, 1, keys);
23295                    mHandler.sendMessage(msg);
23296                }
23297            });
23298        } else {
23299            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23300                    keys);
23301            mHandler.sendMessage(msg);
23302        }
23303    }
23304
23305    private void loadPrivatePackages(final VolumeInfo vol) {
23306        mHandler.post(new Runnable() {
23307            @Override
23308            public void run() {
23309                loadPrivatePackagesInner(vol);
23310            }
23311        });
23312    }
23313
23314    private void loadPrivatePackagesInner(VolumeInfo vol) {
23315        final String volumeUuid = vol.fsUuid;
23316        if (TextUtils.isEmpty(volumeUuid)) {
23317            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23318            return;
23319        }
23320
23321        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23322        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23323        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23324
23325        final VersionInfo ver;
23326        final List<PackageSetting> packages;
23327        synchronized (mPackages) {
23328            ver = mSettings.findOrCreateVersion(volumeUuid);
23329            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23330        }
23331
23332        for (PackageSetting ps : packages) {
23333            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23334            synchronized (mInstallLock) {
23335                final PackageParser.Package pkg;
23336                try {
23337                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23338                    loaded.add(pkg.applicationInfo);
23339
23340                } catch (PackageManagerException e) {
23341                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23342                }
23343
23344                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23345                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23346                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23347                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23348                }
23349            }
23350        }
23351
23352        // Reconcile app data for all started/unlocked users
23353        final StorageManager sm = mContext.getSystemService(StorageManager.class);
23354        final UserManager um = mContext.getSystemService(UserManager.class);
23355        UserManagerInternal umInternal = getUserManagerInternal();
23356        for (UserInfo user : um.getUsers()) {
23357            final int flags;
23358            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23359                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23360            } else if (umInternal.isUserRunning(user.id)) {
23361                flags = StorageManager.FLAG_STORAGE_DE;
23362            } else {
23363                continue;
23364            }
23365
23366            try {
23367                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23368                synchronized (mInstallLock) {
23369                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23370                }
23371            } catch (IllegalStateException e) {
23372                // Device was probably ejected, and we'll process that event momentarily
23373                Slog.w(TAG, "Failed to prepare storage: " + e);
23374            }
23375        }
23376
23377        synchronized (mPackages) {
23378            int updateFlags = UPDATE_PERMISSIONS_ALL;
23379            if (ver.sdkVersion != mSdkVersion) {
23380                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23381                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
23382                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23383            }
23384            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23385
23386            // Yay, everything is now upgraded
23387            ver.forceCurrent();
23388
23389            mSettings.writeLPr();
23390        }
23391
23392        for (PackageFreezer freezer : freezers) {
23393            freezer.close();
23394        }
23395
23396        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23397        sendResourcesChangedBroadcast(true, false, loaded, null);
23398        mLoadedVolumes.add(vol.getId());
23399    }
23400
23401    private void unloadPrivatePackages(final VolumeInfo vol) {
23402        mHandler.post(new Runnable() {
23403            @Override
23404            public void run() {
23405                unloadPrivatePackagesInner(vol);
23406            }
23407        });
23408    }
23409
23410    private void unloadPrivatePackagesInner(VolumeInfo vol) {
23411        final String volumeUuid = vol.fsUuid;
23412        if (TextUtils.isEmpty(volumeUuid)) {
23413            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23414            return;
23415        }
23416
23417        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23418        synchronized (mInstallLock) {
23419        synchronized (mPackages) {
23420            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23421            for (PackageSetting ps : packages) {
23422                if (ps.pkg == null) continue;
23423
23424                final ApplicationInfo info = ps.pkg.applicationInfo;
23425                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23426                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23427
23428                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23429                        "unloadPrivatePackagesInner")) {
23430                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23431                            false, null)) {
23432                        unloaded.add(info);
23433                    } else {
23434                        Slog.w(TAG, "Failed to unload " + ps.codePath);
23435                    }
23436                }
23437
23438                // Try very hard to release any references to this package
23439                // so we don't risk the system server being killed due to
23440                // open FDs
23441                AttributeCache.instance().removePackage(ps.name);
23442            }
23443
23444            mSettings.writeLPr();
23445        }
23446        }
23447
23448        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23449        sendResourcesChangedBroadcast(false, false, unloaded, null);
23450        mLoadedVolumes.remove(vol.getId());
23451
23452        // Try very hard to release any references to this path so we don't risk
23453        // the system server being killed due to open FDs
23454        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23455
23456        for (int i = 0; i < 3; i++) {
23457            System.gc();
23458            System.runFinalization();
23459        }
23460    }
23461
23462    private void assertPackageKnown(String volumeUuid, String packageName)
23463            throws PackageManagerException {
23464        synchronized (mPackages) {
23465            // Normalize package name to handle renamed packages
23466            packageName = normalizePackageNameLPr(packageName);
23467
23468            final PackageSetting ps = mSettings.mPackages.get(packageName);
23469            if (ps == null) {
23470                throw new PackageManagerException("Package " + packageName + " is unknown");
23471            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23472                throw new PackageManagerException(
23473                        "Package " + packageName + " found on unknown volume " + volumeUuid
23474                                + "; expected volume " + ps.volumeUuid);
23475            }
23476        }
23477    }
23478
23479    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23480            throws PackageManagerException {
23481        synchronized (mPackages) {
23482            // Normalize package name to handle renamed packages
23483            packageName = normalizePackageNameLPr(packageName);
23484
23485            final PackageSetting ps = mSettings.mPackages.get(packageName);
23486            if (ps == null) {
23487                throw new PackageManagerException("Package " + packageName + " is unknown");
23488            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23489                throw new PackageManagerException(
23490                        "Package " + packageName + " found on unknown volume " + volumeUuid
23491                                + "; expected volume " + ps.volumeUuid);
23492            } else if (!ps.getInstalled(userId)) {
23493                throw new PackageManagerException(
23494                        "Package " + packageName + " not installed for user " + userId);
23495            }
23496        }
23497    }
23498
23499    private List<String> collectAbsoluteCodePaths() {
23500        synchronized (mPackages) {
23501            List<String> codePaths = new ArrayList<>();
23502            final int packageCount = mSettings.mPackages.size();
23503            for (int i = 0; i < packageCount; i++) {
23504                final PackageSetting ps = mSettings.mPackages.valueAt(i);
23505                codePaths.add(ps.codePath.getAbsolutePath());
23506            }
23507            return codePaths;
23508        }
23509    }
23510
23511    /**
23512     * Examine all apps present on given mounted volume, and destroy apps that
23513     * aren't expected, either due to uninstallation or reinstallation on
23514     * another volume.
23515     */
23516    private void reconcileApps(String volumeUuid) {
23517        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
23518        List<File> filesToDelete = null;
23519
23520        final File[] files = FileUtils.listFilesOrEmpty(
23521                Environment.getDataAppDirectory(volumeUuid));
23522        for (File file : files) {
23523            final boolean isPackage = (isApkFile(file) || file.isDirectory())
23524                    && !PackageInstallerService.isStageName(file.getName());
23525            if (!isPackage) {
23526                // Ignore entries which are not packages
23527                continue;
23528            }
23529
23530            String absolutePath = file.getAbsolutePath();
23531
23532            boolean pathValid = false;
23533            final int absoluteCodePathCount = absoluteCodePaths.size();
23534            for (int i = 0; i < absoluteCodePathCount; i++) {
23535                String absoluteCodePath = absoluteCodePaths.get(i);
23536                if (absolutePath.startsWith(absoluteCodePath)) {
23537                    pathValid = true;
23538                    break;
23539                }
23540            }
23541
23542            if (!pathValid) {
23543                if (filesToDelete == null) {
23544                    filesToDelete = new ArrayList<>();
23545                }
23546                filesToDelete.add(file);
23547            }
23548        }
23549
23550        if (filesToDelete != null) {
23551            final int fileToDeleteCount = filesToDelete.size();
23552            for (int i = 0; i < fileToDeleteCount; i++) {
23553                File fileToDelete = filesToDelete.get(i);
23554                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
23555                synchronized (mInstallLock) {
23556                    removeCodePathLI(fileToDelete);
23557                }
23558            }
23559        }
23560    }
23561
23562    /**
23563     * Reconcile all app data for the given user.
23564     * <p>
23565     * Verifies that directories exist and that ownership and labeling is
23566     * correct for all installed apps on all mounted volumes.
23567     */
23568    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
23569        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23570        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
23571            final String volumeUuid = vol.getFsUuid();
23572            synchronized (mInstallLock) {
23573                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
23574            }
23575        }
23576    }
23577
23578    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23579            boolean migrateAppData) {
23580        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
23581    }
23582
23583    /**
23584     * Reconcile all app data on given mounted volume.
23585     * <p>
23586     * Destroys app data that isn't expected, either due to uninstallation or
23587     * reinstallation on another volume.
23588     * <p>
23589     * Verifies that directories exist and that ownership and labeling is
23590     * correct for all installed apps.
23591     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
23592     */
23593    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23594            boolean migrateAppData, boolean onlyCoreApps) {
23595        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
23596                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
23597        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
23598
23599        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
23600        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
23601
23602        // First look for stale data that doesn't belong, and check if things
23603        // have changed since we did our last restorecon
23604        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23605            if (StorageManager.isFileEncryptedNativeOrEmulated()
23606                    && !StorageManager.isUserKeyUnlocked(userId)) {
23607                throw new RuntimeException(
23608                        "Yikes, someone asked us to reconcile CE storage while " + userId
23609                                + " was still locked; this would have caused massive data loss!");
23610            }
23611
23612            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
23613            for (File file : files) {
23614                final String packageName = file.getName();
23615                try {
23616                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23617                } catch (PackageManagerException e) {
23618                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23619                    try {
23620                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23621                                StorageManager.FLAG_STORAGE_CE, 0);
23622                    } catch (InstallerException e2) {
23623                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23624                    }
23625                }
23626            }
23627        }
23628        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
23629            final File[] files = FileUtils.listFilesOrEmpty(deDir);
23630            for (File file : files) {
23631                final String packageName = file.getName();
23632                try {
23633                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23634                } catch (PackageManagerException e) {
23635                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23636                    try {
23637                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23638                                StorageManager.FLAG_STORAGE_DE, 0);
23639                    } catch (InstallerException e2) {
23640                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23641                    }
23642                }
23643            }
23644        }
23645
23646        // Ensure that data directories are ready to roll for all packages
23647        // installed for this volume and user
23648        final List<PackageSetting> packages;
23649        synchronized (mPackages) {
23650            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23651        }
23652        int preparedCount = 0;
23653        for (PackageSetting ps : packages) {
23654            final String packageName = ps.name;
23655            if (ps.pkg == null) {
23656                Slog.w(TAG, "Odd, missing scanned package " + packageName);
23657                // TODO: might be due to legacy ASEC apps; we should circle back
23658                // and reconcile again once they're scanned
23659                continue;
23660            }
23661            // Skip non-core apps if requested
23662            if (onlyCoreApps && !ps.pkg.coreApp) {
23663                result.add(packageName);
23664                continue;
23665            }
23666
23667            if (ps.getInstalled(userId)) {
23668                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
23669                preparedCount++;
23670            }
23671        }
23672
23673        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
23674        return result;
23675    }
23676
23677    /**
23678     * Prepare app data for the given app just after it was installed or
23679     * upgraded. This method carefully only touches users that it's installed
23680     * for, and it forces a restorecon to handle any seinfo changes.
23681     * <p>
23682     * Verifies that directories exist and that ownership and labeling is
23683     * correct for all installed apps. If there is an ownership mismatch, it
23684     * will try recovering system apps by wiping data; third-party app data is
23685     * left intact.
23686     * <p>
23687     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
23688     */
23689    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
23690        final PackageSetting ps;
23691        synchronized (mPackages) {
23692            ps = mSettings.mPackages.get(pkg.packageName);
23693            mSettings.writeKernelMappingLPr(ps);
23694        }
23695
23696        final UserManager um = mContext.getSystemService(UserManager.class);
23697        UserManagerInternal umInternal = getUserManagerInternal();
23698        for (UserInfo user : um.getUsers()) {
23699            final int flags;
23700            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23701                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23702            } else if (umInternal.isUserRunning(user.id)) {
23703                flags = StorageManager.FLAG_STORAGE_DE;
23704            } else {
23705                continue;
23706            }
23707
23708            if (ps.getInstalled(user.id)) {
23709                // TODO: when user data is locked, mark that we're still dirty
23710                prepareAppDataLIF(pkg, user.id, flags);
23711            }
23712        }
23713    }
23714
23715    /**
23716     * Prepare app data for the given app.
23717     * <p>
23718     * Verifies that directories exist and that ownership and labeling is
23719     * correct for all installed apps. If there is an ownership mismatch, this
23720     * will try recovering system apps by wiping data; third-party app data is
23721     * left intact.
23722     */
23723    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
23724        if (pkg == null) {
23725            Slog.wtf(TAG, "Package was null!", new Throwable());
23726            return;
23727        }
23728        prepareAppDataLeafLIF(pkg, userId, flags);
23729        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23730        for (int i = 0; i < childCount; i++) {
23731            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
23732        }
23733    }
23734
23735    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
23736            boolean maybeMigrateAppData) {
23737        prepareAppDataLIF(pkg, userId, flags);
23738
23739        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
23740            // We may have just shuffled around app data directories, so
23741            // prepare them one more time
23742            prepareAppDataLIF(pkg, userId, flags);
23743        }
23744    }
23745
23746    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23747        if (DEBUG_APP_DATA) {
23748            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
23749                    + Integer.toHexString(flags));
23750        }
23751
23752        final String volumeUuid = pkg.volumeUuid;
23753        final String packageName = pkg.packageName;
23754        final ApplicationInfo app = pkg.applicationInfo;
23755        final int appId = UserHandle.getAppId(app.uid);
23756
23757        Preconditions.checkNotNull(app.seInfo);
23758
23759        long ceDataInode = -1;
23760        try {
23761            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23762                    appId, app.seInfo, app.targetSdkVersion);
23763        } catch (InstallerException e) {
23764            if (app.isSystemApp()) {
23765                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23766                        + ", but trying to recover: " + e);
23767                destroyAppDataLeafLIF(pkg, userId, flags);
23768                try {
23769                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23770                            appId, app.seInfo, app.targetSdkVersion);
23771                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23772                } catch (InstallerException e2) {
23773                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
23774                }
23775            } else {
23776                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23777            }
23778        }
23779
23780        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23781            // TODO: mark this structure as dirty so we persist it!
23782            synchronized (mPackages) {
23783                final PackageSetting ps = mSettings.mPackages.get(packageName);
23784                if (ps != null) {
23785                    ps.setCeDataInode(ceDataInode, userId);
23786                }
23787            }
23788        }
23789
23790        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23791    }
23792
23793    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23794        if (pkg == null) {
23795            Slog.wtf(TAG, "Package was null!", new Throwable());
23796            return;
23797        }
23798        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23799        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23800        for (int i = 0; i < childCount; i++) {
23801            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23802        }
23803    }
23804
23805    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23806        final String volumeUuid = pkg.volumeUuid;
23807        final String packageName = pkg.packageName;
23808        final ApplicationInfo app = pkg.applicationInfo;
23809
23810        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23811            // Create a native library symlink only if we have native libraries
23812            // and if the native libraries are 32 bit libraries. We do not provide
23813            // this symlink for 64 bit libraries.
23814            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23815                final String nativeLibPath = app.nativeLibraryDir;
23816                try {
23817                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23818                            nativeLibPath, userId);
23819                } catch (InstallerException e) {
23820                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23821                }
23822            }
23823        }
23824    }
23825
23826    /**
23827     * For system apps on non-FBE devices, this method migrates any existing
23828     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23829     * requested by the app.
23830     */
23831    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23832        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
23833                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23834            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23835                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23836            try {
23837                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23838                        storageTarget);
23839            } catch (InstallerException e) {
23840                logCriticalInfo(Log.WARN,
23841                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23842            }
23843            return true;
23844        } else {
23845            return false;
23846        }
23847    }
23848
23849    public PackageFreezer freezePackage(String packageName, String killReason) {
23850        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23851    }
23852
23853    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23854        return new PackageFreezer(packageName, userId, killReason);
23855    }
23856
23857    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23858            String killReason) {
23859        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23860    }
23861
23862    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23863            String killReason) {
23864        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23865            return new PackageFreezer();
23866        } else {
23867            return freezePackage(packageName, userId, killReason);
23868        }
23869    }
23870
23871    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23872            String killReason) {
23873        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23874    }
23875
23876    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23877            String killReason) {
23878        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23879            return new PackageFreezer();
23880        } else {
23881            return freezePackage(packageName, userId, killReason);
23882        }
23883    }
23884
23885    /**
23886     * Class that freezes and kills the given package upon creation, and
23887     * unfreezes it upon closing. This is typically used when doing surgery on
23888     * app code/data to prevent the app from running while you're working.
23889     */
23890    private class PackageFreezer implements AutoCloseable {
23891        private final String mPackageName;
23892        private final PackageFreezer[] mChildren;
23893
23894        private final boolean mWeFroze;
23895
23896        private final AtomicBoolean mClosed = new AtomicBoolean();
23897        private final CloseGuard mCloseGuard = CloseGuard.get();
23898
23899        /**
23900         * Create and return a stub freezer that doesn't actually do anything,
23901         * typically used when someone requested
23902         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23903         * {@link PackageManager#DELETE_DONT_KILL_APP}.
23904         */
23905        public PackageFreezer() {
23906            mPackageName = null;
23907            mChildren = null;
23908            mWeFroze = false;
23909            mCloseGuard.open("close");
23910        }
23911
23912        public PackageFreezer(String packageName, int userId, String killReason) {
23913            synchronized (mPackages) {
23914                mPackageName = packageName;
23915                mWeFroze = mFrozenPackages.add(mPackageName);
23916
23917                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23918                if (ps != null) {
23919                    killApplication(ps.name, ps.appId, userId, killReason);
23920                }
23921
23922                final PackageParser.Package p = mPackages.get(packageName);
23923                if (p != null && p.childPackages != null) {
23924                    final int N = p.childPackages.size();
23925                    mChildren = new PackageFreezer[N];
23926                    for (int i = 0; i < N; i++) {
23927                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23928                                userId, killReason);
23929                    }
23930                } else {
23931                    mChildren = null;
23932                }
23933            }
23934            mCloseGuard.open("close");
23935        }
23936
23937        @Override
23938        protected void finalize() throws Throwable {
23939            try {
23940                if (mCloseGuard != null) {
23941                    mCloseGuard.warnIfOpen();
23942                }
23943
23944                close();
23945            } finally {
23946                super.finalize();
23947            }
23948        }
23949
23950        @Override
23951        public void close() {
23952            mCloseGuard.close();
23953            if (mClosed.compareAndSet(false, true)) {
23954                synchronized (mPackages) {
23955                    if (mWeFroze) {
23956                        mFrozenPackages.remove(mPackageName);
23957                    }
23958
23959                    if (mChildren != null) {
23960                        for (PackageFreezer freezer : mChildren) {
23961                            freezer.close();
23962                        }
23963                    }
23964                }
23965            }
23966        }
23967    }
23968
23969    /**
23970     * Verify that given package is currently frozen.
23971     */
23972    private void checkPackageFrozen(String packageName) {
23973        synchronized (mPackages) {
23974            if (!mFrozenPackages.contains(packageName)) {
23975                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23976            }
23977        }
23978    }
23979
23980    @Override
23981    public int movePackage(final String packageName, final String volumeUuid) {
23982        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23983
23984        final int callingUid = Binder.getCallingUid();
23985        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23986        final int moveId = mNextMoveId.getAndIncrement();
23987        mHandler.post(new Runnable() {
23988            @Override
23989            public void run() {
23990                try {
23991                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23992                } catch (PackageManagerException e) {
23993                    Slog.w(TAG, "Failed to move " + packageName, e);
23994                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
23995                }
23996            }
23997        });
23998        return moveId;
23999    }
24000
24001    private void movePackageInternal(final String packageName, final String volumeUuid,
24002            final int moveId, final int callingUid, UserHandle user)
24003                    throws PackageManagerException {
24004        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24005        final PackageManager pm = mContext.getPackageManager();
24006
24007        final boolean currentAsec;
24008        final String currentVolumeUuid;
24009        final File codeFile;
24010        final String installerPackageName;
24011        final String packageAbiOverride;
24012        final int appId;
24013        final String seinfo;
24014        final String label;
24015        final int targetSdkVersion;
24016        final PackageFreezer freezer;
24017        final int[] installedUserIds;
24018
24019        // reader
24020        synchronized (mPackages) {
24021            final PackageParser.Package pkg = mPackages.get(packageName);
24022            final PackageSetting ps = mSettings.mPackages.get(packageName);
24023            if (pkg == null
24024                    || ps == null
24025                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24026                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24027            }
24028            if (pkg.applicationInfo.isSystemApp()) {
24029                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24030                        "Cannot move system application");
24031            }
24032
24033            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24034            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24035                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24036            if (isInternalStorage && !allow3rdPartyOnInternal) {
24037                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24038                        "3rd party apps are not allowed on internal storage");
24039            }
24040
24041            if (pkg.applicationInfo.isExternalAsec()) {
24042                currentAsec = true;
24043                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24044            } else if (pkg.applicationInfo.isForwardLocked()) {
24045                currentAsec = true;
24046                currentVolumeUuid = "forward_locked";
24047            } else {
24048                currentAsec = false;
24049                currentVolumeUuid = ps.volumeUuid;
24050
24051                final File probe = new File(pkg.codePath);
24052                final File probeOat = new File(probe, "oat");
24053                if (!probe.isDirectory() || !probeOat.isDirectory()) {
24054                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24055                            "Move only supported for modern cluster style installs");
24056                }
24057            }
24058
24059            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24060                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24061                        "Package already moved to " + volumeUuid);
24062            }
24063            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24064                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24065                        "Device admin cannot be moved");
24066            }
24067
24068            if (mFrozenPackages.contains(packageName)) {
24069                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24070                        "Failed to move already frozen package");
24071            }
24072
24073            codeFile = new File(pkg.codePath);
24074            installerPackageName = ps.installerPackageName;
24075            packageAbiOverride = ps.cpuAbiOverrideString;
24076            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24077            seinfo = pkg.applicationInfo.seInfo;
24078            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24079            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24080            freezer = freezePackage(packageName, "movePackageInternal");
24081            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24082        }
24083
24084        final Bundle extras = new Bundle();
24085        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24086        extras.putString(Intent.EXTRA_TITLE, label);
24087        mMoveCallbacks.notifyCreated(moveId, extras);
24088
24089        int installFlags;
24090        final boolean moveCompleteApp;
24091        final File measurePath;
24092
24093        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24094            installFlags = INSTALL_INTERNAL;
24095            moveCompleteApp = !currentAsec;
24096            measurePath = Environment.getDataAppDirectory(volumeUuid);
24097        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24098            installFlags = INSTALL_EXTERNAL;
24099            moveCompleteApp = false;
24100            measurePath = storage.getPrimaryPhysicalVolume().getPath();
24101        } else {
24102            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24103            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24104                    || !volume.isMountedWritable()) {
24105                freezer.close();
24106                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24107                        "Move location not mounted private volume");
24108            }
24109
24110            Preconditions.checkState(!currentAsec);
24111
24112            installFlags = INSTALL_INTERNAL;
24113            moveCompleteApp = true;
24114            measurePath = Environment.getDataAppDirectory(volumeUuid);
24115        }
24116
24117        // If we're moving app data around, we need all the users unlocked
24118        if (moveCompleteApp) {
24119            for (int userId : installedUserIds) {
24120                if (StorageManager.isFileEncryptedNativeOrEmulated()
24121                        && !StorageManager.isUserKeyUnlocked(userId)) {
24122                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24123                            "User " + userId + " must be unlocked");
24124                }
24125            }
24126        }
24127
24128        final PackageStats stats = new PackageStats(null, -1);
24129        synchronized (mInstaller) {
24130            for (int userId : installedUserIds) {
24131                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24132                    freezer.close();
24133                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24134                            "Failed to measure package size");
24135                }
24136            }
24137        }
24138
24139        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24140                + stats.dataSize);
24141
24142        final long startFreeBytes = measurePath.getUsableSpace();
24143        final long sizeBytes;
24144        if (moveCompleteApp) {
24145            sizeBytes = stats.codeSize + stats.dataSize;
24146        } else {
24147            sizeBytes = stats.codeSize;
24148        }
24149
24150        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24151            freezer.close();
24152            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24153                    "Not enough free space to move");
24154        }
24155
24156        mMoveCallbacks.notifyStatusChanged(moveId, 10);
24157
24158        final CountDownLatch installedLatch = new CountDownLatch(1);
24159        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24160            @Override
24161            public void onUserActionRequired(Intent intent) throws RemoteException {
24162                throw new IllegalStateException();
24163            }
24164
24165            @Override
24166            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24167                    Bundle extras) throws RemoteException {
24168                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24169                        + PackageManager.installStatusToString(returnCode, msg));
24170
24171                installedLatch.countDown();
24172                freezer.close();
24173
24174                final int status = PackageManager.installStatusToPublicStatus(returnCode);
24175                switch (status) {
24176                    case PackageInstaller.STATUS_SUCCESS:
24177                        mMoveCallbacks.notifyStatusChanged(moveId,
24178                                PackageManager.MOVE_SUCCEEDED);
24179                        break;
24180                    case PackageInstaller.STATUS_FAILURE_STORAGE:
24181                        mMoveCallbacks.notifyStatusChanged(moveId,
24182                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24183                        break;
24184                    default:
24185                        mMoveCallbacks.notifyStatusChanged(moveId,
24186                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24187                        break;
24188                }
24189            }
24190        };
24191
24192        final MoveInfo move;
24193        if (moveCompleteApp) {
24194            // Kick off a thread to report progress estimates
24195            new Thread() {
24196                @Override
24197                public void run() {
24198                    while (true) {
24199                        try {
24200                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
24201                                break;
24202                            }
24203                        } catch (InterruptedException ignored) {
24204                        }
24205
24206                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24207                        final int progress = 10 + (int) MathUtils.constrain(
24208                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24209                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
24210                    }
24211                }
24212            }.start();
24213
24214            final String dataAppName = codeFile.getName();
24215            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24216                    dataAppName, appId, seinfo, targetSdkVersion);
24217        } else {
24218            move = null;
24219        }
24220
24221        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24222
24223        final Message msg = mHandler.obtainMessage(INIT_COPY);
24224        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24225        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24226                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24227                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24228                PackageManager.INSTALL_REASON_UNKNOWN);
24229        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24230        msg.obj = params;
24231
24232        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24233                System.identityHashCode(msg.obj));
24234        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24235                System.identityHashCode(msg.obj));
24236
24237        mHandler.sendMessage(msg);
24238    }
24239
24240    @Override
24241    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24242        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24243
24244        final int realMoveId = mNextMoveId.getAndIncrement();
24245        final Bundle extras = new Bundle();
24246        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24247        mMoveCallbacks.notifyCreated(realMoveId, extras);
24248
24249        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24250            @Override
24251            public void onCreated(int moveId, Bundle extras) {
24252                // Ignored
24253            }
24254
24255            @Override
24256            public void onStatusChanged(int moveId, int status, long estMillis) {
24257                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24258            }
24259        };
24260
24261        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24262        storage.setPrimaryStorageUuid(volumeUuid, callback);
24263        return realMoveId;
24264    }
24265
24266    @Override
24267    public int getMoveStatus(int moveId) {
24268        mContext.enforceCallingOrSelfPermission(
24269                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24270        return mMoveCallbacks.mLastStatus.get(moveId);
24271    }
24272
24273    @Override
24274    public void registerMoveCallback(IPackageMoveObserver callback) {
24275        mContext.enforceCallingOrSelfPermission(
24276                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24277        mMoveCallbacks.register(callback);
24278    }
24279
24280    @Override
24281    public void unregisterMoveCallback(IPackageMoveObserver callback) {
24282        mContext.enforceCallingOrSelfPermission(
24283                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24284        mMoveCallbacks.unregister(callback);
24285    }
24286
24287    @Override
24288    public boolean setInstallLocation(int loc) {
24289        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24290                null);
24291        if (getInstallLocation() == loc) {
24292            return true;
24293        }
24294        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24295                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24296            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24297                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24298            return true;
24299        }
24300        return false;
24301   }
24302
24303    @Override
24304    public int getInstallLocation() {
24305        // allow instant app access
24306        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24307                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24308                PackageHelper.APP_INSTALL_AUTO);
24309    }
24310
24311    /** Called by UserManagerService */
24312    void cleanUpUser(UserManagerService userManager, int userHandle) {
24313        synchronized (mPackages) {
24314            mDirtyUsers.remove(userHandle);
24315            mUserNeedsBadging.delete(userHandle);
24316            mSettings.removeUserLPw(userHandle);
24317            mPendingBroadcasts.remove(userHandle);
24318            mInstantAppRegistry.onUserRemovedLPw(userHandle);
24319            removeUnusedPackagesLPw(userManager, userHandle);
24320        }
24321    }
24322
24323    /**
24324     * We're removing userHandle and would like to remove any downloaded packages
24325     * that are no longer in use by any other user.
24326     * @param userHandle the user being removed
24327     */
24328    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24329        final boolean DEBUG_CLEAN_APKS = false;
24330        int [] users = userManager.getUserIds();
24331        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24332        while (psit.hasNext()) {
24333            PackageSetting ps = psit.next();
24334            if (ps.pkg == null) {
24335                continue;
24336            }
24337            final String packageName = ps.pkg.packageName;
24338            // Skip over if system app
24339            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24340                continue;
24341            }
24342            if (DEBUG_CLEAN_APKS) {
24343                Slog.i(TAG, "Checking package " + packageName);
24344            }
24345            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24346            if (keep) {
24347                if (DEBUG_CLEAN_APKS) {
24348                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
24349                }
24350            } else {
24351                for (int i = 0; i < users.length; i++) {
24352                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
24353                        keep = true;
24354                        if (DEBUG_CLEAN_APKS) {
24355                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
24356                                    + users[i]);
24357                        }
24358                        break;
24359                    }
24360                }
24361            }
24362            if (!keep) {
24363                if (DEBUG_CLEAN_APKS) {
24364                    Slog.i(TAG, "  Removing package " + packageName);
24365                }
24366                mHandler.post(new Runnable() {
24367                    public void run() {
24368                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24369                                userHandle, 0);
24370                    } //end run
24371                });
24372            }
24373        }
24374    }
24375
24376    /** Called by UserManagerService */
24377    void createNewUser(int userId, String[] disallowedPackages) {
24378        synchronized (mInstallLock) {
24379            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24380        }
24381        synchronized (mPackages) {
24382            scheduleWritePackageRestrictionsLocked(userId);
24383            scheduleWritePackageListLocked(userId);
24384            applyFactoryDefaultBrowserLPw(userId);
24385            primeDomainVerificationsLPw(userId);
24386        }
24387    }
24388
24389    void onNewUserCreated(final int userId) {
24390        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
24391        // If permission review for legacy apps is required, we represent
24392        // dagerous permissions for such apps as always granted runtime
24393        // permissions to keep per user flag state whether review is needed.
24394        // Hence, if a new user is added we have to propagate dangerous
24395        // permission grants for these legacy apps.
24396        if (mPermissionReviewRequired) {
24397            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
24398                    | UPDATE_PERMISSIONS_REPLACE_ALL);
24399        }
24400    }
24401
24402    @Override
24403    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
24404        mContext.enforceCallingOrSelfPermission(
24405                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24406                "Only package verification agents can read the verifier device identity");
24407
24408        synchronized (mPackages) {
24409            return mSettings.getVerifierDeviceIdentityLPw();
24410        }
24411    }
24412
24413    @Override
24414    public void setPermissionEnforced(String permission, boolean enforced) {
24415        // TODO: Now that we no longer change GID for storage, this should to away.
24416        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24417                "setPermissionEnforced");
24418        if (READ_EXTERNAL_STORAGE.equals(permission)) {
24419            synchronized (mPackages) {
24420                if (mSettings.mReadExternalStorageEnforced == null
24421                        || mSettings.mReadExternalStorageEnforced != enforced) {
24422                    mSettings.mReadExternalStorageEnforced = enforced;
24423                    mSettings.writeLPr();
24424                }
24425            }
24426            // kill any non-foreground processes so we restart them and
24427            // grant/revoke the GID.
24428            final IActivityManager am = ActivityManager.getService();
24429            if (am != null) {
24430                final long token = Binder.clearCallingIdentity();
24431                try {
24432                    am.killProcessesBelowForeground("setPermissionEnforcement");
24433                } catch (RemoteException e) {
24434                } finally {
24435                    Binder.restoreCallingIdentity(token);
24436                }
24437            }
24438        } else {
24439            throw new IllegalArgumentException("No selective enforcement for " + permission);
24440        }
24441    }
24442
24443    @Override
24444    @Deprecated
24445    public boolean isPermissionEnforced(String permission) {
24446        // allow instant applications
24447        return true;
24448    }
24449
24450    @Override
24451    public boolean isStorageLow() {
24452        // allow instant applications
24453        final long token = Binder.clearCallingIdentity();
24454        try {
24455            final DeviceStorageMonitorInternal
24456                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24457            if (dsm != null) {
24458                return dsm.isMemoryLow();
24459            } else {
24460                return false;
24461            }
24462        } finally {
24463            Binder.restoreCallingIdentity(token);
24464        }
24465    }
24466
24467    @Override
24468    public IPackageInstaller getPackageInstaller() {
24469        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24470            return null;
24471        }
24472        return mInstallerService;
24473    }
24474
24475    private boolean userNeedsBadging(int userId) {
24476        int index = mUserNeedsBadging.indexOfKey(userId);
24477        if (index < 0) {
24478            final UserInfo userInfo;
24479            final long token = Binder.clearCallingIdentity();
24480            try {
24481                userInfo = sUserManager.getUserInfo(userId);
24482            } finally {
24483                Binder.restoreCallingIdentity(token);
24484            }
24485            final boolean b;
24486            if (userInfo != null && userInfo.isManagedProfile()) {
24487                b = true;
24488            } else {
24489                b = false;
24490            }
24491            mUserNeedsBadging.put(userId, b);
24492            return b;
24493        }
24494        return mUserNeedsBadging.valueAt(index);
24495    }
24496
24497    @Override
24498    public KeySet getKeySetByAlias(String packageName, String alias) {
24499        if (packageName == null || alias == null) {
24500            return null;
24501        }
24502        synchronized(mPackages) {
24503            final PackageParser.Package pkg = mPackages.get(packageName);
24504            if (pkg == null) {
24505                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24506                throw new IllegalArgumentException("Unknown package: " + packageName);
24507            }
24508            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24509            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
24510                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
24511                throw new IllegalArgumentException("Unknown package: " + packageName);
24512            }
24513            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24514            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
24515        }
24516    }
24517
24518    @Override
24519    public KeySet getSigningKeySet(String packageName) {
24520        if (packageName == null) {
24521            return null;
24522        }
24523        synchronized(mPackages) {
24524            final int callingUid = Binder.getCallingUid();
24525            final int callingUserId = UserHandle.getUserId(callingUid);
24526            final PackageParser.Package pkg = mPackages.get(packageName);
24527            if (pkg == null) {
24528                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24529                throw new IllegalArgumentException("Unknown package: " + packageName);
24530            }
24531            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24532            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
24533                // filter and pretend the package doesn't exist
24534                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
24535                        + ", uid:" + callingUid);
24536                throw new IllegalArgumentException("Unknown package: " + packageName);
24537            }
24538            if (pkg.applicationInfo.uid != callingUid
24539                    && Process.SYSTEM_UID != callingUid) {
24540                throw new SecurityException("May not access signing KeySet of other apps.");
24541            }
24542            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24543            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
24544        }
24545    }
24546
24547    @Override
24548    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
24549        final int callingUid = Binder.getCallingUid();
24550        if (getInstantAppPackageName(callingUid) != null) {
24551            return false;
24552        }
24553        if (packageName == null || ks == null) {
24554            return false;
24555        }
24556        synchronized(mPackages) {
24557            final PackageParser.Package pkg = mPackages.get(packageName);
24558            if (pkg == null
24559                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24560                            UserHandle.getUserId(callingUid))) {
24561                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24562                throw new IllegalArgumentException("Unknown package: " + packageName);
24563            }
24564            IBinder ksh = ks.getToken();
24565            if (ksh instanceof KeySetHandle) {
24566                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24567                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
24568            }
24569            return false;
24570        }
24571    }
24572
24573    @Override
24574    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
24575        final int callingUid = Binder.getCallingUid();
24576        if (getInstantAppPackageName(callingUid) != null) {
24577            return false;
24578        }
24579        if (packageName == null || ks == null) {
24580            return false;
24581        }
24582        synchronized(mPackages) {
24583            final PackageParser.Package pkg = mPackages.get(packageName);
24584            if (pkg == null
24585                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24586                            UserHandle.getUserId(callingUid))) {
24587                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24588                throw new IllegalArgumentException("Unknown package: " + packageName);
24589            }
24590            IBinder ksh = ks.getToken();
24591            if (ksh instanceof KeySetHandle) {
24592                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24593                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
24594            }
24595            return false;
24596        }
24597    }
24598
24599    private void deletePackageIfUnusedLPr(final String packageName) {
24600        PackageSetting ps = mSettings.mPackages.get(packageName);
24601        if (ps == null) {
24602            return;
24603        }
24604        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
24605            // TODO Implement atomic delete if package is unused
24606            // It is currently possible that the package will be deleted even if it is installed
24607            // after this method returns.
24608            mHandler.post(new Runnable() {
24609                public void run() {
24610                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24611                            0, PackageManager.DELETE_ALL_USERS);
24612                }
24613            });
24614        }
24615    }
24616
24617    /**
24618     * Check and throw if the given before/after packages would be considered a
24619     * downgrade.
24620     */
24621    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
24622            throws PackageManagerException {
24623        if (after.versionCode < before.mVersionCode) {
24624            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24625                    "Update version code " + after.versionCode + " is older than current "
24626                    + before.mVersionCode);
24627        } else if (after.versionCode == before.mVersionCode) {
24628            if (after.baseRevisionCode < before.baseRevisionCode) {
24629                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24630                        "Update base revision code " + after.baseRevisionCode
24631                        + " is older than current " + before.baseRevisionCode);
24632            }
24633
24634            if (!ArrayUtils.isEmpty(after.splitNames)) {
24635                for (int i = 0; i < after.splitNames.length; i++) {
24636                    final String splitName = after.splitNames[i];
24637                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
24638                    if (j != -1) {
24639                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
24640                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24641                                    "Update split " + splitName + " revision code "
24642                                    + after.splitRevisionCodes[i] + " is older than current "
24643                                    + before.splitRevisionCodes[j]);
24644                        }
24645                    }
24646                }
24647            }
24648        }
24649    }
24650
24651    private static class MoveCallbacks extends Handler {
24652        private static final int MSG_CREATED = 1;
24653        private static final int MSG_STATUS_CHANGED = 2;
24654
24655        private final RemoteCallbackList<IPackageMoveObserver>
24656                mCallbacks = new RemoteCallbackList<>();
24657
24658        private final SparseIntArray mLastStatus = new SparseIntArray();
24659
24660        public MoveCallbacks(Looper looper) {
24661            super(looper);
24662        }
24663
24664        public void register(IPackageMoveObserver callback) {
24665            mCallbacks.register(callback);
24666        }
24667
24668        public void unregister(IPackageMoveObserver callback) {
24669            mCallbacks.unregister(callback);
24670        }
24671
24672        @Override
24673        public void handleMessage(Message msg) {
24674            final SomeArgs args = (SomeArgs) msg.obj;
24675            final int n = mCallbacks.beginBroadcast();
24676            for (int i = 0; i < n; i++) {
24677                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
24678                try {
24679                    invokeCallback(callback, msg.what, args);
24680                } catch (RemoteException ignored) {
24681                }
24682            }
24683            mCallbacks.finishBroadcast();
24684            args.recycle();
24685        }
24686
24687        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
24688                throws RemoteException {
24689            switch (what) {
24690                case MSG_CREATED: {
24691                    callback.onCreated(args.argi1, (Bundle) args.arg2);
24692                    break;
24693                }
24694                case MSG_STATUS_CHANGED: {
24695                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
24696                    break;
24697                }
24698            }
24699        }
24700
24701        private void notifyCreated(int moveId, Bundle extras) {
24702            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
24703
24704            final SomeArgs args = SomeArgs.obtain();
24705            args.argi1 = moveId;
24706            args.arg2 = extras;
24707            obtainMessage(MSG_CREATED, args).sendToTarget();
24708        }
24709
24710        private void notifyStatusChanged(int moveId, int status) {
24711            notifyStatusChanged(moveId, status, -1);
24712        }
24713
24714        private void notifyStatusChanged(int moveId, int status, long estMillis) {
24715            Slog.v(TAG, "Move " + moveId + " status " + status);
24716
24717            final SomeArgs args = SomeArgs.obtain();
24718            args.argi1 = moveId;
24719            args.argi2 = status;
24720            args.arg3 = estMillis;
24721            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24722
24723            synchronized (mLastStatus) {
24724                mLastStatus.put(moveId, status);
24725            }
24726        }
24727    }
24728
24729    private final static class OnPermissionChangeListeners extends Handler {
24730        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24731
24732        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24733                new RemoteCallbackList<>();
24734
24735        public OnPermissionChangeListeners(Looper looper) {
24736            super(looper);
24737        }
24738
24739        @Override
24740        public void handleMessage(Message msg) {
24741            switch (msg.what) {
24742                case MSG_ON_PERMISSIONS_CHANGED: {
24743                    final int uid = msg.arg1;
24744                    handleOnPermissionsChanged(uid);
24745                } break;
24746            }
24747        }
24748
24749        public void addListenerLocked(IOnPermissionsChangeListener listener) {
24750            mPermissionListeners.register(listener);
24751
24752        }
24753
24754        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24755            mPermissionListeners.unregister(listener);
24756        }
24757
24758        public void onPermissionsChanged(int uid) {
24759            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24760                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24761            }
24762        }
24763
24764        private void handleOnPermissionsChanged(int uid) {
24765            final int count = mPermissionListeners.beginBroadcast();
24766            try {
24767                for (int i = 0; i < count; i++) {
24768                    IOnPermissionsChangeListener callback = mPermissionListeners
24769                            .getBroadcastItem(i);
24770                    try {
24771                        callback.onPermissionsChanged(uid);
24772                    } catch (RemoteException e) {
24773                        Log.e(TAG, "Permission listener is dead", e);
24774                    }
24775                }
24776            } finally {
24777                mPermissionListeners.finishBroadcast();
24778            }
24779        }
24780    }
24781
24782    private class PackageManagerInternalImpl extends PackageManagerInternal {
24783        @Override
24784        public void setLocationPackagesProvider(PackagesProvider provider) {
24785            synchronized (mPackages) {
24786                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
24787            }
24788        }
24789
24790        @Override
24791        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24792            synchronized (mPackages) {
24793                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
24794            }
24795        }
24796
24797        @Override
24798        public void setSmsAppPackagesProvider(PackagesProvider provider) {
24799            synchronized (mPackages) {
24800                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
24801            }
24802        }
24803
24804        @Override
24805        public void setDialerAppPackagesProvider(PackagesProvider provider) {
24806            synchronized (mPackages) {
24807                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
24808            }
24809        }
24810
24811        @Override
24812        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24813            synchronized (mPackages) {
24814                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
24815            }
24816        }
24817
24818        @Override
24819        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24820            synchronized (mPackages) {
24821                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
24822            }
24823        }
24824
24825        @Override
24826        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24827            synchronized (mPackages) {
24828                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
24829                        packageName, userId);
24830            }
24831        }
24832
24833        @Override
24834        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24835            synchronized (mPackages) {
24836                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24837                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
24838                        packageName, userId);
24839            }
24840        }
24841
24842        @Override
24843        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24844            synchronized (mPackages) {
24845                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
24846                        packageName, userId);
24847            }
24848        }
24849
24850        @Override
24851        public void setKeepUninstalledPackages(final List<String> packageList) {
24852            Preconditions.checkNotNull(packageList);
24853            List<String> removedFromList = null;
24854            synchronized (mPackages) {
24855                if (mKeepUninstalledPackages != null) {
24856                    final int packagesCount = mKeepUninstalledPackages.size();
24857                    for (int i = 0; i < packagesCount; i++) {
24858                        String oldPackage = mKeepUninstalledPackages.get(i);
24859                        if (packageList != null && packageList.contains(oldPackage)) {
24860                            continue;
24861                        }
24862                        if (removedFromList == null) {
24863                            removedFromList = new ArrayList<>();
24864                        }
24865                        removedFromList.add(oldPackage);
24866                    }
24867                }
24868                mKeepUninstalledPackages = new ArrayList<>(packageList);
24869                if (removedFromList != null) {
24870                    final int removedCount = removedFromList.size();
24871                    for (int i = 0; i < removedCount; i++) {
24872                        deletePackageIfUnusedLPr(removedFromList.get(i));
24873                    }
24874                }
24875            }
24876        }
24877
24878        @Override
24879        public boolean isPermissionsReviewRequired(String packageName, int userId) {
24880            synchronized (mPackages) {
24881                // If we do not support permission review, done.
24882                if (!mPermissionReviewRequired) {
24883                    return false;
24884                }
24885
24886                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24887                if (packageSetting == null) {
24888                    return false;
24889                }
24890
24891                // Permission review applies only to apps not supporting the new permission model.
24892                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
24893                    return false;
24894                }
24895
24896                // Legacy apps have the permission and get user consent on launch.
24897                PermissionsState permissionsState = packageSetting.getPermissionsState();
24898                return permissionsState.isPermissionReviewRequired(userId);
24899            }
24900        }
24901
24902        @Override
24903        public PackageInfo getPackageInfo(
24904                String packageName, int flags, int filterCallingUid, int userId) {
24905            return PackageManagerService.this
24906                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24907                            flags, filterCallingUid, userId);
24908        }
24909
24910        @Override
24911        public ApplicationInfo getApplicationInfo(
24912                String packageName, int flags, int filterCallingUid, int userId) {
24913            return PackageManagerService.this
24914                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24915        }
24916
24917        @Override
24918        public ActivityInfo getActivityInfo(
24919                ComponentName component, int flags, int filterCallingUid, int userId) {
24920            return PackageManagerService.this
24921                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24922        }
24923
24924        @Override
24925        public List<ResolveInfo> queryIntentActivities(
24926                Intent intent, int flags, int filterCallingUid, int userId) {
24927            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24928            return PackageManagerService.this
24929                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24930                            userId, false /*resolveForStart*/);
24931        }
24932
24933        @Override
24934        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24935                int userId) {
24936            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24937        }
24938
24939        @Override
24940        public void setDeviceAndProfileOwnerPackages(
24941                int deviceOwnerUserId, String deviceOwnerPackage,
24942                SparseArray<String> profileOwnerPackages) {
24943            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24944                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24945        }
24946
24947        @Override
24948        public boolean isPackageDataProtected(int userId, String packageName) {
24949            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24950        }
24951
24952        @Override
24953        public boolean isPackageEphemeral(int userId, String packageName) {
24954            synchronized (mPackages) {
24955                final PackageSetting ps = mSettings.mPackages.get(packageName);
24956                return ps != null ? ps.getInstantApp(userId) : false;
24957            }
24958        }
24959
24960        @Override
24961        public boolean wasPackageEverLaunched(String packageName, int userId) {
24962            synchronized (mPackages) {
24963                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24964            }
24965        }
24966
24967        @Override
24968        public void grantRuntimePermission(String packageName, String name, int userId,
24969                boolean overridePolicy) {
24970            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
24971                    overridePolicy);
24972        }
24973
24974        @Override
24975        public void revokeRuntimePermission(String packageName, String name, int userId,
24976                boolean overridePolicy) {
24977            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
24978                    overridePolicy);
24979        }
24980
24981        @Override
24982        public String getNameForUid(int uid) {
24983            return PackageManagerService.this.getNameForUid(uid);
24984        }
24985
24986        @Override
24987        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24988                Intent origIntent, String resolvedType, String callingPackage,
24989                Bundle verificationBundle, int userId) {
24990            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24991                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24992                    userId);
24993        }
24994
24995        @Override
24996        public void grantEphemeralAccess(int userId, Intent intent,
24997                int targetAppId, int ephemeralAppId) {
24998            synchronized (mPackages) {
24999                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
25000                        targetAppId, ephemeralAppId);
25001            }
25002        }
25003
25004        @Override
25005        public boolean isInstantAppInstallerComponent(ComponentName component) {
25006            synchronized (mPackages) {
25007                return mInstantAppInstallerActivity != null
25008                        && mInstantAppInstallerActivity.getComponentName().equals(component);
25009            }
25010        }
25011
25012        @Override
25013        public void pruneInstantApps() {
25014            mInstantAppRegistry.pruneInstantApps();
25015        }
25016
25017        @Override
25018        public String getSetupWizardPackageName() {
25019            return mSetupWizardPackage;
25020        }
25021
25022        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25023            if (policy != null) {
25024                mExternalSourcesPolicy = policy;
25025            }
25026        }
25027
25028        @Override
25029        public boolean isPackagePersistent(String packageName) {
25030            synchronized (mPackages) {
25031                PackageParser.Package pkg = mPackages.get(packageName);
25032                return pkg != null
25033                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25034                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
25035                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25036                        : false;
25037            }
25038        }
25039
25040        @Override
25041        public List<PackageInfo> getOverlayPackages(int userId) {
25042            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25043            synchronized (mPackages) {
25044                for (PackageParser.Package p : mPackages.values()) {
25045                    if (p.mOverlayTarget != null) {
25046                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25047                        if (pkg != null) {
25048                            overlayPackages.add(pkg);
25049                        }
25050                    }
25051                }
25052            }
25053            return overlayPackages;
25054        }
25055
25056        @Override
25057        public List<String> getTargetPackageNames(int userId) {
25058            List<String> targetPackages = new ArrayList<>();
25059            synchronized (mPackages) {
25060                for (PackageParser.Package p : mPackages.values()) {
25061                    if (p.mOverlayTarget == null) {
25062                        targetPackages.add(p.packageName);
25063                    }
25064                }
25065            }
25066            return targetPackages;
25067        }
25068
25069        @Override
25070        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25071                @Nullable List<String> overlayPackageNames) {
25072            synchronized (mPackages) {
25073                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25074                    Slog.e(TAG, "failed to find package " + targetPackageName);
25075                    return false;
25076                }
25077                ArrayList<String> overlayPaths = null;
25078                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25079                    final int N = overlayPackageNames.size();
25080                    overlayPaths = new ArrayList<>(N);
25081                    for (int i = 0; i < N; i++) {
25082                        final String packageName = overlayPackageNames.get(i);
25083                        final PackageParser.Package pkg = mPackages.get(packageName);
25084                        if (pkg == null) {
25085                            Slog.e(TAG, "failed to find package " + packageName);
25086                            return false;
25087                        }
25088                        overlayPaths.add(pkg.baseCodePath);
25089                    }
25090                }
25091
25092                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25093                ps.setOverlayPaths(overlayPaths, userId);
25094                return true;
25095            }
25096        }
25097
25098        @Override
25099        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25100                int flags, int userId) {
25101            return resolveIntentInternal(
25102                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
25103        }
25104
25105        @Override
25106        public ResolveInfo resolveService(Intent intent, String resolvedType,
25107                int flags, int userId, int callingUid) {
25108            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25109        }
25110
25111        @Override
25112        public void addIsolatedUid(int isolatedUid, int ownerUid) {
25113            synchronized (mPackages) {
25114                mIsolatedOwners.put(isolatedUid, ownerUid);
25115            }
25116        }
25117
25118        @Override
25119        public void removeIsolatedUid(int isolatedUid) {
25120            synchronized (mPackages) {
25121                mIsolatedOwners.delete(isolatedUid);
25122            }
25123        }
25124
25125        @Override
25126        public int getUidTargetSdkVersion(int uid) {
25127            synchronized (mPackages) {
25128                return getUidTargetSdkVersionLockedLPr(uid);
25129            }
25130        }
25131
25132        @Override
25133        public boolean canAccessInstantApps(int callingUid, int userId) {
25134            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25135        }
25136    }
25137
25138    @Override
25139    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25140        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25141        synchronized (mPackages) {
25142            final long identity = Binder.clearCallingIdentity();
25143            try {
25144                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25145                        packageNames, userId);
25146            } finally {
25147                Binder.restoreCallingIdentity(identity);
25148            }
25149        }
25150    }
25151
25152    @Override
25153    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25154        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25155        synchronized (mPackages) {
25156            final long identity = Binder.clearCallingIdentity();
25157            try {
25158                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25159                        packageNames, userId);
25160            } finally {
25161                Binder.restoreCallingIdentity(identity);
25162            }
25163        }
25164    }
25165
25166    private static void enforceSystemOrPhoneCaller(String tag) {
25167        int callingUid = Binder.getCallingUid();
25168        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25169            throw new SecurityException(
25170                    "Cannot call " + tag + " from UID " + callingUid);
25171        }
25172    }
25173
25174    boolean isHistoricalPackageUsageAvailable() {
25175        return mPackageUsage.isHistoricalPackageUsageAvailable();
25176    }
25177
25178    /**
25179     * Return a <b>copy</b> of the collection of packages known to the package manager.
25180     * @return A copy of the values of mPackages.
25181     */
25182    Collection<PackageParser.Package> getPackages() {
25183        synchronized (mPackages) {
25184            return new ArrayList<>(mPackages.values());
25185        }
25186    }
25187
25188    /**
25189     * Logs process start information (including base APK hash) to the security log.
25190     * @hide
25191     */
25192    @Override
25193    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25194            String apkFile, int pid) {
25195        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25196            return;
25197        }
25198        if (!SecurityLog.isLoggingEnabled()) {
25199            return;
25200        }
25201        Bundle data = new Bundle();
25202        data.putLong("startTimestamp", System.currentTimeMillis());
25203        data.putString("processName", processName);
25204        data.putInt("uid", uid);
25205        data.putString("seinfo", seinfo);
25206        data.putString("apkFile", apkFile);
25207        data.putInt("pid", pid);
25208        Message msg = mProcessLoggingHandler.obtainMessage(
25209                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25210        msg.setData(data);
25211        mProcessLoggingHandler.sendMessage(msg);
25212    }
25213
25214    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25215        return mCompilerStats.getPackageStats(pkgName);
25216    }
25217
25218    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25219        return getOrCreateCompilerPackageStats(pkg.packageName);
25220    }
25221
25222    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25223        return mCompilerStats.getOrCreatePackageStats(pkgName);
25224    }
25225
25226    public void deleteCompilerPackageStats(String pkgName) {
25227        mCompilerStats.deletePackageStats(pkgName);
25228    }
25229
25230    @Override
25231    public int getInstallReason(String packageName, int userId) {
25232        final int callingUid = Binder.getCallingUid();
25233        enforceCrossUserPermission(callingUid, userId,
25234                true /* requireFullPermission */, false /* checkShell */,
25235                "get install reason");
25236        synchronized (mPackages) {
25237            final PackageSetting ps = mSettings.mPackages.get(packageName);
25238            if (filterAppAccessLPr(ps, callingUid, userId)) {
25239                return PackageManager.INSTALL_REASON_UNKNOWN;
25240            }
25241            if (ps != null) {
25242                return ps.getInstallReason(userId);
25243            }
25244        }
25245        return PackageManager.INSTALL_REASON_UNKNOWN;
25246    }
25247
25248    @Override
25249    public boolean canRequestPackageInstalls(String packageName, int userId) {
25250        return canRequestPackageInstallsInternal(packageName, 0, userId,
25251                true /* throwIfPermNotDeclared*/);
25252    }
25253
25254    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25255            boolean throwIfPermNotDeclared) {
25256        int callingUid = Binder.getCallingUid();
25257        int uid = getPackageUid(packageName, 0, userId);
25258        if (callingUid != uid && callingUid != Process.ROOT_UID
25259                && callingUid != Process.SYSTEM_UID) {
25260            throw new SecurityException(
25261                    "Caller uid " + callingUid + " does not own package " + packageName);
25262        }
25263        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25264        if (info == null) {
25265            return false;
25266        }
25267        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25268            return false;
25269        }
25270        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25271        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25272        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25273            if (throwIfPermNotDeclared) {
25274                throw new SecurityException("Need to declare " + appOpPermission
25275                        + " to call this api");
25276            } else {
25277                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25278                return false;
25279            }
25280        }
25281        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25282            return false;
25283        }
25284        if (mExternalSourcesPolicy != null) {
25285            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25286            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
25287                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25288            }
25289        }
25290        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
25291    }
25292
25293    @Override
25294    public ComponentName getInstantAppResolverSettingsComponent() {
25295        return mInstantAppResolverSettingsComponent;
25296    }
25297
25298    @Override
25299    public ComponentName getInstantAppInstallerComponent() {
25300        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25301            return null;
25302        }
25303        return mInstantAppInstallerActivity == null
25304                ? null : mInstantAppInstallerActivity.getComponentName();
25305    }
25306
25307    @Override
25308    public String getInstantAppAndroidId(String packageName, int userId) {
25309        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25310                "getInstantAppAndroidId");
25311        enforceCrossUserPermission(Binder.getCallingUid(), userId,
25312                true /* requireFullPermission */, false /* checkShell */,
25313                "getInstantAppAndroidId");
25314        // Make sure the target is an Instant App.
25315        if (!isInstantApp(packageName, userId)) {
25316            return null;
25317        }
25318        synchronized (mPackages) {
25319            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25320        }
25321    }
25322
25323    boolean canHaveOatDir(String packageName) {
25324        synchronized (mPackages) {
25325            PackageParser.Package p = mPackages.get(packageName);
25326            if (p == null) {
25327                return false;
25328            }
25329            return p.canHaveOatDir();
25330        }
25331    }
25332
25333    private String getOatDir(PackageParser.Package pkg) {
25334        if (!pkg.canHaveOatDir()) {
25335            return null;
25336        }
25337        File codePath = new File(pkg.codePath);
25338        if (codePath.isDirectory()) {
25339            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25340        }
25341        return null;
25342    }
25343
25344    void deleteOatArtifactsOfPackage(String packageName) {
25345        final String[] instructionSets;
25346        final List<String> codePaths;
25347        final String oatDir;
25348        final PackageParser.Package pkg;
25349        synchronized (mPackages) {
25350            pkg = mPackages.get(packageName);
25351        }
25352        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25353        codePaths = pkg.getAllCodePaths();
25354        oatDir = getOatDir(pkg);
25355
25356        for (String codePath : codePaths) {
25357            for (String isa : instructionSets) {
25358                try {
25359                    mInstaller.deleteOdex(codePath, isa, oatDir);
25360                } catch (InstallerException e) {
25361                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25362                }
25363            }
25364        }
25365    }
25366
25367    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25368        Set<String> unusedPackages = new HashSet<>();
25369        long currentTimeInMillis = System.currentTimeMillis();
25370        synchronized (mPackages) {
25371            for (PackageParser.Package pkg : mPackages.values()) {
25372                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
25373                if (ps == null) {
25374                    continue;
25375                }
25376                PackageDexUsage.PackageUseInfo packageUseInfo = getDexManager().getPackageUseInfo(
25377                        pkg.packageName);
25378                if (PackageManagerServiceUtils
25379                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25380                                downgradeTimeThresholdMillis, packageUseInfo,
25381                                pkg.getLatestPackageUseTimeInMills(),
25382                                pkg.getLatestForegroundPackageUseTimeInMills())) {
25383                    unusedPackages.add(pkg.packageName);
25384                }
25385            }
25386        }
25387        return unusedPackages;
25388    }
25389}
25390
25391interface PackageSender {
25392    void sendPackageBroadcast(final String action, final String pkg,
25393        final Bundle extras, final int flags, final String targetPkg,
25394        final IIntentReceiver finishedReceiver, final int[] userIds);
25395    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25396        boolean includeStopped, int appId, int... userIds);
25397}
25398