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.os.storage.StorageManager.FLAG_STORAGE_CE;
89import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
90import static android.system.OsConstants.O_CREAT;
91import static android.system.OsConstants.O_RDWR;
92
93import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
94import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
95import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
96import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
97import static com.android.internal.util.ArrayUtils.appendInt;
98import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
99import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
100import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
101import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
102import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
103import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
104import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
105import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
106import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
107import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
108
109import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
110
111import android.Manifest;
112import android.annotation.IntDef;
113import android.annotation.NonNull;
114import android.annotation.Nullable;
115import android.app.ActivityManager;
116import android.app.AppOpsManager;
117import android.app.IActivityManager;
118import android.app.ResourcesManager;
119import android.app.admin.IDevicePolicyManager;
120import android.app.admin.SecurityLog;
121import android.app.backup.IBackupManager;
122import android.content.BroadcastReceiver;
123import android.content.ComponentName;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.IIntentReceiver;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.IntentSender.SendIntentException;
131import android.content.ServiceConnection;
132import android.content.pm.ActivityInfo;
133import android.content.pm.ApplicationInfo;
134import android.content.pm.AppsQueryHelper;
135import android.content.pm.AuxiliaryResolveInfo;
136import android.content.pm.ChangedPackages;
137import android.content.pm.ComponentInfo;
138import android.content.pm.FallbackCategoryProvider;
139import android.content.pm.FeatureInfo;
140import android.content.pm.IDexModuleRegisterCallback;
141import android.content.pm.IOnPermissionsChangeListener;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageDeleteObserver;
144import android.content.pm.IPackageDeleteObserver2;
145import android.content.pm.IPackageInstallObserver2;
146import android.content.pm.IPackageInstaller;
147import android.content.pm.IPackageManager;
148import android.content.pm.IPackageManagerNative;
149import android.content.pm.IPackageMoveObserver;
150import android.content.pm.IPackageStatsObserver;
151import android.content.pm.InstantAppInfo;
152import android.content.pm.InstantAppRequest;
153import android.content.pm.InstantAppResolveInfo;
154import android.content.pm.InstrumentationInfo;
155import android.content.pm.IntentFilterVerificationInfo;
156import android.content.pm.KeySet;
157import android.content.pm.PackageCleanItem;
158import android.content.pm.PackageInfo;
159import android.content.pm.PackageInfoLite;
160import android.content.pm.PackageInstaller;
161import android.content.pm.PackageManager;
162import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
163import android.content.pm.PackageManagerInternal;
164import android.content.pm.PackageParser;
165import android.content.pm.PackageParser.ActivityIntentInfo;
166import android.content.pm.PackageParser.PackageLite;
167import android.content.pm.PackageParser.PackageParserException;
168import android.content.pm.PackageStats;
169import android.content.pm.PackageUserState;
170import android.content.pm.ParceledListSlice;
171import android.content.pm.PermissionGroupInfo;
172import android.content.pm.PermissionInfo;
173import android.content.pm.ProviderInfo;
174import android.content.pm.ResolveInfo;
175import android.content.pm.ServiceInfo;
176import android.content.pm.SharedLibraryInfo;
177import android.content.pm.Signature;
178import android.content.pm.UserInfo;
179import android.content.pm.VerifierDeviceIdentity;
180import android.content.pm.VerifierInfo;
181import android.content.pm.VersionedPackage;
182import android.content.res.Resources;
183import android.database.ContentObserver;
184import android.graphics.Bitmap;
185import android.hardware.display.DisplayManager;
186import android.net.Uri;
187import android.os.AsyncTask;
188import android.os.Binder;
189import android.os.Build;
190import android.os.Bundle;
191import android.os.Debug;
192import android.os.Environment;
193import android.os.Environment.UserEnvironment;
194import android.os.FileUtils;
195import android.os.Handler;
196import android.os.IBinder;
197import android.os.Looper;
198import android.os.Message;
199import android.os.Parcel;
200import android.os.ParcelFileDescriptor;
201import android.os.PatternMatcher;
202import android.os.Process;
203import android.os.RemoteCallbackList;
204import android.os.RemoteException;
205import android.os.ResultReceiver;
206import android.os.SELinux;
207import android.os.ServiceManager;
208import android.os.ShellCallback;
209import android.os.SystemClock;
210import android.os.SystemProperties;
211import android.os.Trace;
212import android.os.UserHandle;
213import android.os.UserManager;
214import android.os.UserManagerInternal;
215import android.os.storage.IStorageManager;
216import android.os.storage.StorageEventListener;
217import android.os.storage.StorageManager;
218import android.os.storage.StorageManagerInternal;
219import android.os.storage.VolumeInfo;
220import android.os.storage.VolumeRecord;
221import android.provider.Settings.Global;
222import android.provider.Settings.Secure;
223import android.security.KeyStore;
224import android.security.SystemKeyStore;
225import android.service.pm.PackageServiceDumpProto;
226import android.system.ErrnoException;
227import android.system.Os;
228import android.text.TextUtils;
229import android.text.format.DateUtils;
230import android.util.ArrayMap;
231import android.util.ArraySet;
232import android.util.Base64;
233import android.util.TimingsTraceLog;
234import android.util.DisplayMetrics;
235import android.util.EventLog;
236import android.util.ExceptionUtils;
237import android.util.Log;
238import android.util.LogPrinter;
239import android.util.MathUtils;
240import android.util.PackageUtils;
241import android.util.Pair;
242import android.util.PrintStreamPrinter;
243import android.util.Slog;
244import android.util.SparseArray;
245import android.util.SparseBooleanArray;
246import android.util.SparseIntArray;
247import android.util.Xml;
248import android.util.jar.StrictJarFile;
249import android.util.proto.ProtoOutputStream;
250import android.view.Display;
251
252import com.android.internal.R;
253import com.android.internal.annotations.GuardedBy;
254import com.android.internal.app.IMediaContainerService;
255import com.android.internal.app.ResolverActivity;
256import com.android.internal.content.NativeLibraryHelper;
257import com.android.internal.content.PackageHelper;
258import com.android.internal.logging.MetricsLogger;
259import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
260import com.android.internal.os.IParcelFileDescriptorFactory;
261import com.android.internal.os.RoSystemProperties;
262import com.android.internal.os.SomeArgs;
263import com.android.internal.os.Zygote;
264import com.android.internal.telephony.CarrierAppUtils;
265import com.android.internal.util.ArrayUtils;
266import com.android.internal.util.ConcurrentUtils;
267import com.android.internal.util.DumpUtils;
268import com.android.internal.util.FastPrintWriter;
269import com.android.internal.util.FastXmlSerializer;
270import com.android.internal.util.IndentingPrintWriter;
271import com.android.internal.util.Preconditions;
272import com.android.internal.util.XmlUtils;
273import com.android.server.AttributeCache;
274import com.android.server.DeviceIdleController;
275import com.android.server.EventLogTags;
276import com.android.server.FgThread;
277import com.android.server.IntentResolver;
278import com.android.server.LocalServices;
279import com.android.server.LockGuard;
280import com.android.server.ServiceThread;
281import com.android.server.SystemConfig;
282import com.android.server.SystemServerInitThreadPool;
283import com.android.server.Watchdog;
284import com.android.server.net.NetworkPolicyManagerInternal;
285import com.android.server.pm.Installer.InstallerException;
286import com.android.server.pm.PermissionsState.PermissionState;
287import com.android.server.pm.Settings.DatabaseVersion;
288import com.android.server.pm.Settings.VersionInfo;
289import com.android.server.pm.dex.DexManager;
290import com.android.server.pm.dex.DexoptOptions;
291import com.android.server.pm.dex.PackageDexUsage;
292import com.android.server.storage.DeviceStorageMonitorInternal;
293
294import dalvik.system.CloseGuard;
295import dalvik.system.DexFile;
296import dalvik.system.VMRuntime;
297
298import libcore.io.IoUtils;
299import libcore.io.Streams;
300import libcore.util.EmptyArray;
301
302import org.xmlpull.v1.XmlPullParser;
303import org.xmlpull.v1.XmlPullParserException;
304import org.xmlpull.v1.XmlSerializer;
305
306import java.io.BufferedOutputStream;
307import java.io.BufferedReader;
308import java.io.ByteArrayInputStream;
309import java.io.ByteArrayOutputStream;
310import java.io.File;
311import java.io.FileDescriptor;
312import java.io.FileInputStream;
313import java.io.FileOutputStream;
314import java.io.FileReader;
315import java.io.FilenameFilter;
316import java.io.IOException;
317import java.io.InputStream;
318import java.io.OutputStream;
319import java.io.PrintWriter;
320import java.lang.annotation.Retention;
321import java.lang.annotation.RetentionPolicy;
322import java.nio.charset.StandardCharsets;
323import java.security.DigestInputStream;
324import java.security.MessageDigest;
325import java.security.NoSuchAlgorithmException;
326import java.security.PublicKey;
327import java.security.SecureRandom;
328import java.security.cert.Certificate;
329import java.security.cert.CertificateEncodingException;
330import java.security.cert.CertificateException;
331import java.text.SimpleDateFormat;
332import java.util.ArrayList;
333import java.util.Arrays;
334import java.util.Collection;
335import java.util.Collections;
336import java.util.Comparator;
337import java.util.Date;
338import java.util.HashMap;
339import java.util.HashSet;
340import java.util.Iterator;
341import java.util.List;
342import java.util.Map;
343import java.util.Objects;
344import java.util.Set;
345import java.util.concurrent.CountDownLatch;
346import java.util.concurrent.Future;
347import java.util.concurrent.TimeUnit;
348import java.util.concurrent.atomic.AtomicBoolean;
349import java.util.concurrent.atomic.AtomicInteger;
350import java.util.zip.GZIPInputStream;
351
352/**
353 * Keep track of all those APKs everywhere.
354 * <p>
355 * Internally there are two important locks:
356 * <ul>
357 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
358 * and other related state. It is a fine-grained lock that should only be held
359 * momentarily, as it's one of the most contended locks in the system.
360 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
361 * operations typically involve heavy lifting of application data on disk. Since
362 * {@code installd} is single-threaded, and it's operations can often be slow,
363 * this lock should never be acquired while already holding {@link #mPackages}.
364 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
365 * holding {@link #mInstallLock}.
366 * </ul>
367 * Many internal methods rely on the caller to hold the appropriate locks, and
368 * this contract is expressed through method name suffixes:
369 * <ul>
370 * <li>fooLI(): the caller must hold {@link #mInstallLock}
371 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
372 * being modified must be frozen
373 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
374 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
375 * </ul>
376 * <p>
377 * Because this class is very central to the platform's security; please run all
378 * CTS and unit tests whenever making modifications:
379 *
380 * <pre>
381 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
382 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
383 * </pre>
384 */
385public class PackageManagerService extends IPackageManager.Stub
386        implements PackageSender {
387    static final String TAG = "PackageManager";
388    static final boolean DEBUG_SETTINGS = false;
389    static final boolean DEBUG_PREFERRED = false;
390    static final boolean DEBUG_UPGRADE = false;
391    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
392    private static final boolean DEBUG_BACKUP = false;
393    private static final boolean DEBUG_INSTALL = false;
394    private static final boolean DEBUG_REMOVE = false;
395    private static final boolean DEBUG_BROADCASTS = false;
396    private static final boolean DEBUG_SHOW_INFO = false;
397    private static final boolean DEBUG_PACKAGE_INFO = false;
398    private static final boolean DEBUG_INTENT_MATCHING = false;
399    private static final boolean DEBUG_PACKAGE_SCANNING = false;
400    private static final boolean DEBUG_VERIFY = false;
401    private static final boolean DEBUG_FILTERS = false;
402    private static final boolean DEBUG_PERMISSIONS = false;
403    private static final boolean DEBUG_SHARED_LIBRARIES = false;
404    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
405
406    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
407    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
408    // user, but by default initialize to this.
409    public static final boolean DEBUG_DEXOPT = false;
410
411    private static final boolean DEBUG_ABI_SELECTION = false;
412    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
413    private static final boolean DEBUG_TRIAGED_MISSING = false;
414    private static final boolean DEBUG_APP_DATA = false;
415
416    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
417    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
418
419    private static final boolean HIDE_EPHEMERAL_APIS = false;
420
421    private static final boolean ENABLE_FREE_CACHE_V2 =
422            SystemProperties.getBoolean("fw.free_cache_v2", true);
423
424    private static final int RADIO_UID = Process.PHONE_UID;
425    private static final int LOG_UID = Process.LOG_UID;
426    private static final int NFC_UID = Process.NFC_UID;
427    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
428    private static final int SHELL_UID = Process.SHELL_UID;
429
430    // Cap the size of permission trees that 3rd party apps can define
431    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
432
433    // Suffix used during package installation when copying/moving
434    // package apks to install directory.
435    private static final String INSTALL_PACKAGE_SUFFIX = "-";
436
437    static final int SCAN_NO_DEX = 1<<1;
438    static final int SCAN_FORCE_DEX = 1<<2;
439    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
440    static final int SCAN_NEW_INSTALL = 1<<4;
441    static final int SCAN_UPDATE_TIME = 1<<5;
442    static final int SCAN_BOOTING = 1<<6;
443    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
444    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
445    static final int SCAN_REPLACING = 1<<9;
446    static final int SCAN_REQUIRE_KNOWN = 1<<10;
447    static final int SCAN_MOVE = 1<<11;
448    static final int SCAN_INITIAL = 1<<12;
449    static final int SCAN_CHECK_ONLY = 1<<13;
450    static final int SCAN_DONT_KILL_APP = 1<<14;
451    static final int SCAN_IGNORE_FROZEN = 1<<15;
452    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
453    static final int SCAN_AS_INSTANT_APP = 1<<17;
454    static final int SCAN_AS_FULL_APP = 1<<18;
455    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
456    /** Should not be with the scan flags */
457    static final int FLAGS_REMOVE_CHATTY = 1<<31;
458
459    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
460    /** Extension of the compressed packages */
461    private final static String COMPRESSED_EXTENSION = ".gz";
462    /** Suffix of stub packages on the system partition */
463    private final static String STUB_SUFFIX = "-Stub";
464
465    private static final int[] EMPTY_INT_ARRAY = new int[0];
466
467    private static final int TYPE_UNKNOWN = 0;
468    private static final int TYPE_ACTIVITY = 1;
469    private static final int TYPE_RECEIVER = 2;
470    private static final int TYPE_SERVICE = 3;
471    private static final int TYPE_PROVIDER = 4;
472    @IntDef(prefix = { "TYPE_" }, value = {
473            TYPE_UNKNOWN,
474            TYPE_ACTIVITY,
475            TYPE_RECEIVER,
476            TYPE_SERVICE,
477            TYPE_PROVIDER,
478    })
479    @Retention(RetentionPolicy.SOURCE)
480    public @interface ComponentType {}
481
482    /**
483     * Timeout (in milliseconds) after which the watchdog should declare that
484     * our handler thread is wedged.  The usual default for such things is one
485     * minute but we sometimes do very lengthy I/O operations on this thread,
486     * such as installing multi-gigabyte applications, so ours needs to be longer.
487     */
488    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
489
490    /**
491     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
492     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
493     * settings entry if available, otherwise we use the hardcoded default.  If it's been
494     * more than this long since the last fstrim, we force one during the boot sequence.
495     *
496     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
497     * one gets run at the next available charging+idle time.  This final mandatory
498     * no-fstrim check kicks in only of the other scheduling criteria is never met.
499     */
500    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
501
502    /**
503     * Whether verification is enabled by default.
504     */
505    private static final boolean DEFAULT_VERIFY_ENABLE = true;
506
507    /**
508     * The default maximum time to wait for the verification agent to return in
509     * milliseconds.
510     */
511    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
512
513    /**
514     * The default response for package verification timeout.
515     *
516     * This can be either PackageManager.VERIFICATION_ALLOW or
517     * PackageManager.VERIFICATION_REJECT.
518     */
519    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
520
521    static final String PLATFORM_PACKAGE_NAME = "android";
522
523    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
524
525    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
526            DEFAULT_CONTAINER_PACKAGE,
527            "com.android.defcontainer.DefaultContainerService");
528
529    private static final String KILL_APP_REASON_GIDS_CHANGED =
530            "permission grant or revoke changed gids";
531
532    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
533            "permissions revoked";
534
535    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
536
537    private static final String PACKAGE_SCHEME = "package";
538
539    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
540
541    /** Permission grant: not grant the permission. */
542    private static final int GRANT_DENIED = 1;
543
544    /** Permission grant: grant the permission as an install permission. */
545    private static final int GRANT_INSTALL = 2;
546
547    /** Permission grant: grant the permission as a runtime one. */
548    private static final int GRANT_RUNTIME = 3;
549
550    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
551    private static final int GRANT_UPGRADE = 4;
552
553    /** Canonical intent used to identify what counts as a "web browser" app */
554    private static final Intent sBrowserIntent;
555    static {
556        sBrowserIntent = new Intent();
557        sBrowserIntent.setAction(Intent.ACTION_VIEW);
558        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
559        sBrowserIntent.setData(Uri.parse("http:"));
560    }
561
562    /**
563     * The set of all protected actions [i.e. those actions for which a high priority
564     * intent filter is disallowed].
565     */
566    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
567    static {
568        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
569        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
570        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
571        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
572    }
573
574    // Compilation reasons.
575    public static final int REASON_FIRST_BOOT = 0;
576    public static final int REASON_BOOT = 1;
577    public static final int REASON_INSTALL = 2;
578    public static final int REASON_BACKGROUND_DEXOPT = 3;
579    public static final int REASON_AB_OTA = 4;
580    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
581    public static final int REASON_SHARED = 6;
582
583    public static final int REASON_LAST = REASON_SHARED;
584
585    /** All dangerous permission names in the same order as the events in MetricsEvent */
586    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
587            Manifest.permission.READ_CALENDAR,
588            Manifest.permission.WRITE_CALENDAR,
589            Manifest.permission.CAMERA,
590            Manifest.permission.READ_CONTACTS,
591            Manifest.permission.WRITE_CONTACTS,
592            Manifest.permission.GET_ACCOUNTS,
593            Manifest.permission.ACCESS_FINE_LOCATION,
594            Manifest.permission.ACCESS_COARSE_LOCATION,
595            Manifest.permission.RECORD_AUDIO,
596            Manifest.permission.READ_PHONE_STATE,
597            Manifest.permission.CALL_PHONE,
598            Manifest.permission.READ_CALL_LOG,
599            Manifest.permission.WRITE_CALL_LOG,
600            Manifest.permission.ADD_VOICEMAIL,
601            Manifest.permission.USE_SIP,
602            Manifest.permission.PROCESS_OUTGOING_CALLS,
603            Manifest.permission.READ_CELL_BROADCASTS,
604            Manifest.permission.BODY_SENSORS,
605            Manifest.permission.SEND_SMS,
606            Manifest.permission.RECEIVE_SMS,
607            Manifest.permission.READ_SMS,
608            Manifest.permission.RECEIVE_WAP_PUSH,
609            Manifest.permission.RECEIVE_MMS,
610            Manifest.permission.READ_EXTERNAL_STORAGE,
611            Manifest.permission.WRITE_EXTERNAL_STORAGE,
612            Manifest.permission.READ_PHONE_NUMBERS,
613            Manifest.permission.ANSWER_PHONE_CALLS);
614
615
616    /**
617     * Version number for the package parser cache. Increment this whenever the format or
618     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
619     */
620    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
621
622    /**
623     * Whether the package parser cache is enabled.
624     */
625    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
626
627    final ServiceThread mHandlerThread;
628
629    final PackageHandler mHandler;
630
631    private final ProcessLoggingHandler mProcessLoggingHandler;
632
633    /**
634     * Messages for {@link #mHandler} that need to wait for system ready before
635     * being dispatched.
636     */
637    private ArrayList<Message> mPostSystemReadyMessages;
638
639    final int mSdkVersion = Build.VERSION.SDK_INT;
640
641    final Context mContext;
642    final boolean mFactoryTest;
643    final boolean mOnlyCore;
644    final DisplayMetrics mMetrics;
645    final int mDefParseFlags;
646    final String[] mSeparateProcesses;
647    final boolean mIsUpgrade;
648    final boolean mIsPreNUpgrade;
649    final boolean mIsPreNMR1Upgrade;
650
651    // Have we told the Activity Manager to whitelist the default container service by uid yet?
652    @GuardedBy("mPackages")
653    boolean mDefaultContainerWhitelisted = false;
654
655    @GuardedBy("mPackages")
656    private boolean mDexOptDialogShown;
657
658    /** The location for ASEC container files on internal storage. */
659    final String mAsecInternalPath;
660
661    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
662    // LOCK HELD.  Can be called with mInstallLock held.
663    @GuardedBy("mInstallLock")
664    final Installer mInstaller;
665
666    /** Directory where installed third-party apps stored */
667    final File mAppInstallDir;
668
669    /**
670     * Directory to which applications installed internally have their
671     * 32 bit native libraries copied.
672     */
673    private File mAppLib32InstallDir;
674
675    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
676    // apps.
677    final File mDrmAppPrivateInstallDir;
678
679    // ----------------------------------------------------------------
680
681    // Lock for state used when installing and doing other long running
682    // operations.  Methods that must be called with this lock held have
683    // the suffix "LI".
684    final Object mInstallLock = new Object();
685
686    // ----------------------------------------------------------------
687
688    // Keys are String (package name), values are Package.  This also serves
689    // as the lock for the global state.  Methods that must be called with
690    // this lock held have the prefix "LP".
691    @GuardedBy("mPackages")
692    final ArrayMap<String, PackageParser.Package> mPackages =
693            new ArrayMap<String, PackageParser.Package>();
694
695    final ArrayMap<String, Set<String>> mKnownCodebase =
696            new ArrayMap<String, Set<String>>();
697
698    // Keys are isolated uids and values are the uid of the application
699    // that created the isolated proccess.
700    @GuardedBy("mPackages")
701    final SparseIntArray mIsolatedOwners = new SparseIntArray();
702
703    /**
704     * Tracks new system packages [received in an OTA] that we expect to
705     * find updated user-installed versions. Keys are package name, values
706     * are package location.
707     */
708    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
709    /**
710     * Tracks high priority intent filters for protected actions. During boot, certain
711     * filter actions are protected and should never be allowed to have a high priority
712     * intent filter for them. However, there is one, and only one exception -- the
713     * setup wizard. It must be able to define a high priority intent filter for these
714     * actions to ensure there are no escapes from the wizard. We need to delay processing
715     * of these during boot as we need to look at all of the system packages in order
716     * to know which component is the setup wizard.
717     */
718    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
719    /**
720     * Whether or not processing protected filters should be deferred.
721     */
722    private boolean mDeferProtectedFilters = true;
723
724    /**
725     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
726     */
727    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
728    /**
729     * Whether or not system app permissions should be promoted from install to runtime.
730     */
731    boolean mPromoteSystemApps;
732
733    @GuardedBy("mPackages")
734    final Settings mSettings;
735
736    /**
737     * Set of package names that are currently "frozen", which means active
738     * surgery is being done on the code/data for that package. The platform
739     * will refuse to launch frozen packages to avoid race conditions.
740     *
741     * @see PackageFreezer
742     */
743    @GuardedBy("mPackages")
744    final ArraySet<String> mFrozenPackages = new ArraySet<>();
745
746    final ProtectedPackages mProtectedPackages;
747
748    @GuardedBy("mLoadedVolumes")
749    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
750
751    boolean mFirstBoot;
752
753    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
754
755    // System configuration read by SystemConfig.
756    final int[] mGlobalGids;
757    final SparseArray<ArraySet<String>> mSystemPermissions;
758    @GuardedBy("mAvailableFeatures")
759    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
760
761    // If mac_permissions.xml was found for seinfo labeling.
762    boolean mFoundPolicyFile;
763
764    private final InstantAppRegistry mInstantAppRegistry;
765
766    @GuardedBy("mPackages")
767    int mChangedPackagesSequenceNumber;
768    /**
769     * List of changed [installed, removed or updated] packages.
770     * mapping from user id -> sequence number -> package name
771     */
772    @GuardedBy("mPackages")
773    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
774    /**
775     * The sequence number of the last change to a package.
776     * mapping from user id -> package name -> sequence number
777     */
778    @GuardedBy("mPackages")
779    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
780
781    class PackageParserCallback implements PackageParser.Callback {
782        @Override public final boolean hasFeature(String feature) {
783            return PackageManagerService.this.hasSystemFeature(feature, 0);
784        }
785
786        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
787                Collection<PackageParser.Package> allPackages, String targetPackageName) {
788            List<PackageParser.Package> overlayPackages = null;
789            for (PackageParser.Package p : allPackages) {
790                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
791                    if (overlayPackages == null) {
792                        overlayPackages = new ArrayList<PackageParser.Package>();
793                    }
794                    overlayPackages.add(p);
795                }
796            }
797            if (overlayPackages != null) {
798                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
799                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
800                        return p1.mOverlayPriority - p2.mOverlayPriority;
801                    }
802                };
803                Collections.sort(overlayPackages, cmp);
804            }
805            return overlayPackages;
806        }
807
808        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
809                String targetPackageName, String targetPath) {
810            if ("android".equals(targetPackageName)) {
811                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
812                // native AssetManager.
813                return null;
814            }
815            List<PackageParser.Package> overlayPackages =
816                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
817            if (overlayPackages == null || overlayPackages.isEmpty()) {
818                return null;
819            }
820            List<String> overlayPathList = null;
821            for (PackageParser.Package overlayPackage : overlayPackages) {
822                if (targetPath == null) {
823                    if (overlayPathList == null) {
824                        overlayPathList = new ArrayList<String>();
825                    }
826                    overlayPathList.add(overlayPackage.baseCodePath);
827                    continue;
828                }
829
830                try {
831                    // Creates idmaps for system to parse correctly the Android manifest of the
832                    // target package.
833                    //
834                    // OverlayManagerService will update each of them with a correct gid from its
835                    // target package app id.
836                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
837                            UserHandle.getSharedAppGid(
838                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
839                    if (overlayPathList == null) {
840                        overlayPathList = new ArrayList<String>();
841                    }
842                    overlayPathList.add(overlayPackage.baseCodePath);
843                } catch (InstallerException e) {
844                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
845                            overlayPackage.baseCodePath);
846                }
847            }
848            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
849        }
850
851        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
852            synchronized (mPackages) {
853                return getStaticOverlayPathsLocked(
854                        mPackages.values(), targetPackageName, targetPath);
855            }
856        }
857
858        @Override public final String[] getOverlayApks(String targetPackageName) {
859            return getStaticOverlayPaths(targetPackageName, null);
860        }
861
862        @Override public final String[] getOverlayPaths(String targetPackageName,
863                String targetPath) {
864            return getStaticOverlayPaths(targetPackageName, targetPath);
865        }
866    };
867
868    class ParallelPackageParserCallback extends PackageParserCallback {
869        List<PackageParser.Package> mOverlayPackages = null;
870
871        void findStaticOverlayPackages() {
872            synchronized (mPackages) {
873                for (PackageParser.Package p : mPackages.values()) {
874                    if (p.mIsStaticOverlay) {
875                        if (mOverlayPackages == null) {
876                            mOverlayPackages = new ArrayList<PackageParser.Package>();
877                        }
878                        mOverlayPackages.add(p);
879                    }
880                }
881            }
882        }
883
884        @Override
885        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
886            // We can trust mOverlayPackages without holding mPackages because package uninstall
887            // can't happen while running parallel parsing.
888            // Moreover holding mPackages on each parsing thread causes dead-lock.
889            return mOverlayPackages == null ? null :
890                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
891        }
892    }
893
894    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
895    final ParallelPackageParserCallback mParallelPackageParserCallback =
896            new ParallelPackageParserCallback();
897
898    public static final class SharedLibraryEntry {
899        public final @Nullable String path;
900        public final @Nullable String apk;
901        public final @NonNull SharedLibraryInfo info;
902
903        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
904                String declaringPackageName, int declaringPackageVersionCode) {
905            path = _path;
906            apk = _apk;
907            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
908                    declaringPackageName, declaringPackageVersionCode), null);
909        }
910    }
911
912    // Currently known shared libraries.
913    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
914    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
915            new ArrayMap<>();
916
917    // All available activities, for your resolving pleasure.
918    final ActivityIntentResolver mActivities =
919            new ActivityIntentResolver();
920
921    // All available receivers, for your resolving pleasure.
922    final ActivityIntentResolver mReceivers =
923            new ActivityIntentResolver();
924
925    // All available services, for your resolving pleasure.
926    final ServiceIntentResolver mServices = new ServiceIntentResolver();
927
928    // All available providers, for your resolving pleasure.
929    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
930
931    // Mapping from provider base names (first directory in content URI codePath)
932    // to the provider information.
933    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
934            new ArrayMap<String, PackageParser.Provider>();
935
936    // Mapping from instrumentation class names to info about them.
937    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
938            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
939
940    // Mapping from permission names to info about them.
941    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
942            new ArrayMap<String, PackageParser.PermissionGroup>();
943
944    // Packages whose data we have transfered into another package, thus
945    // should no longer exist.
946    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
947
948    // Broadcast actions that are only available to the system.
949    @GuardedBy("mProtectedBroadcasts")
950    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
951
952    /** List of packages waiting for verification. */
953    final SparseArray<PackageVerificationState> mPendingVerification
954            = new SparseArray<PackageVerificationState>();
955
956    /** Set of packages associated with each app op permission. */
957    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
958
959    final PackageInstallerService mInstallerService;
960
961    private final PackageDexOptimizer mPackageDexOptimizer;
962    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
963    // is used by other apps).
964    private final DexManager mDexManager;
965
966    private AtomicInteger mNextMoveId = new AtomicInteger();
967    private final MoveCallbacks mMoveCallbacks;
968
969    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
970
971    // Cache of users who need badging.
972    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
973
974    /** Token for keys in mPendingVerification. */
975    private int mPendingVerificationToken = 0;
976
977    volatile boolean mSystemReady;
978    volatile boolean mSafeMode;
979    volatile boolean mHasSystemUidErrors;
980    private volatile boolean mEphemeralAppsDisabled;
981
982    ApplicationInfo mAndroidApplication;
983    final ActivityInfo mResolveActivity = new ActivityInfo();
984    final ResolveInfo mResolveInfo = new ResolveInfo();
985    ComponentName mResolveComponentName;
986    PackageParser.Package mPlatformPackage;
987    ComponentName mCustomResolverComponentName;
988
989    boolean mResolverReplaced = false;
990
991    private final @Nullable ComponentName mIntentFilterVerifierComponent;
992    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
993
994    private int mIntentFilterVerificationToken = 0;
995
996    /** The service connection to the ephemeral resolver */
997    final EphemeralResolverConnection mInstantAppResolverConnection;
998    /** Component used to show resolver settings for Instant Apps */
999    final ComponentName mInstantAppResolverSettingsComponent;
1000
1001    /** Activity used to install instant applications */
1002    ActivityInfo mInstantAppInstallerActivity;
1003    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1004
1005    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1006            = new SparseArray<IntentFilterVerificationState>();
1007
1008    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1009
1010    // List of packages names to keep cached, even if they are uninstalled for all users
1011    private List<String> mKeepUninstalledPackages;
1012
1013    private UserManagerInternal mUserManagerInternal;
1014
1015    private DeviceIdleController.LocalService mDeviceIdleController;
1016
1017    private File mCacheDir;
1018
1019    private ArraySet<String> mPrivappPermissionsViolations;
1020
1021    private Future<?> mPrepareAppDataFuture;
1022
1023    private static class IFVerificationParams {
1024        PackageParser.Package pkg;
1025        boolean replacing;
1026        int userId;
1027        int verifierUid;
1028
1029        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1030                int _userId, int _verifierUid) {
1031            pkg = _pkg;
1032            replacing = _replacing;
1033            userId = _userId;
1034            replacing = _replacing;
1035            verifierUid = _verifierUid;
1036        }
1037    }
1038
1039    private interface IntentFilterVerifier<T extends IntentFilter> {
1040        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1041                                               T filter, String packageName);
1042        void startVerifications(int userId);
1043        void receiveVerificationResponse(int verificationId);
1044    }
1045
1046    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1047        private Context mContext;
1048        private ComponentName mIntentFilterVerifierComponent;
1049        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1050
1051        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1052            mContext = context;
1053            mIntentFilterVerifierComponent = verifierComponent;
1054        }
1055
1056        private String getDefaultScheme() {
1057            return IntentFilter.SCHEME_HTTPS;
1058        }
1059
1060        @Override
1061        public void startVerifications(int userId) {
1062            // Launch verifications requests
1063            int count = mCurrentIntentFilterVerifications.size();
1064            for (int n=0; n<count; n++) {
1065                int verificationId = mCurrentIntentFilterVerifications.get(n);
1066                final IntentFilterVerificationState ivs =
1067                        mIntentFilterVerificationStates.get(verificationId);
1068
1069                String packageName = ivs.getPackageName();
1070
1071                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1072                final int filterCount = filters.size();
1073                ArraySet<String> domainsSet = new ArraySet<>();
1074                for (int m=0; m<filterCount; m++) {
1075                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1076                    domainsSet.addAll(filter.getHostsList());
1077                }
1078                synchronized (mPackages) {
1079                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1080                            packageName, domainsSet) != null) {
1081                        scheduleWriteSettingsLocked();
1082                    }
1083                }
1084                sendVerificationRequest(verificationId, ivs);
1085            }
1086            mCurrentIntentFilterVerifications.clear();
1087        }
1088
1089        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1090            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1091            verificationIntent.putExtra(
1092                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1093                    verificationId);
1094            verificationIntent.putExtra(
1095                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1096                    getDefaultScheme());
1097            verificationIntent.putExtra(
1098                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1099                    ivs.getHostsString());
1100            verificationIntent.putExtra(
1101                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1102                    ivs.getPackageName());
1103            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1104            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1105
1106            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1107            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1108                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1109                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1110
1111            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1112            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1113                    "Sending IntentFilter verification broadcast");
1114        }
1115
1116        public void receiveVerificationResponse(int verificationId) {
1117            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1118
1119            final boolean verified = ivs.isVerified();
1120
1121            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1122            final int count = filters.size();
1123            if (DEBUG_DOMAIN_VERIFICATION) {
1124                Slog.i(TAG, "Received verification response " + verificationId
1125                        + " for " + count + " filters, verified=" + verified);
1126            }
1127            for (int n=0; n<count; n++) {
1128                PackageParser.ActivityIntentInfo filter = filters.get(n);
1129                filter.setVerified(verified);
1130
1131                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1132                        + " verified with result:" + verified + " and hosts:"
1133                        + ivs.getHostsString());
1134            }
1135
1136            mIntentFilterVerificationStates.remove(verificationId);
1137
1138            final String packageName = ivs.getPackageName();
1139            IntentFilterVerificationInfo ivi = null;
1140
1141            synchronized (mPackages) {
1142                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1143            }
1144            if (ivi == null) {
1145                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1146                        + verificationId + " packageName:" + packageName);
1147                return;
1148            }
1149            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1150                    "Updating IntentFilterVerificationInfo for package " + packageName
1151                            +" verificationId:" + verificationId);
1152
1153            synchronized (mPackages) {
1154                if (verified) {
1155                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1156                } else {
1157                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1158                }
1159                scheduleWriteSettingsLocked();
1160
1161                final int userId = ivs.getUserId();
1162                if (userId != UserHandle.USER_ALL) {
1163                    final int userStatus =
1164                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1165
1166                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1167                    boolean needUpdate = false;
1168
1169                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1170                    // already been set by the User thru the Disambiguation dialog
1171                    switch (userStatus) {
1172                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1173                            if (verified) {
1174                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1175                            } else {
1176                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1177                            }
1178                            needUpdate = true;
1179                            break;
1180
1181                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1182                            if (verified) {
1183                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1184                                needUpdate = true;
1185                            }
1186                            break;
1187
1188                        default:
1189                            // Nothing to do
1190                    }
1191
1192                    if (needUpdate) {
1193                        mSettings.updateIntentFilterVerificationStatusLPw(
1194                                packageName, updatedStatus, userId);
1195                        scheduleWritePackageRestrictionsLocked(userId);
1196                    }
1197                }
1198            }
1199        }
1200
1201        @Override
1202        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1203                    ActivityIntentInfo filter, String packageName) {
1204            if (!hasValidDomains(filter)) {
1205                return false;
1206            }
1207            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1208            if (ivs == null) {
1209                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1210                        packageName);
1211            }
1212            if (DEBUG_DOMAIN_VERIFICATION) {
1213                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1214            }
1215            ivs.addFilter(filter);
1216            return true;
1217        }
1218
1219        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1220                int userId, int verificationId, String packageName) {
1221            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1222                    verifierUid, userId, packageName);
1223            ivs.setPendingState();
1224            synchronized (mPackages) {
1225                mIntentFilterVerificationStates.append(verificationId, ivs);
1226                mCurrentIntentFilterVerifications.add(verificationId);
1227            }
1228            return ivs;
1229        }
1230    }
1231
1232    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1233        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1234                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1235                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1236    }
1237
1238    // Set of pending broadcasts for aggregating enable/disable of components.
1239    static class PendingPackageBroadcasts {
1240        // for each user id, a map of <package name -> components within that package>
1241        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1242
1243        public PendingPackageBroadcasts() {
1244            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1245        }
1246
1247        public ArrayList<String> get(int userId, String packageName) {
1248            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1249            return packages.get(packageName);
1250        }
1251
1252        public void put(int userId, String packageName, ArrayList<String> components) {
1253            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1254            packages.put(packageName, components);
1255        }
1256
1257        public void remove(int userId, String packageName) {
1258            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1259            if (packages != null) {
1260                packages.remove(packageName);
1261            }
1262        }
1263
1264        public void remove(int userId) {
1265            mUidMap.remove(userId);
1266        }
1267
1268        public int userIdCount() {
1269            return mUidMap.size();
1270        }
1271
1272        public int userIdAt(int n) {
1273            return mUidMap.keyAt(n);
1274        }
1275
1276        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1277            return mUidMap.get(userId);
1278        }
1279
1280        public int size() {
1281            // total number of pending broadcast entries across all userIds
1282            int num = 0;
1283            for (int i = 0; i< mUidMap.size(); i++) {
1284                num += mUidMap.valueAt(i).size();
1285            }
1286            return num;
1287        }
1288
1289        public void clear() {
1290            mUidMap.clear();
1291        }
1292
1293        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1294            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1295            if (map == null) {
1296                map = new ArrayMap<String, ArrayList<String>>();
1297                mUidMap.put(userId, map);
1298            }
1299            return map;
1300        }
1301    }
1302    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1303
1304    // Service Connection to remote media container service to copy
1305    // package uri's from external media onto secure containers
1306    // or internal storage.
1307    private IMediaContainerService mContainerService = null;
1308
1309    static final int SEND_PENDING_BROADCAST = 1;
1310    static final int MCS_BOUND = 3;
1311    static final int END_COPY = 4;
1312    static final int INIT_COPY = 5;
1313    static final int MCS_UNBIND = 6;
1314    static final int START_CLEANING_PACKAGE = 7;
1315    static final int FIND_INSTALL_LOC = 8;
1316    static final int POST_INSTALL = 9;
1317    static final int MCS_RECONNECT = 10;
1318    static final int MCS_GIVE_UP = 11;
1319    static final int UPDATED_MEDIA_STATUS = 12;
1320    static final int WRITE_SETTINGS = 13;
1321    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1322    static final int PACKAGE_VERIFIED = 15;
1323    static final int CHECK_PENDING_VERIFICATION = 16;
1324    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1325    static final int INTENT_FILTER_VERIFIED = 18;
1326    static final int WRITE_PACKAGE_LIST = 19;
1327    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1328
1329    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1330
1331    // Delay time in millisecs
1332    static final int BROADCAST_DELAY = 10 * 1000;
1333
1334    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1335            2 * 60 * 60 * 1000L; /* two hours */
1336
1337    static UserManagerService sUserManager;
1338
1339    // Stores a list of users whose package restrictions file needs to be updated
1340    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1341
1342    final private DefaultContainerConnection mDefContainerConn =
1343            new DefaultContainerConnection();
1344    class DefaultContainerConnection implements ServiceConnection {
1345        public void onServiceConnected(ComponentName name, IBinder service) {
1346            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1347            final IMediaContainerService imcs = IMediaContainerService.Stub
1348                    .asInterface(Binder.allowBlocking(service));
1349            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1350        }
1351
1352        public void onServiceDisconnected(ComponentName name) {
1353            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1354        }
1355    }
1356
1357    // Recordkeeping of restore-after-install operations that are currently in flight
1358    // between the Package Manager and the Backup Manager
1359    static class PostInstallData {
1360        public InstallArgs args;
1361        public PackageInstalledInfo res;
1362
1363        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1364            args = _a;
1365            res = _r;
1366        }
1367    }
1368
1369    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1370    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1371
1372    // XML tags for backup/restore of various bits of state
1373    private static final String TAG_PREFERRED_BACKUP = "pa";
1374    private static final String TAG_DEFAULT_APPS = "da";
1375    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1376
1377    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1378    private static final String TAG_ALL_GRANTS = "rt-grants";
1379    private static final String TAG_GRANT = "grant";
1380    private static final String ATTR_PACKAGE_NAME = "pkg";
1381
1382    private static final String TAG_PERMISSION = "perm";
1383    private static final String ATTR_PERMISSION_NAME = "name";
1384    private static final String ATTR_IS_GRANTED = "g";
1385    private static final String ATTR_USER_SET = "set";
1386    private static final String ATTR_USER_FIXED = "fixed";
1387    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1388
1389    // System/policy permission grants are not backed up
1390    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1391            FLAG_PERMISSION_POLICY_FIXED
1392            | FLAG_PERMISSION_SYSTEM_FIXED
1393            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1394
1395    // And we back up these user-adjusted states
1396    private static final int USER_RUNTIME_GRANT_MASK =
1397            FLAG_PERMISSION_USER_SET
1398            | FLAG_PERMISSION_USER_FIXED
1399            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1400
1401    final @Nullable String mRequiredVerifierPackage;
1402    final @NonNull String mRequiredInstallerPackage;
1403    final @NonNull String mRequiredUninstallerPackage;
1404    final @Nullable String mSetupWizardPackage;
1405    final @Nullable String mStorageManagerPackage;
1406    final @NonNull String mServicesSystemSharedLibraryPackageName;
1407    final @NonNull String mSharedSystemSharedLibraryPackageName;
1408
1409    final boolean mPermissionReviewRequired;
1410
1411    private final PackageUsage mPackageUsage = new PackageUsage();
1412    private final CompilerStats mCompilerStats = new CompilerStats();
1413
1414    class PackageHandler extends Handler {
1415        private boolean mBound = false;
1416        final ArrayList<HandlerParams> mPendingInstalls =
1417            new ArrayList<HandlerParams>();
1418
1419        private boolean connectToService() {
1420            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1421                    " DefaultContainerService");
1422            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1423            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1424            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1425                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1426                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1427                mBound = true;
1428                return true;
1429            }
1430            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1431            return false;
1432        }
1433
1434        private void disconnectService() {
1435            mContainerService = null;
1436            mBound = false;
1437            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1438            mContext.unbindService(mDefContainerConn);
1439            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1440        }
1441
1442        PackageHandler(Looper looper) {
1443            super(looper);
1444        }
1445
1446        public void handleMessage(Message msg) {
1447            try {
1448                doHandleMessage(msg);
1449            } finally {
1450                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1451            }
1452        }
1453
1454        void doHandleMessage(Message msg) {
1455            switch (msg.what) {
1456                case INIT_COPY: {
1457                    HandlerParams params = (HandlerParams) msg.obj;
1458                    int idx = mPendingInstalls.size();
1459                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1460                    // If a bind was already initiated we dont really
1461                    // need to do anything. The pending install
1462                    // will be processed later on.
1463                    if (!mBound) {
1464                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1465                                System.identityHashCode(mHandler));
1466                        // If this is the only one pending we might
1467                        // have to bind to the service again.
1468                        if (!connectToService()) {
1469                            Slog.e(TAG, "Failed to bind to media container service");
1470                            params.serviceError();
1471                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1472                                    System.identityHashCode(mHandler));
1473                            if (params.traceMethod != null) {
1474                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1475                                        params.traceCookie);
1476                            }
1477                            return;
1478                        } else {
1479                            // Once we bind to the service, the first
1480                            // pending request will be processed.
1481                            mPendingInstalls.add(idx, params);
1482                        }
1483                    } else {
1484                        mPendingInstalls.add(idx, params);
1485                        // Already bound to the service. Just make
1486                        // sure we trigger off processing the first request.
1487                        if (idx == 0) {
1488                            mHandler.sendEmptyMessage(MCS_BOUND);
1489                        }
1490                    }
1491                    break;
1492                }
1493                case MCS_BOUND: {
1494                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1495                    if (msg.obj != null) {
1496                        mContainerService = (IMediaContainerService) msg.obj;
1497                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1498                                System.identityHashCode(mHandler));
1499                    }
1500                    if (mContainerService == null) {
1501                        if (!mBound) {
1502                            // Something seriously wrong since we are not bound and we are not
1503                            // waiting for connection. Bail out.
1504                            Slog.e(TAG, "Cannot bind to media container service");
1505                            for (HandlerParams params : mPendingInstalls) {
1506                                // Indicate service bind error
1507                                params.serviceError();
1508                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1509                                        System.identityHashCode(params));
1510                                if (params.traceMethod != null) {
1511                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1512                                            params.traceMethod, params.traceCookie);
1513                                }
1514                                return;
1515                            }
1516                            mPendingInstalls.clear();
1517                        } else {
1518                            Slog.w(TAG, "Waiting to connect to media container service");
1519                        }
1520                    } else if (mPendingInstalls.size() > 0) {
1521                        HandlerParams params = mPendingInstalls.get(0);
1522                        if (params != null) {
1523                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1524                                    System.identityHashCode(params));
1525                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1526                            if (params.startCopy()) {
1527                                // We are done...  look for more work or to
1528                                // go idle.
1529                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1530                                        "Checking for more work or unbind...");
1531                                // Delete pending install
1532                                if (mPendingInstalls.size() > 0) {
1533                                    mPendingInstalls.remove(0);
1534                                }
1535                                if (mPendingInstalls.size() == 0) {
1536                                    if (mBound) {
1537                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1538                                                "Posting delayed MCS_UNBIND");
1539                                        removeMessages(MCS_UNBIND);
1540                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1541                                        // Unbind after a little delay, to avoid
1542                                        // continual thrashing.
1543                                        sendMessageDelayed(ubmsg, 10000);
1544                                    }
1545                                } else {
1546                                    // There are more pending requests in queue.
1547                                    // Just post MCS_BOUND message to trigger processing
1548                                    // of next pending install.
1549                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1550                                            "Posting MCS_BOUND for next work");
1551                                    mHandler.sendEmptyMessage(MCS_BOUND);
1552                                }
1553                            }
1554                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1555                        }
1556                    } else {
1557                        // Should never happen ideally.
1558                        Slog.w(TAG, "Empty queue");
1559                    }
1560                    break;
1561                }
1562                case MCS_RECONNECT: {
1563                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1564                    if (mPendingInstalls.size() > 0) {
1565                        if (mBound) {
1566                            disconnectService();
1567                        }
1568                        if (!connectToService()) {
1569                            Slog.e(TAG, "Failed to bind to media container service");
1570                            for (HandlerParams params : mPendingInstalls) {
1571                                // Indicate service bind error
1572                                params.serviceError();
1573                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1574                                        System.identityHashCode(params));
1575                            }
1576                            mPendingInstalls.clear();
1577                        }
1578                    }
1579                    break;
1580                }
1581                case MCS_UNBIND: {
1582                    // If there is no actual work left, then time to unbind.
1583                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1584
1585                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1586                        if (mBound) {
1587                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1588
1589                            disconnectService();
1590                        }
1591                    } else if (mPendingInstalls.size() > 0) {
1592                        // There are more pending requests in queue.
1593                        // Just post MCS_BOUND message to trigger processing
1594                        // of next pending install.
1595                        mHandler.sendEmptyMessage(MCS_BOUND);
1596                    }
1597
1598                    break;
1599                }
1600                case MCS_GIVE_UP: {
1601                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1602                    HandlerParams params = mPendingInstalls.remove(0);
1603                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1604                            System.identityHashCode(params));
1605                    break;
1606                }
1607                case SEND_PENDING_BROADCAST: {
1608                    String packages[];
1609                    ArrayList<String> components[];
1610                    int size = 0;
1611                    int uids[];
1612                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1613                    synchronized (mPackages) {
1614                        if (mPendingBroadcasts == null) {
1615                            return;
1616                        }
1617                        size = mPendingBroadcasts.size();
1618                        if (size <= 0) {
1619                            // Nothing to be done. Just return
1620                            return;
1621                        }
1622                        packages = new String[size];
1623                        components = new ArrayList[size];
1624                        uids = new int[size];
1625                        int i = 0;  // filling out the above arrays
1626
1627                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1628                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1629                            Iterator<Map.Entry<String, ArrayList<String>>> it
1630                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1631                                            .entrySet().iterator();
1632                            while (it.hasNext() && i < size) {
1633                                Map.Entry<String, ArrayList<String>> ent = it.next();
1634                                packages[i] = ent.getKey();
1635                                components[i] = ent.getValue();
1636                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1637                                uids[i] = (ps != null)
1638                                        ? UserHandle.getUid(packageUserId, ps.appId)
1639                                        : -1;
1640                                i++;
1641                            }
1642                        }
1643                        size = i;
1644                        mPendingBroadcasts.clear();
1645                    }
1646                    // Send broadcasts
1647                    for (int i = 0; i < size; i++) {
1648                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1649                    }
1650                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1651                    break;
1652                }
1653                case START_CLEANING_PACKAGE: {
1654                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1655                    final String packageName = (String)msg.obj;
1656                    final int userId = msg.arg1;
1657                    final boolean andCode = msg.arg2 != 0;
1658                    synchronized (mPackages) {
1659                        if (userId == UserHandle.USER_ALL) {
1660                            int[] users = sUserManager.getUserIds();
1661                            for (int user : users) {
1662                                mSettings.addPackageToCleanLPw(
1663                                        new PackageCleanItem(user, packageName, andCode));
1664                            }
1665                        } else {
1666                            mSettings.addPackageToCleanLPw(
1667                                    new PackageCleanItem(userId, packageName, andCode));
1668                        }
1669                    }
1670                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1671                    startCleaningPackages();
1672                } break;
1673                case POST_INSTALL: {
1674                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1675
1676                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1677                    final boolean didRestore = (msg.arg2 != 0);
1678                    mRunningInstalls.delete(msg.arg1);
1679
1680                    if (data != null) {
1681                        InstallArgs args = data.args;
1682                        PackageInstalledInfo parentRes = data.res;
1683
1684                        final boolean grantPermissions = (args.installFlags
1685                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1686                        final boolean killApp = (args.installFlags
1687                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1688                        final boolean virtualPreload = ((args.installFlags
1689                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1690                        final String[] grantedPermissions = args.installGrantPermissions;
1691
1692                        // Handle the parent package
1693                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1694                                virtualPreload, grantedPermissions, didRestore,
1695                                args.installerPackageName, args.observer);
1696
1697                        // Handle the child packages
1698                        final int childCount = (parentRes.addedChildPackages != null)
1699                                ? parentRes.addedChildPackages.size() : 0;
1700                        for (int i = 0; i < childCount; i++) {
1701                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1702                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1703                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1704                                    args.installerPackageName, args.observer);
1705                        }
1706
1707                        // Log tracing if needed
1708                        if (args.traceMethod != null) {
1709                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1710                                    args.traceCookie);
1711                        }
1712                    } else {
1713                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1714                    }
1715
1716                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1717                } break;
1718                case UPDATED_MEDIA_STATUS: {
1719                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1720                    boolean reportStatus = msg.arg1 == 1;
1721                    boolean doGc = msg.arg2 == 1;
1722                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1723                    if (doGc) {
1724                        // Force a gc to clear up stale containers.
1725                        Runtime.getRuntime().gc();
1726                    }
1727                    if (msg.obj != null) {
1728                        @SuppressWarnings("unchecked")
1729                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1730                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1731                        // Unload containers
1732                        unloadAllContainers(args);
1733                    }
1734                    if (reportStatus) {
1735                        try {
1736                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1737                                    "Invoking StorageManagerService call back");
1738                            PackageHelper.getStorageManager().finishMediaUpdate();
1739                        } catch (RemoteException e) {
1740                            Log.e(TAG, "StorageManagerService not running?");
1741                        }
1742                    }
1743                } break;
1744                case WRITE_SETTINGS: {
1745                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1746                    synchronized (mPackages) {
1747                        removeMessages(WRITE_SETTINGS);
1748                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1749                        mSettings.writeLPr();
1750                        mDirtyUsers.clear();
1751                    }
1752                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1753                } break;
1754                case WRITE_PACKAGE_RESTRICTIONS: {
1755                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1756                    synchronized (mPackages) {
1757                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1758                        for (int userId : mDirtyUsers) {
1759                            mSettings.writePackageRestrictionsLPr(userId);
1760                        }
1761                        mDirtyUsers.clear();
1762                    }
1763                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1764                } break;
1765                case WRITE_PACKAGE_LIST: {
1766                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1767                    synchronized (mPackages) {
1768                        removeMessages(WRITE_PACKAGE_LIST);
1769                        mSettings.writePackageListLPr(msg.arg1);
1770                    }
1771                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1772                } break;
1773                case CHECK_PENDING_VERIFICATION: {
1774                    final int verificationId = msg.arg1;
1775                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1776
1777                    if ((state != null) && !state.timeoutExtended()) {
1778                        final InstallArgs args = state.getInstallArgs();
1779                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1780
1781                        Slog.i(TAG, "Verification timed out for " + originUri);
1782                        mPendingVerification.remove(verificationId);
1783
1784                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1785
1786                        final UserHandle user = args.getUser();
1787                        if (getDefaultVerificationResponse(user)
1788                                == PackageManager.VERIFICATION_ALLOW) {
1789                            Slog.i(TAG, "Continuing with installation of " + originUri);
1790                            state.setVerifierResponse(Binder.getCallingUid(),
1791                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1792                            broadcastPackageVerified(verificationId, originUri,
1793                                    PackageManager.VERIFICATION_ALLOW, user);
1794                            try {
1795                                ret = args.copyApk(mContainerService, true);
1796                            } catch (RemoteException e) {
1797                                Slog.e(TAG, "Could not contact the ContainerService");
1798                            }
1799                        } else {
1800                            broadcastPackageVerified(verificationId, originUri,
1801                                    PackageManager.VERIFICATION_REJECT, user);
1802                        }
1803
1804                        Trace.asyncTraceEnd(
1805                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1806
1807                        processPendingInstall(args, ret);
1808                        mHandler.sendEmptyMessage(MCS_UNBIND);
1809                    }
1810                    break;
1811                }
1812                case PACKAGE_VERIFIED: {
1813                    final int verificationId = msg.arg1;
1814
1815                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1816                    if (state == null) {
1817                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1818                        break;
1819                    }
1820
1821                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1822
1823                    state.setVerifierResponse(response.callerUid, response.code);
1824
1825                    if (state.isVerificationComplete()) {
1826                        mPendingVerification.remove(verificationId);
1827
1828                        final InstallArgs args = state.getInstallArgs();
1829                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1830
1831                        int ret;
1832                        if (state.isInstallAllowed()) {
1833                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1834                            broadcastPackageVerified(verificationId, originUri,
1835                                    response.code, state.getInstallArgs().getUser());
1836                            try {
1837                                ret = args.copyApk(mContainerService, true);
1838                            } catch (RemoteException e) {
1839                                Slog.e(TAG, "Could not contact the ContainerService");
1840                            }
1841                        } else {
1842                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1843                        }
1844
1845                        Trace.asyncTraceEnd(
1846                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1847
1848                        processPendingInstall(args, ret);
1849                        mHandler.sendEmptyMessage(MCS_UNBIND);
1850                    }
1851
1852                    break;
1853                }
1854                case START_INTENT_FILTER_VERIFICATIONS: {
1855                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1856                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1857                            params.replacing, params.pkg);
1858                    break;
1859                }
1860                case INTENT_FILTER_VERIFIED: {
1861                    final int verificationId = msg.arg1;
1862
1863                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1864                            verificationId);
1865                    if (state == null) {
1866                        Slog.w(TAG, "Invalid IntentFilter verification token "
1867                                + verificationId + " received");
1868                        break;
1869                    }
1870
1871                    final int userId = state.getUserId();
1872
1873                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1874                            "Processing IntentFilter verification with token:"
1875                            + verificationId + " and userId:" + userId);
1876
1877                    final IntentFilterVerificationResponse response =
1878                            (IntentFilterVerificationResponse) msg.obj;
1879
1880                    state.setVerifierResponse(response.callerUid, response.code);
1881
1882                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1883                            "IntentFilter verification with token:" + verificationId
1884                            + " and userId:" + userId
1885                            + " is settings verifier response with response code:"
1886                            + response.code);
1887
1888                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1889                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1890                                + response.getFailedDomainsString());
1891                    }
1892
1893                    if (state.isVerificationComplete()) {
1894                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1895                    } else {
1896                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1897                                "IntentFilter verification with token:" + verificationId
1898                                + " was not said to be complete");
1899                    }
1900
1901                    break;
1902                }
1903                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1904                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1905                            mInstantAppResolverConnection,
1906                            (InstantAppRequest) msg.obj,
1907                            mInstantAppInstallerActivity,
1908                            mHandler);
1909                }
1910            }
1911        }
1912    }
1913
1914    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1915            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1916            boolean launchedForRestore, String installerPackage,
1917            IPackageInstallObserver2 installObserver) {
1918        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1919            // Send the removed broadcasts
1920            if (res.removedInfo != null) {
1921                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1922            }
1923
1924            // Now that we successfully installed the package, grant runtime
1925            // permissions if requested before broadcasting the install. Also
1926            // for legacy apps in permission review mode we clear the permission
1927            // review flag which is used to emulate runtime permissions for
1928            // legacy apps.
1929            if (grantPermissions) {
1930                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1931            }
1932
1933            final boolean update = res.removedInfo != null
1934                    && res.removedInfo.removedPackage != null;
1935            final String installerPackageName =
1936                    res.installerPackageName != null
1937                            ? res.installerPackageName
1938                            : res.removedInfo != null
1939                                    ? res.removedInfo.installerPackageName
1940                                    : null;
1941
1942            // If this is the first time we have child packages for a disabled privileged
1943            // app that had no children, we grant requested runtime permissions to the new
1944            // children if the parent on the system image had them already granted.
1945            if (res.pkg.parentPackage != null) {
1946                synchronized (mPackages) {
1947                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1948                }
1949            }
1950
1951            synchronized (mPackages) {
1952                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1953            }
1954
1955            final String packageName = res.pkg.applicationInfo.packageName;
1956
1957            // Determine the set of users who are adding this package for
1958            // the first time vs. those who are seeing an update.
1959            int[] firstUsers = EMPTY_INT_ARRAY;
1960            int[] updateUsers = EMPTY_INT_ARRAY;
1961            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1962            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1963            for (int newUser : res.newUsers) {
1964                if (ps.getInstantApp(newUser)) {
1965                    continue;
1966                }
1967                if (allNewUsers) {
1968                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1969                    continue;
1970                }
1971                boolean isNew = true;
1972                for (int origUser : res.origUsers) {
1973                    if (origUser == newUser) {
1974                        isNew = false;
1975                        break;
1976                    }
1977                }
1978                if (isNew) {
1979                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1980                } else {
1981                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1982                }
1983            }
1984
1985            // Send installed broadcasts if the package is not a static shared lib.
1986            if (res.pkg.staticSharedLibName == null) {
1987                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1988
1989                // Send added for users that see the package for the first time
1990                // sendPackageAddedForNewUsers also deals with system apps
1991                int appId = UserHandle.getAppId(res.uid);
1992                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1993                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1994                        virtualPreload /*startReceiver*/, appId, firstUsers);
1995
1996                // Send added for users that don't see the package for the first time
1997                Bundle extras = new Bundle(1);
1998                extras.putInt(Intent.EXTRA_UID, res.uid);
1999                if (update) {
2000                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2001                }
2002                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2003                        extras, 0 /*flags*/,
2004                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
2005                if (installerPackageName != null) {
2006                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2007                            extras, 0 /*flags*/,
2008                            installerPackageName, null /*finishedReceiver*/, updateUsers);
2009                }
2010
2011                // Send replaced for users that don't see the package for the first time
2012                if (update) {
2013                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2014                            packageName, extras, 0 /*flags*/,
2015                            null /*targetPackage*/, null /*finishedReceiver*/,
2016                            updateUsers);
2017                    if (installerPackageName != null) {
2018                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2019                                extras, 0 /*flags*/,
2020                                installerPackageName, null /*finishedReceiver*/, updateUsers);
2021                    }
2022                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2023                            null /*package*/, null /*extras*/, 0 /*flags*/,
2024                            packageName /*targetPackage*/,
2025                            null /*finishedReceiver*/, updateUsers);
2026                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2027                    // First-install and we did a restore, so we're responsible for the
2028                    // first-launch broadcast.
2029                    if (DEBUG_BACKUP) {
2030                        Slog.i(TAG, "Post-restore of " + packageName
2031                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2032                    }
2033                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2034                }
2035
2036                // Send broadcast package appeared if forward locked/external for all users
2037                // treat asec-hosted packages like removable media on upgrade
2038                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2039                    if (DEBUG_INSTALL) {
2040                        Slog.i(TAG, "upgrading pkg " + res.pkg
2041                                + " is ASEC-hosted -> AVAILABLE");
2042                    }
2043                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2044                    ArrayList<String> pkgList = new ArrayList<>(1);
2045                    pkgList.add(packageName);
2046                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2047                }
2048            }
2049
2050            // Work that needs to happen on first install within each user
2051            if (firstUsers != null && firstUsers.length > 0) {
2052                synchronized (mPackages) {
2053                    for (int userId : firstUsers) {
2054                        // If this app is a browser and it's newly-installed for some
2055                        // users, clear any default-browser state in those users. The
2056                        // app's nature doesn't depend on the user, so we can just check
2057                        // its browser nature in any user and generalize.
2058                        if (packageIsBrowser(packageName, userId)) {
2059                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2060                        }
2061
2062                        // We may also need to apply pending (restored) runtime
2063                        // permission grants within these users.
2064                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2065                    }
2066                }
2067            }
2068
2069            // Log current value of "unknown sources" setting
2070            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2071                    getUnknownSourcesSettings());
2072
2073            // Remove the replaced package's older resources safely now
2074            // We delete after a gc for applications  on sdcard.
2075            if (res.removedInfo != null && res.removedInfo.args != null) {
2076                Runtime.getRuntime().gc();
2077                synchronized (mInstallLock) {
2078                    res.removedInfo.args.doPostDeleteLI(true);
2079                }
2080            } else {
2081                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2082                // and not block here.
2083                VMRuntime.getRuntime().requestConcurrentGC();
2084            }
2085
2086            // Notify DexManager that the package was installed for new users.
2087            // The updated users should already be indexed and the package code paths
2088            // should not change.
2089            // Don't notify the manager for ephemeral apps as they are not expected to
2090            // survive long enough to benefit of background optimizations.
2091            for (int userId : firstUsers) {
2092                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2093                // There's a race currently where some install events may interleave with an uninstall.
2094                // This can lead to package info being null (b/36642664).
2095                if (info != null) {
2096                    mDexManager.notifyPackageInstalled(info, userId);
2097                }
2098            }
2099        }
2100
2101        // If someone is watching installs - notify them
2102        if (installObserver != null) {
2103            try {
2104                Bundle extras = extrasForInstallResult(res);
2105                installObserver.onPackageInstalled(res.name, res.returnCode,
2106                        res.returnMsg, extras);
2107            } catch (RemoteException e) {
2108                Slog.i(TAG, "Observer no longer exists.");
2109            }
2110        }
2111    }
2112
2113    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2114            PackageParser.Package pkg) {
2115        if (pkg.parentPackage == null) {
2116            return;
2117        }
2118        if (pkg.requestedPermissions == null) {
2119            return;
2120        }
2121        final PackageSetting disabledSysParentPs = mSettings
2122                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2123        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2124                || !disabledSysParentPs.isPrivileged()
2125                || (disabledSysParentPs.childPackageNames != null
2126                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2127            return;
2128        }
2129        final int[] allUserIds = sUserManager.getUserIds();
2130        final int permCount = pkg.requestedPermissions.size();
2131        for (int i = 0; i < permCount; i++) {
2132            String permission = pkg.requestedPermissions.get(i);
2133            BasePermission bp = mSettings.mPermissions.get(permission);
2134            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2135                continue;
2136            }
2137            for (int userId : allUserIds) {
2138                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2139                        permission, userId)) {
2140                    grantRuntimePermission(pkg.packageName, permission, userId);
2141                }
2142            }
2143        }
2144    }
2145
2146    private StorageEventListener mStorageListener = new StorageEventListener() {
2147        @Override
2148        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2149            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2150                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2151                    final String volumeUuid = vol.getFsUuid();
2152
2153                    // Clean up any users or apps that were removed or recreated
2154                    // while this volume was missing
2155                    sUserManager.reconcileUsers(volumeUuid);
2156                    reconcileApps(volumeUuid);
2157
2158                    // Clean up any install sessions that expired or were
2159                    // cancelled while this volume was missing
2160                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2161
2162                    loadPrivatePackages(vol);
2163
2164                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2165                    unloadPrivatePackages(vol);
2166                }
2167            }
2168
2169            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2170                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2171                    updateExternalMediaStatus(true, false);
2172                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2173                    updateExternalMediaStatus(false, false);
2174                }
2175            }
2176        }
2177
2178        @Override
2179        public void onVolumeForgotten(String fsUuid) {
2180            if (TextUtils.isEmpty(fsUuid)) {
2181                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2182                return;
2183            }
2184
2185            // Remove any apps installed on the forgotten volume
2186            synchronized (mPackages) {
2187                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2188                for (PackageSetting ps : packages) {
2189                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2190                    deletePackageVersioned(new VersionedPackage(ps.name,
2191                            PackageManager.VERSION_CODE_HIGHEST),
2192                            new LegacyPackageDeleteObserver(null).getBinder(),
2193                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2194                    // Try very hard to release any references to this package
2195                    // so we don't risk the system server being killed due to
2196                    // open FDs
2197                    AttributeCache.instance().removePackage(ps.name);
2198                }
2199
2200                mSettings.onVolumeForgotten(fsUuid);
2201                mSettings.writeLPr();
2202            }
2203        }
2204    };
2205
2206    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2207            String[] grantedPermissions) {
2208        for (int userId : userIds) {
2209            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2210        }
2211    }
2212
2213    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2214            String[] grantedPermissions) {
2215        PackageSetting ps = (PackageSetting) pkg.mExtras;
2216        if (ps == null) {
2217            return;
2218        }
2219
2220        PermissionsState permissionsState = ps.getPermissionsState();
2221
2222        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2223                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2224
2225        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2226                >= Build.VERSION_CODES.M;
2227
2228        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2229
2230        for (String permission : pkg.requestedPermissions) {
2231            final BasePermission bp;
2232            synchronized (mPackages) {
2233                bp = mSettings.mPermissions.get(permission);
2234            }
2235            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2236                    && (!instantApp || bp.isInstant())
2237                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2238                    && (grantedPermissions == null
2239                           || ArrayUtils.contains(grantedPermissions, permission))) {
2240                final int flags = permissionsState.getPermissionFlags(permission, userId);
2241                if (supportsRuntimePermissions) {
2242                    // Installer cannot change immutable permissions.
2243                    if ((flags & immutableFlags) == 0) {
2244                        grantRuntimePermission(pkg.packageName, permission, userId);
2245                    }
2246                } else if (mPermissionReviewRequired) {
2247                    // In permission review mode we clear the review flag when we
2248                    // are asked to install the app with all permissions granted.
2249                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2250                        updatePermissionFlags(permission, pkg.packageName,
2251                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2252                    }
2253                }
2254            }
2255        }
2256    }
2257
2258    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2259        Bundle extras = null;
2260        switch (res.returnCode) {
2261            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2262                extras = new Bundle();
2263                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2264                        res.origPermission);
2265                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2266                        res.origPackage);
2267                break;
2268            }
2269            case PackageManager.INSTALL_SUCCEEDED: {
2270                extras = new Bundle();
2271                extras.putBoolean(Intent.EXTRA_REPLACING,
2272                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2273                break;
2274            }
2275        }
2276        return extras;
2277    }
2278
2279    void scheduleWriteSettingsLocked() {
2280        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2281            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2282        }
2283    }
2284
2285    void scheduleWritePackageListLocked(int userId) {
2286        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2287            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2288            msg.arg1 = userId;
2289            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2290        }
2291    }
2292
2293    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2294        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2295        scheduleWritePackageRestrictionsLocked(userId);
2296    }
2297
2298    void scheduleWritePackageRestrictionsLocked(int userId) {
2299        final int[] userIds = (userId == UserHandle.USER_ALL)
2300                ? sUserManager.getUserIds() : new int[]{userId};
2301        for (int nextUserId : userIds) {
2302            if (!sUserManager.exists(nextUserId)) return;
2303            mDirtyUsers.add(nextUserId);
2304            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2305                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2306            }
2307        }
2308    }
2309
2310    public static PackageManagerService main(Context context, Installer installer,
2311            boolean factoryTest, boolean onlyCore) {
2312        // Self-check for initial settings.
2313        PackageManagerServiceCompilerMapping.checkProperties();
2314
2315        PackageManagerService m = new PackageManagerService(context, installer,
2316                factoryTest, onlyCore);
2317        m.enableSystemUserPackages();
2318        ServiceManager.addService("package", m);
2319        final PackageManagerNative pmn = m.new PackageManagerNative();
2320        ServiceManager.addService("package_native", pmn);
2321        return m;
2322    }
2323
2324    private void enableSystemUserPackages() {
2325        if (!UserManager.isSplitSystemUser()) {
2326            return;
2327        }
2328        // For system user, enable apps based on the following conditions:
2329        // - app is whitelisted or belong to one of these groups:
2330        //   -- system app which has no launcher icons
2331        //   -- system app which has INTERACT_ACROSS_USERS permission
2332        //   -- system IME app
2333        // - app is not in the blacklist
2334        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2335        Set<String> enableApps = new ArraySet<>();
2336        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2337                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2338                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2339        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2340        enableApps.addAll(wlApps);
2341        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2342                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2343        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2344        enableApps.removeAll(blApps);
2345        Log.i(TAG, "Applications installed for system user: " + enableApps);
2346        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2347                UserHandle.SYSTEM);
2348        final int allAppsSize = allAps.size();
2349        synchronized (mPackages) {
2350            for (int i = 0; i < allAppsSize; i++) {
2351                String pName = allAps.get(i);
2352                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2353                // Should not happen, but we shouldn't be failing if it does
2354                if (pkgSetting == null) {
2355                    continue;
2356                }
2357                boolean install = enableApps.contains(pName);
2358                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2359                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2360                            + " for system user");
2361                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2362                }
2363            }
2364            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2365        }
2366    }
2367
2368    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2369        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2370                Context.DISPLAY_SERVICE);
2371        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2372    }
2373
2374    /**
2375     * Requests that files preopted on a secondary system partition be copied to the data partition
2376     * if possible.  Note that the actual copying of the files is accomplished by init for security
2377     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2378     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2379     */
2380    private static void requestCopyPreoptedFiles() {
2381        final int WAIT_TIME_MS = 100;
2382        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2383        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2384            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2385            // We will wait for up to 100 seconds.
2386            final long timeStart = SystemClock.uptimeMillis();
2387            final long timeEnd = timeStart + 100 * 1000;
2388            long timeNow = timeStart;
2389            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2390                try {
2391                    Thread.sleep(WAIT_TIME_MS);
2392                } catch (InterruptedException e) {
2393                    // Do nothing
2394                }
2395                timeNow = SystemClock.uptimeMillis();
2396                if (timeNow > timeEnd) {
2397                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2398                    Slog.wtf(TAG, "cppreopt did not finish!");
2399                    break;
2400                }
2401            }
2402
2403            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2404        }
2405    }
2406
2407    public PackageManagerService(Context context, Installer installer,
2408            boolean factoryTest, boolean onlyCore) {
2409        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2410        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2411        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2412                SystemClock.uptimeMillis());
2413
2414        if (mSdkVersion <= 0) {
2415            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2416        }
2417
2418        mContext = context;
2419
2420        mPermissionReviewRequired = context.getResources().getBoolean(
2421                R.bool.config_permissionReviewRequired);
2422
2423        mFactoryTest = factoryTest;
2424        mOnlyCore = onlyCore;
2425        mMetrics = new DisplayMetrics();
2426        mSettings = new Settings(mPackages);
2427        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2428                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2429        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2430                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2431        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2432                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2433        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2434                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2435        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2436                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2437        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2438                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2439
2440        String separateProcesses = SystemProperties.get("debug.separate_processes");
2441        if (separateProcesses != null && separateProcesses.length() > 0) {
2442            if ("*".equals(separateProcesses)) {
2443                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2444                mSeparateProcesses = null;
2445                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2446            } else {
2447                mDefParseFlags = 0;
2448                mSeparateProcesses = separateProcesses.split(",");
2449                Slog.w(TAG, "Running with debug.separate_processes: "
2450                        + separateProcesses);
2451            }
2452        } else {
2453            mDefParseFlags = 0;
2454            mSeparateProcesses = null;
2455        }
2456
2457        mInstaller = installer;
2458        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2459                "*dexopt*");
2460        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2461        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2462
2463        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2464                FgThread.get().getLooper());
2465
2466        getDefaultDisplayMetrics(context, mMetrics);
2467
2468        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2469        SystemConfig systemConfig = SystemConfig.getInstance();
2470        mGlobalGids = systemConfig.getGlobalGids();
2471        mSystemPermissions = systemConfig.getSystemPermissions();
2472        mAvailableFeatures = systemConfig.getAvailableFeatures();
2473        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2474
2475        mProtectedPackages = new ProtectedPackages(mContext);
2476
2477        synchronized (mInstallLock) {
2478        // writer
2479        synchronized (mPackages) {
2480            mHandlerThread = new ServiceThread(TAG,
2481                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2482            mHandlerThread.start();
2483            mHandler = new PackageHandler(mHandlerThread.getLooper());
2484            mProcessLoggingHandler = new ProcessLoggingHandler();
2485            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2486
2487            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2488            mInstantAppRegistry = new InstantAppRegistry(this);
2489
2490            File dataDir = Environment.getDataDirectory();
2491            mAppInstallDir = new File(dataDir, "app");
2492            mAppLib32InstallDir = new File(dataDir, "app-lib");
2493            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2494            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2495            sUserManager = new UserManagerService(context, this,
2496                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2497
2498            // Propagate permission configuration in to package manager.
2499            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2500                    = systemConfig.getPermissions();
2501            for (int i=0; i<permConfig.size(); i++) {
2502                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2503                BasePermission bp = mSettings.mPermissions.get(perm.name);
2504                if (bp == null) {
2505                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2506                    mSettings.mPermissions.put(perm.name, bp);
2507                }
2508                if (perm.gids != null) {
2509                    bp.setGids(perm.gids, perm.perUser);
2510                }
2511            }
2512
2513            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2514            final int builtInLibCount = libConfig.size();
2515            for (int i = 0; i < builtInLibCount; i++) {
2516                String name = libConfig.keyAt(i);
2517                String path = libConfig.valueAt(i);
2518                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2519                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2520            }
2521
2522            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2523
2524            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2525            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2526            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2527
2528            // Clean up orphaned packages for which the code path doesn't exist
2529            // and they are an update to a system app - caused by bug/32321269
2530            final int packageSettingCount = mSettings.mPackages.size();
2531            for (int i = packageSettingCount - 1; i >= 0; i--) {
2532                PackageSetting ps = mSettings.mPackages.valueAt(i);
2533                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2534                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2535                    mSettings.mPackages.removeAt(i);
2536                    mSettings.enableSystemPackageLPw(ps.name);
2537                }
2538            }
2539
2540            if (mFirstBoot) {
2541                requestCopyPreoptedFiles();
2542            }
2543
2544            String customResolverActivity = Resources.getSystem().getString(
2545                    R.string.config_customResolverActivity);
2546            if (TextUtils.isEmpty(customResolverActivity)) {
2547                customResolverActivity = null;
2548            } else {
2549                mCustomResolverComponentName = ComponentName.unflattenFromString(
2550                        customResolverActivity);
2551            }
2552
2553            long startTime = SystemClock.uptimeMillis();
2554
2555            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2556                    startTime);
2557
2558            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2559            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2560
2561            if (bootClassPath == null) {
2562                Slog.w(TAG, "No BOOTCLASSPATH found!");
2563            }
2564
2565            if (systemServerClassPath == null) {
2566                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2567            }
2568
2569            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2570
2571            final VersionInfo ver = mSettings.getInternalVersion();
2572            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2573            if (mIsUpgrade) {
2574                logCriticalInfo(Log.INFO,
2575                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2576            }
2577
2578            // when upgrading from pre-M, promote system app permissions from install to runtime
2579            mPromoteSystemApps =
2580                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2581
2582            // When upgrading from pre-N, we need to handle package extraction like first boot,
2583            // as there is no profiling data available.
2584            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2585
2586            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2587
2588            // save off the names of pre-existing system packages prior to scanning; we don't
2589            // want to automatically grant runtime permissions for new system apps
2590            if (mPromoteSystemApps) {
2591                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2592                while (pkgSettingIter.hasNext()) {
2593                    PackageSetting ps = pkgSettingIter.next();
2594                    if (isSystemApp(ps)) {
2595                        mExistingSystemPackages.add(ps.name);
2596                    }
2597                }
2598            }
2599
2600            mCacheDir = preparePackageParserCache(mIsUpgrade);
2601
2602            // Set flag to monitor and not change apk file paths when
2603            // scanning install directories.
2604            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2605
2606            if (mIsUpgrade || mFirstBoot) {
2607                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2608            }
2609
2610            // Collect vendor overlay packages. (Do this before scanning any apps.)
2611            // For security and version matching reason, only consider
2612            // overlay packages if they reside in the right directory.
2613            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2614                    | PackageParser.PARSE_IS_SYSTEM
2615                    | PackageParser.PARSE_IS_SYSTEM_DIR
2616                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2617
2618            mParallelPackageParserCallback.findStaticOverlayPackages();
2619
2620            // Find base frameworks (resource packages without code).
2621            scanDirTracedLI(frameworkDir, mDefParseFlags
2622                    | PackageParser.PARSE_IS_SYSTEM
2623                    | PackageParser.PARSE_IS_SYSTEM_DIR
2624                    | PackageParser.PARSE_IS_PRIVILEGED,
2625                    scanFlags | SCAN_NO_DEX, 0);
2626
2627            // Collected privileged system packages.
2628            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2629            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2630                    | PackageParser.PARSE_IS_SYSTEM
2631                    | PackageParser.PARSE_IS_SYSTEM_DIR
2632                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2633
2634            // Collect ordinary system packages.
2635            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2636            scanDirTracedLI(systemAppDir, mDefParseFlags
2637                    | PackageParser.PARSE_IS_SYSTEM
2638                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2639
2640            // Collect all vendor packages.
2641            File vendorAppDir = new File("/vendor/app");
2642            try {
2643                vendorAppDir = vendorAppDir.getCanonicalFile();
2644            } catch (IOException e) {
2645                // failed to look up canonical path, continue with original one
2646            }
2647            scanDirTracedLI(vendorAppDir, mDefParseFlags
2648                    | PackageParser.PARSE_IS_SYSTEM
2649                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2650
2651            // Collect all OEM packages.
2652            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2653            scanDirTracedLI(oemAppDir, mDefParseFlags
2654                    | PackageParser.PARSE_IS_SYSTEM
2655                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2656
2657            // Prune any system packages that no longer exist.
2658            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2659            // Stub packages must either be replaced with full versions in the /data
2660            // partition or be disabled.
2661            final List<String> stubSystemApps = new ArrayList<>();
2662            if (!mOnlyCore) {
2663                // do this first before mucking with mPackages for the "expecting better" case
2664                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2665                while (pkgIterator.hasNext()) {
2666                    final PackageParser.Package pkg = pkgIterator.next();
2667                    if (pkg.isStub) {
2668                        stubSystemApps.add(pkg.packageName);
2669                    }
2670                }
2671
2672                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2673                while (psit.hasNext()) {
2674                    PackageSetting ps = psit.next();
2675
2676                    /*
2677                     * If this is not a system app, it can't be a
2678                     * disable system app.
2679                     */
2680                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2681                        continue;
2682                    }
2683
2684                    /*
2685                     * If the package is scanned, it's not erased.
2686                     */
2687                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2688                    if (scannedPkg != null) {
2689                        /*
2690                         * If the system app is both scanned and in the
2691                         * disabled packages list, then it must have been
2692                         * added via OTA. Remove it from the currently
2693                         * scanned package so the previously user-installed
2694                         * application can be scanned.
2695                         */
2696                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2697                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2698                                    + ps.name + "; removing system app.  Last known codePath="
2699                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2700                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2701                                    + scannedPkg.mVersionCode);
2702                            removePackageLI(scannedPkg, true);
2703                            mExpectingBetter.put(ps.name, ps.codePath);
2704                        }
2705
2706                        continue;
2707                    }
2708
2709                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2710                        psit.remove();
2711                        logCriticalInfo(Log.WARN, "System package " + ps.name
2712                                + " no longer exists; it's data will be wiped");
2713                        // Actual deletion of code and data will be handled by later
2714                        // reconciliation step
2715                    } else {
2716                        // we still have a disabled system package, but, it still might have
2717                        // been removed. check the code path still exists and check there's
2718                        // still a package. the latter can happen if an OTA keeps the same
2719                        // code path, but, changes the package name.
2720                        final PackageSetting disabledPs =
2721                                mSettings.getDisabledSystemPkgLPr(ps.name);
2722                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2723                                || disabledPs.pkg == null) {
2724                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2725                        }
2726                    }
2727                }
2728            }
2729
2730            //look for any incomplete package installations
2731            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2732            for (int i = 0; i < deletePkgsList.size(); i++) {
2733                // Actual deletion of code and data will be handled by later
2734                // reconciliation step
2735                final String packageName = deletePkgsList.get(i).name;
2736                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2737                synchronized (mPackages) {
2738                    mSettings.removePackageLPw(packageName);
2739                }
2740            }
2741
2742            //delete tmp files
2743            deleteTempPackageFiles();
2744
2745            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2746
2747            // Remove any shared userIDs that have no associated packages
2748            mSettings.pruneSharedUsersLPw();
2749            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2750            final int systemPackagesCount = mPackages.size();
2751            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2752                    + " ms, packageCount: " + systemPackagesCount
2753                    + " , timePerPackage: "
2754                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2755                    + " , cached: " + cachedSystemApps);
2756            if (mIsUpgrade && systemPackagesCount > 0) {
2757                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2758                        ((int) systemScanTime) / systemPackagesCount);
2759            }
2760            if (!mOnlyCore) {
2761                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2762                        SystemClock.uptimeMillis());
2763                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2764
2765                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2766                        | PackageParser.PARSE_FORWARD_LOCK,
2767                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2768
2769                // Remove disable package settings for updated system apps that were
2770                // removed via an OTA. If the update is no longer present, remove the
2771                // app completely. Otherwise, revoke their system privileges.
2772                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2773                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2774                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2775
2776                    final String msg;
2777                    if (deletedPkg == null) {
2778                        // should have found an update, but, we didn't; remove everything
2779                        msg = "Updated system package " + deletedAppName
2780                                + " no longer exists; removing its data";
2781                        // Actual deletion of code and data will be handled by later
2782                        // reconciliation step
2783                    } else {
2784                        // found an update; revoke system privileges
2785                        msg = "Updated system package + " + deletedAppName
2786                                + " no longer exists; revoking system privileges";
2787
2788                        // Don't do anything if a stub is removed from the system image. If
2789                        // we were to remove the uncompressed version from the /data partition,
2790                        // this is where it'd be done.
2791
2792                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2793                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2794                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2795                    }
2796                    logCriticalInfo(Log.WARN, msg);
2797                }
2798
2799                /*
2800                 * Make sure all system apps that we expected to appear on
2801                 * the userdata partition actually showed up. If they never
2802                 * appeared, crawl back and revive the system version.
2803                 */
2804                for (int i = 0; i < mExpectingBetter.size(); i++) {
2805                    final String packageName = mExpectingBetter.keyAt(i);
2806                    if (!mPackages.containsKey(packageName)) {
2807                        final File scanFile = mExpectingBetter.valueAt(i);
2808
2809                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2810                                + " but never showed up; reverting to system");
2811
2812                        int reparseFlags = mDefParseFlags;
2813                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2814                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2815                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2816                                    | PackageParser.PARSE_IS_PRIVILEGED;
2817                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2818                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2819                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2820                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2821                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2822                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2823                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2824                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2825                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2826                        } else {
2827                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2828                            continue;
2829                        }
2830
2831                        mSettings.enableSystemPackageLPw(packageName);
2832
2833                        try {
2834                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2835                        } catch (PackageManagerException e) {
2836                            Slog.e(TAG, "Failed to parse original system package: "
2837                                    + e.getMessage());
2838                        }
2839                    }
2840                }
2841
2842                // Uncompress and install any stubbed system applications.
2843                // This must be done last to ensure all stubs are replaced or disabled.
2844                decompressSystemApplications(stubSystemApps, scanFlags);
2845
2846                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2847                                - cachedSystemApps;
2848
2849                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2850                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2851                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2852                        + " ms, packageCount: " + dataPackagesCount
2853                        + " , timePerPackage: "
2854                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2855                        + " , cached: " + cachedNonSystemApps);
2856                if (mIsUpgrade && dataPackagesCount > 0) {
2857                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2858                            ((int) dataScanTime) / dataPackagesCount);
2859                }
2860            }
2861            mExpectingBetter.clear();
2862
2863            // Resolve the storage manager.
2864            mStorageManagerPackage = getStorageManagerPackageName();
2865
2866            // Resolve protected action filters. Only the setup wizard is allowed to
2867            // have a high priority filter for these actions.
2868            mSetupWizardPackage = getSetupWizardPackageName();
2869            if (mProtectedFilters.size() > 0) {
2870                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2871                    Slog.i(TAG, "No setup wizard;"
2872                        + " All protected intents capped to priority 0");
2873                }
2874                for (ActivityIntentInfo filter : mProtectedFilters) {
2875                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2876                        if (DEBUG_FILTERS) {
2877                            Slog.i(TAG, "Found setup wizard;"
2878                                + " allow priority " + filter.getPriority() + ";"
2879                                + " package: " + filter.activity.info.packageName
2880                                + " activity: " + filter.activity.className
2881                                + " priority: " + filter.getPriority());
2882                        }
2883                        // skip setup wizard; allow it to keep the high priority filter
2884                        continue;
2885                    }
2886                    if (DEBUG_FILTERS) {
2887                        Slog.i(TAG, "Protected action; cap priority to 0;"
2888                                + " package: " + filter.activity.info.packageName
2889                                + " activity: " + filter.activity.className
2890                                + " origPrio: " + filter.getPriority());
2891                    }
2892                    filter.setPriority(0);
2893                }
2894            }
2895            mDeferProtectedFilters = false;
2896            mProtectedFilters.clear();
2897
2898            // Now that we know all of the shared libraries, update all clients to have
2899            // the correct library paths.
2900            updateAllSharedLibrariesLPw(null);
2901
2902            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2903                // NOTE: We ignore potential failures here during a system scan (like
2904                // the rest of the commands above) because there's precious little we
2905                // can do about it. A settings error is reported, though.
2906                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2907            }
2908
2909            // Now that we know all the packages we are keeping,
2910            // read and update their last usage times.
2911            mPackageUsage.read(mPackages);
2912            mCompilerStats.read();
2913
2914            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2915                    SystemClock.uptimeMillis());
2916            Slog.i(TAG, "Time to scan packages: "
2917                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2918                    + " seconds");
2919
2920            // If the platform SDK has changed since the last time we booted,
2921            // we need to re-grant app permission to catch any new ones that
2922            // appear.  This is really a hack, and means that apps can in some
2923            // cases get permissions that the user didn't initially explicitly
2924            // allow...  it would be nice to have some better way to handle
2925            // this situation.
2926            int updateFlags = UPDATE_PERMISSIONS_ALL;
2927            if (ver.sdkVersion != mSdkVersion) {
2928                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2929                        + mSdkVersion + "; regranting permissions for internal storage");
2930                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2931            }
2932            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2933            ver.sdkVersion = mSdkVersion;
2934
2935            // If this is the first boot or an update from pre-M, and it is a normal
2936            // boot, then we need to initialize the default preferred apps across
2937            // all defined users.
2938            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2939                for (UserInfo user : sUserManager.getUsers(true)) {
2940                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2941                    applyFactoryDefaultBrowserLPw(user.id);
2942                    primeDomainVerificationsLPw(user.id);
2943                }
2944            }
2945
2946            // Prepare storage for system user really early during boot,
2947            // since core system apps like SettingsProvider and SystemUI
2948            // can't wait for user to start
2949            final int storageFlags;
2950            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2951                storageFlags = StorageManager.FLAG_STORAGE_DE;
2952            } else {
2953                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2954            }
2955            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2956                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2957                    true /* onlyCoreApps */);
2958            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2959                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2960                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2961                traceLog.traceBegin("AppDataFixup");
2962                try {
2963                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2964                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2965                } catch (InstallerException e) {
2966                    Slog.w(TAG, "Trouble fixing GIDs", e);
2967                }
2968                traceLog.traceEnd();
2969
2970                traceLog.traceBegin("AppDataPrepare");
2971                if (deferPackages == null || deferPackages.isEmpty()) {
2972                    return;
2973                }
2974                int count = 0;
2975                for (String pkgName : deferPackages) {
2976                    PackageParser.Package pkg = null;
2977                    synchronized (mPackages) {
2978                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2979                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2980                            pkg = ps.pkg;
2981                        }
2982                    }
2983                    if (pkg != null) {
2984                        synchronized (mInstallLock) {
2985                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2986                                    true /* maybeMigrateAppData */);
2987                        }
2988                        count++;
2989                    }
2990                }
2991                traceLog.traceEnd();
2992                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2993            }, "prepareAppData");
2994
2995            // If this is first boot after an OTA, and a normal boot, then
2996            // we need to clear code cache directories.
2997            // Note that we do *not* clear the application profiles. These remain valid
2998            // across OTAs and are used to drive profile verification (post OTA) and
2999            // profile compilation (without waiting to collect a fresh set of profiles).
3000            if (mIsUpgrade && !onlyCore) {
3001                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3002                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3003                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3004                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3005                        // No apps are running this early, so no need to freeze
3006                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3007                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3008                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3009                    }
3010                }
3011                ver.fingerprint = Build.FINGERPRINT;
3012            }
3013
3014            checkDefaultBrowser();
3015
3016            // clear only after permissions and other defaults have been updated
3017            mExistingSystemPackages.clear();
3018            mPromoteSystemApps = false;
3019
3020            // All the changes are done during package scanning.
3021            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3022
3023            // can downgrade to reader
3024            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3025            mSettings.writeLPr();
3026            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3027            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3028                    SystemClock.uptimeMillis());
3029
3030            if (!mOnlyCore) {
3031                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3032                mRequiredInstallerPackage = getRequiredInstallerLPr();
3033                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3034                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3035                if (mIntentFilterVerifierComponent != null) {
3036                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3037                            mIntentFilterVerifierComponent);
3038                } else {
3039                    mIntentFilterVerifier = null;
3040                }
3041                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3042                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3043                        SharedLibraryInfo.VERSION_UNDEFINED);
3044                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3045                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3046                        SharedLibraryInfo.VERSION_UNDEFINED);
3047            } else {
3048                mRequiredVerifierPackage = null;
3049                mRequiredInstallerPackage = null;
3050                mRequiredUninstallerPackage = null;
3051                mIntentFilterVerifierComponent = null;
3052                mIntentFilterVerifier = null;
3053                mServicesSystemSharedLibraryPackageName = null;
3054                mSharedSystemSharedLibraryPackageName = null;
3055            }
3056
3057            mInstallerService = new PackageInstallerService(context, this);
3058            final Pair<ComponentName, String> instantAppResolverComponent =
3059                    getInstantAppResolverLPr();
3060            if (instantAppResolverComponent != null) {
3061                if (DEBUG_EPHEMERAL) {
3062                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3063                }
3064                mInstantAppResolverConnection = new EphemeralResolverConnection(
3065                        mContext, instantAppResolverComponent.first,
3066                        instantAppResolverComponent.second);
3067                mInstantAppResolverSettingsComponent =
3068                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3069            } else {
3070                mInstantAppResolverConnection = null;
3071                mInstantAppResolverSettingsComponent = null;
3072            }
3073            updateInstantAppInstallerLocked(null);
3074
3075            // Read and update the usage of dex files.
3076            // Do this at the end of PM init so that all the packages have their
3077            // data directory reconciled.
3078            // At this point we know the code paths of the packages, so we can validate
3079            // the disk file and build the internal cache.
3080            // The usage file is expected to be small so loading and verifying it
3081            // should take a fairly small time compare to the other activities (e.g. package
3082            // scanning).
3083            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3084            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3085            for (int userId : currentUserIds) {
3086                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3087            }
3088            mDexManager.load(userPackages);
3089            if (mIsUpgrade) {
3090                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3091                        (int) (SystemClock.uptimeMillis() - startTime));
3092            }
3093        } // synchronized (mPackages)
3094        } // synchronized (mInstallLock)
3095
3096        // Now after opening every single application zip, make sure they
3097        // are all flushed.  Not really needed, but keeps things nice and
3098        // tidy.
3099        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3100        Runtime.getRuntime().gc();
3101        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3102
3103        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3104        FallbackCategoryProvider.loadFallbacks();
3105        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3106
3107        // The initial scanning above does many calls into installd while
3108        // holding the mPackages lock, but we're mostly interested in yelling
3109        // once we have a booted system.
3110        mInstaller.setWarnIfHeld(mPackages);
3111
3112        // Expose private service for system components to use.
3113        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3114        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3115    }
3116
3117    /**
3118     * Uncompress and install stub applications.
3119     * <p>In order to save space on the system partition, some applications are shipped in a
3120     * compressed form. In addition the compressed bits for the full application, the
3121     * system image contains a tiny stub comprised of only the Android manifest.
3122     * <p>During the first boot, attempt to uncompress and install the full application. If
3123     * the application can't be installed for any reason, disable the stub and prevent
3124     * uncompressing the full application during future boots.
3125     * <p>In order to forcefully attempt an installation of a full application, go to app
3126     * settings and enable the application.
3127     */
3128    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3129        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3130            final String pkgName = stubSystemApps.get(i);
3131            // skip if the system package is already disabled
3132            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3133                stubSystemApps.remove(i);
3134                continue;
3135            }
3136            // skip if the package isn't installed (?!); this should never happen
3137            final PackageParser.Package pkg = mPackages.get(pkgName);
3138            if (pkg == null) {
3139                stubSystemApps.remove(i);
3140                continue;
3141            }
3142            // skip if the package has been disabled by the user
3143            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3144            if (ps != null) {
3145                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3146                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3147                    stubSystemApps.remove(i);
3148                    continue;
3149                }
3150            }
3151
3152            if (DEBUG_COMPRESSION) {
3153                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3154            }
3155
3156            // uncompress the binary to its eventual destination on /data
3157            final File scanFile = decompressPackage(pkg);
3158            if (scanFile == null) {
3159                continue;
3160            }
3161
3162            // install the package to replace the stub on /system
3163            try {
3164                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3165                removePackageLI(pkg, true /*chatty*/);
3166                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3167                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3168                        UserHandle.USER_SYSTEM, "android");
3169                stubSystemApps.remove(i);
3170                continue;
3171            } catch (PackageManagerException e) {
3172                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3173            }
3174
3175            // any failed attempt to install the package will be cleaned up later
3176        }
3177
3178        // disable any stub still left; these failed to install the full application
3179        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3180            final String pkgName = stubSystemApps.get(i);
3181            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3182            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3183                    UserHandle.USER_SYSTEM, "android");
3184            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3185        }
3186    }
3187
3188    private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3189        if (DEBUG_COMPRESSION) {
3190            Slog.i(TAG, "Decompress file"
3191                    + "; src: " + srcFile.getAbsolutePath()
3192                    + ", dst: " + dstFile.getAbsolutePath());
3193        }
3194        try (
3195                InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3196                OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3197        ) {
3198            Streams.copy(fileIn, fileOut);
3199            Os.chmod(dstFile.getAbsolutePath(), 0644);
3200            return PackageManager.INSTALL_SUCCEEDED;
3201        } catch (IOException e) {
3202            logCriticalInfo(Log.ERROR, "Failed to decompress file"
3203                    + "; src: " + srcFile.getAbsolutePath()
3204                    + ", dst: " + dstFile.getAbsolutePath());
3205        }
3206        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3207    }
3208
3209    private File[] getCompressedFiles(String codePath) {
3210        final File stubCodePath = new File(codePath);
3211        final String stubName = stubCodePath.getName();
3212
3213        // The layout of a compressed package on a given partition is as follows :
3214        //
3215        // Compressed artifacts:
3216        //
3217        // /partition/ModuleName/foo.gz
3218        // /partation/ModuleName/bar.gz
3219        //
3220        // Stub artifact:
3221        //
3222        // /partition/ModuleName-Stub/ModuleName-Stub.apk
3223        //
3224        // In other words, stub is on the same partition as the compressed artifacts
3225        // and in a directory that's suffixed with "-Stub".
3226        int idx = stubName.lastIndexOf(STUB_SUFFIX);
3227        if (idx < 0 || (stubName.length() != (idx + STUB_SUFFIX.length()))) {
3228            return null;
3229        }
3230
3231        final File stubParentDir = stubCodePath.getParentFile();
3232        if (stubParentDir == null) {
3233            Slog.e(TAG, "Unable to determine stub parent dir for codePath: " + codePath);
3234            return null;
3235        }
3236
3237        final File compressedPath = new File(stubParentDir, stubName.substring(0, idx));
3238        final File[] files = compressedPath.listFiles(new FilenameFilter() {
3239            @Override
3240            public boolean accept(File dir, String name) {
3241                return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3242            }
3243        });
3244
3245        if (DEBUG_COMPRESSION && files != null && files.length > 0) {
3246            Slog.i(TAG, "getCompressedFiles[" + codePath + "]: " + Arrays.toString(files));
3247        }
3248
3249        return files;
3250    }
3251
3252    private boolean compressedFileExists(String codePath) {
3253        final File[] compressedFiles = getCompressedFiles(codePath);
3254        return compressedFiles != null && compressedFiles.length > 0;
3255    }
3256
3257    /**
3258     * Decompresses the given package on the system image onto
3259     * the /data partition.
3260     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3261     */
3262    private File decompressPackage(PackageParser.Package pkg) {
3263        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3264        if (compressedFiles == null || compressedFiles.length == 0) {
3265            if (DEBUG_COMPRESSION) {
3266                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3267            }
3268            return null;
3269        }
3270        final File dstCodePath =
3271                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3272        int ret = PackageManager.INSTALL_SUCCEEDED;
3273        try {
3274            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3275            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3276            for (File srcFile : compressedFiles) {
3277                final String srcFileName = srcFile.getName();
3278                final String dstFileName = srcFileName.substring(
3279                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3280                final File dstFile = new File(dstCodePath, dstFileName);
3281                ret = decompressFile(srcFile, dstFile);
3282                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3283                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3284                            + "; pkg: " + pkg.packageName
3285                            + ", file: " + dstFileName);
3286                    break;
3287                }
3288            }
3289        } catch (ErrnoException e) {
3290            logCriticalInfo(Log.ERROR, "Failed to decompress"
3291                    + "; pkg: " + pkg.packageName
3292                    + ", err: " + e.errno);
3293        }
3294        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3295            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3296            NativeLibraryHelper.Handle handle = null;
3297            try {
3298                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3299                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3300                        null /*abiOverride*/);
3301            } catch (IOException e) {
3302                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3303                        + "; pkg: " + pkg.packageName);
3304                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3305            } finally {
3306                IoUtils.closeQuietly(handle);
3307            }
3308        }
3309        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3310            if (dstCodePath == null || !dstCodePath.exists()) {
3311                return null;
3312            }
3313            removeCodePathLI(dstCodePath);
3314            return null;
3315        }
3316
3317        return dstCodePath;
3318    }
3319
3320    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3321        // we're only interested in updating the installer appliction when 1) it's not
3322        // already set or 2) the modified package is the installer
3323        if (mInstantAppInstallerActivity != null
3324                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3325                        .equals(modifiedPackage)) {
3326            return;
3327        }
3328        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3329    }
3330
3331    private static File preparePackageParserCache(boolean isUpgrade) {
3332        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3333            return null;
3334        }
3335
3336        // Disable package parsing on eng builds to allow for faster incremental development.
3337        if (Build.IS_ENG) {
3338            return null;
3339        }
3340
3341        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3342            Slog.i(TAG, "Disabling package parser cache due to system property.");
3343            return null;
3344        }
3345
3346        // The base directory for the package parser cache lives under /data/system/.
3347        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3348                "package_cache");
3349        if (cacheBaseDir == null) {
3350            return null;
3351        }
3352
3353        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3354        // This also serves to "GC" unused entries when the package cache version changes (which
3355        // can only happen during upgrades).
3356        if (isUpgrade) {
3357            FileUtils.deleteContents(cacheBaseDir);
3358        }
3359
3360
3361        // Return the versioned package cache directory. This is something like
3362        // "/data/system/package_cache/1"
3363        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3364
3365        // The following is a workaround to aid development on non-numbered userdebug
3366        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3367        // the system partition is newer.
3368        //
3369        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3370        // that starts with "eng." to signify that this is an engineering build and not
3371        // destined for release.
3372        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3373            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3374
3375            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3376            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3377            // in general and should not be used for production changes. In this specific case,
3378            // we know that they will work.
3379            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3380            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3381                FileUtils.deleteContents(cacheBaseDir);
3382                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3383            }
3384        }
3385
3386        return cacheDir;
3387    }
3388
3389    @Override
3390    public boolean isFirstBoot() {
3391        // allow instant applications
3392        return mFirstBoot;
3393    }
3394
3395    @Override
3396    public boolean isOnlyCoreApps() {
3397        // allow instant applications
3398        return mOnlyCore;
3399    }
3400
3401    @Override
3402    public boolean isUpgrade() {
3403        // allow instant applications
3404        return mIsUpgrade;
3405    }
3406
3407    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3408        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3409
3410        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3411                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3412                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3413        if (matches.size() == 1) {
3414            return matches.get(0).getComponentInfo().packageName;
3415        } else if (matches.size() == 0) {
3416            Log.e(TAG, "There should probably be a verifier, but, none were found");
3417            return null;
3418        }
3419        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3420    }
3421
3422    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3423        synchronized (mPackages) {
3424            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3425            if (libraryEntry == null) {
3426                throw new IllegalStateException("Missing required shared library:" + name);
3427            }
3428            return libraryEntry.apk;
3429        }
3430    }
3431
3432    private @NonNull String getRequiredInstallerLPr() {
3433        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3434        intent.addCategory(Intent.CATEGORY_DEFAULT);
3435        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3436
3437        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3438                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3439                UserHandle.USER_SYSTEM);
3440        if (matches.size() == 1) {
3441            ResolveInfo resolveInfo = matches.get(0);
3442            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3443                throw new RuntimeException("The installer must be a privileged app");
3444            }
3445            return matches.get(0).getComponentInfo().packageName;
3446        } else {
3447            throw new RuntimeException("There must be exactly one installer; found " + matches);
3448        }
3449    }
3450
3451    private @NonNull String getRequiredUninstallerLPr() {
3452        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3453        intent.addCategory(Intent.CATEGORY_DEFAULT);
3454        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3455
3456        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3457                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3458                UserHandle.USER_SYSTEM);
3459        if (resolveInfo == null ||
3460                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3461            throw new RuntimeException("There must be exactly one uninstaller; found "
3462                    + resolveInfo);
3463        }
3464        return resolveInfo.getComponentInfo().packageName;
3465    }
3466
3467    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3468        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3469
3470        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3471                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3472                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3473        ResolveInfo best = null;
3474        final int N = matches.size();
3475        for (int i = 0; i < N; i++) {
3476            final ResolveInfo cur = matches.get(i);
3477            final String packageName = cur.getComponentInfo().packageName;
3478            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3479                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3480                continue;
3481            }
3482
3483            if (best == null || cur.priority > best.priority) {
3484                best = cur;
3485            }
3486        }
3487
3488        if (best != null) {
3489            return best.getComponentInfo().getComponentName();
3490        }
3491        Slog.w(TAG, "Intent filter verifier not found");
3492        return null;
3493    }
3494
3495    @Override
3496    public @Nullable ComponentName getInstantAppResolverComponent() {
3497        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3498            return null;
3499        }
3500        synchronized (mPackages) {
3501            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3502            if (instantAppResolver == null) {
3503                return null;
3504            }
3505            return instantAppResolver.first;
3506        }
3507    }
3508
3509    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3510        final String[] packageArray =
3511                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3512        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3513            if (DEBUG_EPHEMERAL) {
3514                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3515            }
3516            return null;
3517        }
3518
3519        final int callingUid = Binder.getCallingUid();
3520        final int resolveFlags =
3521                MATCH_DIRECT_BOOT_AWARE
3522                | MATCH_DIRECT_BOOT_UNAWARE
3523                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3524        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3525        final Intent resolverIntent = new Intent(actionName);
3526        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3527                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3528        // temporarily look for the old action
3529        if (resolvers.size() == 0) {
3530            if (DEBUG_EPHEMERAL) {
3531                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3532            }
3533            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3534            resolverIntent.setAction(actionName);
3535            resolvers = queryIntentServicesInternal(resolverIntent, null,
3536                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3537        }
3538        final int N = resolvers.size();
3539        if (N == 0) {
3540            if (DEBUG_EPHEMERAL) {
3541                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3542            }
3543            return null;
3544        }
3545
3546        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3547        for (int i = 0; i < N; i++) {
3548            final ResolveInfo info = resolvers.get(i);
3549
3550            if (info.serviceInfo == null) {
3551                continue;
3552            }
3553
3554            final String packageName = info.serviceInfo.packageName;
3555            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3556                if (DEBUG_EPHEMERAL) {
3557                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3558                            + " pkg: " + packageName + ", info:" + info);
3559                }
3560                continue;
3561            }
3562
3563            if (DEBUG_EPHEMERAL) {
3564                Slog.v(TAG, "Ephemeral resolver found;"
3565                        + " pkg: " + packageName + ", info:" + info);
3566            }
3567            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3568        }
3569        if (DEBUG_EPHEMERAL) {
3570            Slog.v(TAG, "Ephemeral resolver NOT found");
3571        }
3572        return null;
3573    }
3574
3575    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3576        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3577        intent.addCategory(Intent.CATEGORY_DEFAULT);
3578        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3579
3580        final int resolveFlags =
3581                MATCH_DIRECT_BOOT_AWARE
3582                | MATCH_DIRECT_BOOT_UNAWARE
3583                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3584        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3585                resolveFlags, UserHandle.USER_SYSTEM);
3586        // temporarily look for the old action
3587        if (matches.isEmpty()) {
3588            if (DEBUG_EPHEMERAL) {
3589                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3590            }
3591            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3592            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3593                    resolveFlags, UserHandle.USER_SYSTEM);
3594        }
3595        Iterator<ResolveInfo> iter = matches.iterator();
3596        while (iter.hasNext()) {
3597            final ResolveInfo rInfo = iter.next();
3598            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3599            if (ps != null) {
3600                final PermissionsState permissionsState = ps.getPermissionsState();
3601                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3602                    continue;
3603                }
3604            }
3605            iter.remove();
3606        }
3607        if (matches.size() == 0) {
3608            return null;
3609        } else if (matches.size() == 1) {
3610            return (ActivityInfo) matches.get(0).getComponentInfo();
3611        } else {
3612            throw new RuntimeException(
3613                    "There must be at most one ephemeral installer; found " + matches);
3614        }
3615    }
3616
3617    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3618            @NonNull ComponentName resolver) {
3619        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3620                .addCategory(Intent.CATEGORY_DEFAULT)
3621                .setPackage(resolver.getPackageName());
3622        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3623        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3624                UserHandle.USER_SYSTEM);
3625        // temporarily look for the old action
3626        if (matches.isEmpty()) {
3627            if (DEBUG_EPHEMERAL) {
3628                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3629            }
3630            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3631            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3632                    UserHandle.USER_SYSTEM);
3633        }
3634        if (matches.isEmpty()) {
3635            return null;
3636        }
3637        return matches.get(0).getComponentInfo().getComponentName();
3638    }
3639
3640    private void primeDomainVerificationsLPw(int userId) {
3641        if (DEBUG_DOMAIN_VERIFICATION) {
3642            Slog.d(TAG, "Priming domain verifications in user " + userId);
3643        }
3644
3645        SystemConfig systemConfig = SystemConfig.getInstance();
3646        ArraySet<String> packages = systemConfig.getLinkedApps();
3647
3648        for (String packageName : packages) {
3649            PackageParser.Package pkg = mPackages.get(packageName);
3650            if (pkg != null) {
3651                if (!pkg.isSystemApp()) {
3652                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3653                    continue;
3654                }
3655
3656                ArraySet<String> domains = null;
3657                for (PackageParser.Activity a : pkg.activities) {
3658                    for (ActivityIntentInfo filter : a.intents) {
3659                        if (hasValidDomains(filter)) {
3660                            if (domains == null) {
3661                                domains = new ArraySet<String>();
3662                            }
3663                            domains.addAll(filter.getHostsList());
3664                        }
3665                    }
3666                }
3667
3668                if (domains != null && domains.size() > 0) {
3669                    if (DEBUG_DOMAIN_VERIFICATION) {
3670                        Slog.v(TAG, "      + " + packageName);
3671                    }
3672                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3673                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3674                    // and then 'always' in the per-user state actually used for intent resolution.
3675                    final IntentFilterVerificationInfo ivi;
3676                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3677                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3678                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3679                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3680                } else {
3681                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3682                            + "' does not handle web links");
3683                }
3684            } else {
3685                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3686            }
3687        }
3688
3689        scheduleWritePackageRestrictionsLocked(userId);
3690        scheduleWriteSettingsLocked();
3691    }
3692
3693    private void applyFactoryDefaultBrowserLPw(int userId) {
3694        // The default browser app's package name is stored in a string resource,
3695        // with a product-specific overlay used for vendor customization.
3696        String browserPkg = mContext.getResources().getString(
3697                com.android.internal.R.string.default_browser);
3698        if (!TextUtils.isEmpty(browserPkg)) {
3699            // non-empty string => required to be a known package
3700            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3701            if (ps == null) {
3702                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3703                browserPkg = null;
3704            } else {
3705                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3706            }
3707        }
3708
3709        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3710        // default.  If there's more than one, just leave everything alone.
3711        if (browserPkg == null) {
3712            calculateDefaultBrowserLPw(userId);
3713        }
3714    }
3715
3716    private void calculateDefaultBrowserLPw(int userId) {
3717        List<String> allBrowsers = resolveAllBrowserApps(userId);
3718        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3719        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3720    }
3721
3722    private List<String> resolveAllBrowserApps(int userId) {
3723        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3724        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3725                PackageManager.MATCH_ALL, userId);
3726
3727        final int count = list.size();
3728        List<String> result = new ArrayList<String>(count);
3729        for (int i=0; i<count; i++) {
3730            ResolveInfo info = list.get(i);
3731            if (info.activityInfo == null
3732                    || !info.handleAllWebDataURI
3733                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3734                    || result.contains(info.activityInfo.packageName)) {
3735                continue;
3736            }
3737            result.add(info.activityInfo.packageName);
3738        }
3739
3740        return result;
3741    }
3742
3743    private boolean packageIsBrowser(String packageName, int userId) {
3744        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3745                PackageManager.MATCH_ALL, userId);
3746        final int N = list.size();
3747        for (int i = 0; i < N; i++) {
3748            ResolveInfo info = list.get(i);
3749            if (packageName.equals(info.activityInfo.packageName)) {
3750                return true;
3751            }
3752        }
3753        return false;
3754    }
3755
3756    private void checkDefaultBrowser() {
3757        final int myUserId = UserHandle.myUserId();
3758        final String packageName = getDefaultBrowserPackageName(myUserId);
3759        if (packageName != null) {
3760            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3761            if (info == null) {
3762                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3763                synchronized (mPackages) {
3764                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3765                }
3766            }
3767        }
3768    }
3769
3770    @Override
3771    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3772            throws RemoteException {
3773        try {
3774            return super.onTransact(code, data, reply, flags);
3775        } catch (RuntimeException e) {
3776            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3777                Slog.wtf(TAG, "Package Manager Crash", e);
3778            }
3779            throw e;
3780        }
3781    }
3782
3783    static int[] appendInts(int[] cur, int[] add) {
3784        if (add == null) return cur;
3785        if (cur == null) return add;
3786        final int N = add.length;
3787        for (int i=0; i<N; i++) {
3788            cur = appendInt(cur, add[i]);
3789        }
3790        return cur;
3791    }
3792
3793    /**
3794     * Returns whether or not a full application can see an instant application.
3795     * <p>
3796     * Currently, there are three cases in which this can occur:
3797     * <ol>
3798     * <li>The calling application is a "special" process. Special processes
3799     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3800     * <li>The calling application has the permission
3801     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3802     * <li>The calling application is the default launcher on the
3803     *     system partition.</li>
3804     * </ol>
3805     */
3806    private boolean canViewInstantApps(int callingUid, int userId) {
3807        if (callingUid < Process.FIRST_APPLICATION_UID) {
3808            return true;
3809        }
3810        if (mContext.checkCallingOrSelfPermission(
3811                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3812            return true;
3813        }
3814        if (mContext.checkCallingOrSelfPermission(
3815                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3816            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3817            if (homeComponent != null
3818                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3819                return true;
3820            }
3821        }
3822        return false;
3823    }
3824
3825    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3826        if (!sUserManager.exists(userId)) return null;
3827        if (ps == null) {
3828            return null;
3829        }
3830        PackageParser.Package p = ps.pkg;
3831        if (p == null) {
3832            return null;
3833        }
3834        final int callingUid = Binder.getCallingUid();
3835        // Filter out ephemeral app metadata:
3836        //   * The system/shell/root can see metadata for any app
3837        //   * An installed app can see metadata for 1) other installed apps
3838        //     and 2) ephemeral apps that have explicitly interacted with it
3839        //   * Ephemeral apps can only see their own data and exposed installed apps
3840        //   * Holding a signature permission allows seeing instant apps
3841        if (filterAppAccessLPr(ps, callingUid, userId)) {
3842            return null;
3843        }
3844
3845        final PermissionsState permissionsState = ps.getPermissionsState();
3846
3847        // Compute GIDs only if requested
3848        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3849                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3850        // Compute granted permissions only if package has requested permissions
3851        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3852                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3853        final PackageUserState state = ps.readUserState(userId);
3854
3855        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3856                && ps.isSystem()) {
3857            flags |= MATCH_ANY_USER;
3858        }
3859
3860        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3861                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3862
3863        if (packageInfo == null) {
3864            return null;
3865        }
3866
3867        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3868                resolveExternalPackageNameLPr(p);
3869
3870        return packageInfo;
3871    }
3872
3873    @Override
3874    public void checkPackageStartable(String packageName, int userId) {
3875        final int callingUid = Binder.getCallingUid();
3876        if (getInstantAppPackageName(callingUid) != null) {
3877            throw new SecurityException("Instant applications don't have access to this method");
3878        }
3879        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3880        synchronized (mPackages) {
3881            final PackageSetting ps = mSettings.mPackages.get(packageName);
3882            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3883                throw new SecurityException("Package " + packageName + " was not found!");
3884            }
3885
3886            if (!ps.getInstalled(userId)) {
3887                throw new SecurityException(
3888                        "Package " + packageName + " was not installed for user " + userId + "!");
3889            }
3890
3891            if (mSafeMode && !ps.isSystem()) {
3892                throw new SecurityException("Package " + packageName + " not a system app!");
3893            }
3894
3895            if (mFrozenPackages.contains(packageName)) {
3896                throw new SecurityException("Package " + packageName + " is currently frozen!");
3897            }
3898
3899            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3900                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3901            }
3902        }
3903    }
3904
3905    @Override
3906    public boolean isPackageAvailable(String packageName, int userId) {
3907        if (!sUserManager.exists(userId)) return false;
3908        final int callingUid = Binder.getCallingUid();
3909        enforceCrossUserPermission(callingUid, userId,
3910                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3911        synchronized (mPackages) {
3912            PackageParser.Package p = mPackages.get(packageName);
3913            if (p != null) {
3914                final PackageSetting ps = (PackageSetting) p.mExtras;
3915                if (filterAppAccessLPr(ps, callingUid, userId)) {
3916                    return false;
3917                }
3918                if (ps != null) {
3919                    final PackageUserState state = ps.readUserState(userId);
3920                    if (state != null) {
3921                        return PackageParser.isAvailable(state);
3922                    }
3923                }
3924            }
3925        }
3926        return false;
3927    }
3928
3929    @Override
3930    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3931        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3932                flags, Binder.getCallingUid(), userId);
3933    }
3934
3935    @Override
3936    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3937            int flags, int userId) {
3938        return getPackageInfoInternal(versionedPackage.getPackageName(),
3939                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3940    }
3941
3942    /**
3943     * Important: The provided filterCallingUid is used exclusively to filter out packages
3944     * that can be seen based on user state. It's typically the original caller uid prior
3945     * to clearing. Because it can only be provided by trusted code, it's value can be
3946     * trusted and will be used as-is; unlike userId which will be validated by this method.
3947     */
3948    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3949            int flags, int filterCallingUid, int userId) {
3950        if (!sUserManager.exists(userId)) return null;
3951        flags = updateFlagsForPackage(flags, userId, packageName);
3952        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3953                false /* requireFullPermission */, false /* checkShell */, "get package info");
3954
3955        // reader
3956        synchronized (mPackages) {
3957            // Normalize package name to handle renamed packages and static libs
3958            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3959
3960            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3961            if (matchFactoryOnly) {
3962                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3963                if (ps != null) {
3964                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3965                        return null;
3966                    }
3967                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3968                        return null;
3969                    }
3970                    return generatePackageInfo(ps, flags, userId);
3971                }
3972            }
3973
3974            PackageParser.Package p = mPackages.get(packageName);
3975            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3976                return null;
3977            }
3978            if (DEBUG_PACKAGE_INFO)
3979                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3980            if (p != null) {
3981                final PackageSetting ps = (PackageSetting) p.mExtras;
3982                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3983                    return null;
3984                }
3985                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3986                    return null;
3987                }
3988                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3989            }
3990            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3991                final PackageSetting ps = mSettings.mPackages.get(packageName);
3992                if (ps == null) return null;
3993                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3994                    return null;
3995                }
3996                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3997                    return null;
3998                }
3999                return generatePackageInfo(ps, flags, userId);
4000            }
4001        }
4002        return null;
4003    }
4004
4005    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4006        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4007            return true;
4008        }
4009        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4010            return true;
4011        }
4012        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4013            return true;
4014        }
4015        return false;
4016    }
4017
4018    private boolean isComponentVisibleToInstantApp(
4019            @Nullable ComponentName component, @ComponentType int type) {
4020        if (type == TYPE_ACTIVITY) {
4021            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4022            return activity != null
4023                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4024                    : false;
4025        } else if (type == TYPE_RECEIVER) {
4026            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4027            return activity != null
4028                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4029                    : false;
4030        } else if (type == TYPE_SERVICE) {
4031            final PackageParser.Service service = mServices.mServices.get(component);
4032            return service != null
4033                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4034                    : false;
4035        } else if (type == TYPE_PROVIDER) {
4036            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4037            return provider != null
4038                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4039                    : false;
4040        } else if (type == TYPE_UNKNOWN) {
4041            return isComponentVisibleToInstantApp(component);
4042        }
4043        return false;
4044    }
4045
4046    /**
4047     * Returns whether or not access to the application should be filtered.
4048     * <p>
4049     * Access may be limited based upon whether the calling or target applications
4050     * are instant applications.
4051     *
4052     * @see #canAccessInstantApps(int)
4053     */
4054    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4055            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4056        // if we're in an isolated process, get the real calling UID
4057        if (Process.isIsolated(callingUid)) {
4058            callingUid = mIsolatedOwners.get(callingUid);
4059        }
4060        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4061        final boolean callerIsInstantApp = instantAppPkgName != null;
4062        if (ps == null) {
4063            if (callerIsInstantApp) {
4064                // pretend the application exists, but, needs to be filtered
4065                return true;
4066            }
4067            return false;
4068        }
4069        // if the target and caller are the same application, don't filter
4070        if (isCallerSameApp(ps.name, callingUid)) {
4071            return false;
4072        }
4073        if (callerIsInstantApp) {
4074            // request for a specific component; if it hasn't been explicitly exposed, filter
4075            if (component != null) {
4076                return !isComponentVisibleToInstantApp(component, componentType);
4077            }
4078            // request for application; if no components have been explicitly exposed, filter
4079            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4080        }
4081        if (ps.getInstantApp(userId)) {
4082            // caller can see all components of all instant applications, don't filter
4083            if (canViewInstantApps(callingUid, userId)) {
4084                return false;
4085            }
4086            // request for a specific instant application component, filter
4087            if (component != null) {
4088                return true;
4089            }
4090            // request for an instant application; if the caller hasn't been granted access, filter
4091            return !mInstantAppRegistry.isInstantAccessGranted(
4092                    userId, UserHandle.getAppId(callingUid), ps.appId);
4093        }
4094        return false;
4095    }
4096
4097    /**
4098     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4099     */
4100    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4101        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4102    }
4103
4104    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4105            int flags) {
4106        // Callers can access only the libs they depend on, otherwise they need to explicitly
4107        // ask for the shared libraries given the caller is allowed to access all static libs.
4108        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4109            // System/shell/root get to see all static libs
4110            final int appId = UserHandle.getAppId(uid);
4111            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4112                    || appId == Process.ROOT_UID) {
4113                return false;
4114            }
4115        }
4116
4117        // No package means no static lib as it is always on internal storage
4118        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4119            return false;
4120        }
4121
4122        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4123                ps.pkg.staticSharedLibVersion);
4124        if (libEntry == null) {
4125            return false;
4126        }
4127
4128        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4129        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4130        if (uidPackageNames == null) {
4131            return true;
4132        }
4133
4134        for (String uidPackageName : uidPackageNames) {
4135            if (ps.name.equals(uidPackageName)) {
4136                return false;
4137            }
4138            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4139            if (uidPs != null) {
4140                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4141                        libEntry.info.getName());
4142                if (index < 0) {
4143                    continue;
4144                }
4145                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4146                    return false;
4147                }
4148            }
4149        }
4150        return true;
4151    }
4152
4153    @Override
4154    public String[] currentToCanonicalPackageNames(String[] names) {
4155        final int callingUid = Binder.getCallingUid();
4156        if (getInstantAppPackageName(callingUid) != null) {
4157            return names;
4158        }
4159        final String[] out = new String[names.length];
4160        // reader
4161        synchronized (mPackages) {
4162            final int callingUserId = UserHandle.getUserId(callingUid);
4163            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4164            for (int i=names.length-1; i>=0; i--) {
4165                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4166                boolean translateName = false;
4167                if (ps != null && ps.realName != null) {
4168                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4169                    translateName = !targetIsInstantApp
4170                            || canViewInstantApps
4171                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4172                                    UserHandle.getAppId(callingUid), ps.appId);
4173                }
4174                out[i] = translateName ? ps.realName : names[i];
4175            }
4176        }
4177        return out;
4178    }
4179
4180    @Override
4181    public String[] canonicalToCurrentPackageNames(String[] names) {
4182        final int callingUid = Binder.getCallingUid();
4183        if (getInstantAppPackageName(callingUid) != null) {
4184            return names;
4185        }
4186        final String[] out = new String[names.length];
4187        // reader
4188        synchronized (mPackages) {
4189            final int callingUserId = UserHandle.getUserId(callingUid);
4190            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4191            for (int i=names.length-1; i>=0; i--) {
4192                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4193                boolean translateName = false;
4194                if (cur != null) {
4195                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4196                    final boolean targetIsInstantApp =
4197                            ps != null && ps.getInstantApp(callingUserId);
4198                    translateName = !targetIsInstantApp
4199                            || canViewInstantApps
4200                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4201                                    UserHandle.getAppId(callingUid), ps.appId);
4202                }
4203                out[i] = translateName ? cur : names[i];
4204            }
4205        }
4206        return out;
4207    }
4208
4209    @Override
4210    public int getPackageUid(String packageName, int flags, int userId) {
4211        if (!sUserManager.exists(userId)) return -1;
4212        final int callingUid = Binder.getCallingUid();
4213        flags = updateFlagsForPackage(flags, userId, packageName);
4214        enforceCrossUserPermission(callingUid, userId,
4215                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4216
4217        // reader
4218        synchronized (mPackages) {
4219            final PackageParser.Package p = mPackages.get(packageName);
4220            if (p != null && p.isMatch(flags)) {
4221                PackageSetting ps = (PackageSetting) p.mExtras;
4222                if (filterAppAccessLPr(ps, callingUid, userId)) {
4223                    return -1;
4224                }
4225                return UserHandle.getUid(userId, p.applicationInfo.uid);
4226            }
4227            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4228                final PackageSetting ps = mSettings.mPackages.get(packageName);
4229                if (ps != null && ps.isMatch(flags)
4230                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4231                    return UserHandle.getUid(userId, ps.appId);
4232                }
4233            }
4234        }
4235
4236        return -1;
4237    }
4238
4239    @Override
4240    public int[] getPackageGids(String packageName, int flags, int userId) {
4241        if (!sUserManager.exists(userId)) return null;
4242        final int callingUid = Binder.getCallingUid();
4243        flags = updateFlagsForPackage(flags, userId, packageName);
4244        enforceCrossUserPermission(callingUid, userId,
4245                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4246
4247        // reader
4248        synchronized (mPackages) {
4249            final PackageParser.Package p = mPackages.get(packageName);
4250            if (p != null && p.isMatch(flags)) {
4251                PackageSetting ps = (PackageSetting) p.mExtras;
4252                if (filterAppAccessLPr(ps, callingUid, userId)) {
4253                    return null;
4254                }
4255                // TODO: Shouldn't this be checking for package installed state for userId and
4256                // return null?
4257                return ps.getPermissionsState().computeGids(userId);
4258            }
4259            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4260                final PackageSetting ps = mSettings.mPackages.get(packageName);
4261                if (ps != null && ps.isMatch(flags)
4262                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4263                    return ps.getPermissionsState().computeGids(userId);
4264                }
4265            }
4266        }
4267
4268        return null;
4269    }
4270
4271    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4272        if (bp.perm != null) {
4273            return PackageParser.generatePermissionInfo(bp.perm, flags);
4274        }
4275        PermissionInfo pi = new PermissionInfo();
4276        pi.name = bp.name;
4277        pi.packageName = bp.sourcePackage;
4278        pi.nonLocalizedLabel = bp.name;
4279        pi.protectionLevel = bp.protectionLevel;
4280        return pi;
4281    }
4282
4283    @Override
4284    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4285        final int callingUid = Binder.getCallingUid();
4286        if (getInstantAppPackageName(callingUid) != null) {
4287            return null;
4288        }
4289        // reader
4290        synchronized (mPackages) {
4291            final BasePermission p = mSettings.mPermissions.get(name);
4292            if (p == null) {
4293                return null;
4294            }
4295            // If the caller is an app that targets pre 26 SDK drop protection flags.
4296            PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4297            if (permissionInfo != null) {
4298                final int protectionLevel = adjustPermissionProtectionFlagsLPr(
4299                        permissionInfo.protectionLevel, packageName, callingUid);
4300                if (permissionInfo.protectionLevel != protectionLevel) {
4301                    // If we return different protection level, don't use the cached info
4302                    if (p.perm != null && p.perm.info == permissionInfo) {
4303                        permissionInfo = new PermissionInfo(permissionInfo);
4304                    }
4305                    permissionInfo.protectionLevel = protectionLevel;
4306                }
4307            }
4308            return permissionInfo;
4309        }
4310    }
4311
4312    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4313            String packageName, int uid) {
4314        // Signature permission flags area always reported
4315        final int protectionLevelMasked = protectionLevel
4316                & (PermissionInfo.PROTECTION_NORMAL
4317                | PermissionInfo.PROTECTION_DANGEROUS
4318                | PermissionInfo.PROTECTION_SIGNATURE);
4319        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4320            return protectionLevel;
4321        }
4322
4323        // System sees all flags.
4324        final int appId = UserHandle.getAppId(uid);
4325        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4326                || appId == Process.SHELL_UID) {
4327            return protectionLevel;
4328        }
4329
4330        // Normalize package name to handle renamed packages and static libs
4331        packageName = resolveInternalPackageNameLPr(packageName,
4332                PackageManager.VERSION_CODE_HIGHEST);
4333
4334        // Apps that target O see flags for all protection levels.
4335        final PackageSetting ps = mSettings.mPackages.get(packageName);
4336        if (ps == null) {
4337            return protectionLevel;
4338        }
4339        if (ps.appId != appId) {
4340            return protectionLevel;
4341        }
4342
4343        final PackageParser.Package pkg = mPackages.get(packageName);
4344        if (pkg == null) {
4345            return protectionLevel;
4346        }
4347        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4348            return protectionLevelMasked;
4349        }
4350
4351        return protectionLevel;
4352    }
4353
4354    @Override
4355    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4356            int flags) {
4357        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4358            return null;
4359        }
4360        // reader
4361        synchronized (mPackages) {
4362            if (group != null && !mPermissionGroups.containsKey(group)) {
4363                // This is thrown as NameNotFoundException
4364                return null;
4365            }
4366
4367            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4368            for (BasePermission p : mSettings.mPermissions.values()) {
4369                if (group == null) {
4370                    if (p.perm == null || p.perm.info.group == null) {
4371                        out.add(generatePermissionInfo(p, flags));
4372                    }
4373                } else {
4374                    if (p.perm != null && group.equals(p.perm.info.group)) {
4375                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4376                    }
4377                }
4378            }
4379            return new ParceledListSlice<>(out);
4380        }
4381    }
4382
4383    @Override
4384    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4385        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4386            return null;
4387        }
4388        // reader
4389        synchronized (mPackages) {
4390            return PackageParser.generatePermissionGroupInfo(
4391                    mPermissionGroups.get(name), flags);
4392        }
4393    }
4394
4395    @Override
4396    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4397        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4398            return ParceledListSlice.emptyList();
4399        }
4400        // reader
4401        synchronized (mPackages) {
4402            final int N = mPermissionGroups.size();
4403            ArrayList<PermissionGroupInfo> out
4404                    = new ArrayList<PermissionGroupInfo>(N);
4405            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4406                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4407            }
4408            return new ParceledListSlice<>(out);
4409        }
4410    }
4411
4412    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4413            int filterCallingUid, int userId) {
4414        if (!sUserManager.exists(userId)) return null;
4415        PackageSetting ps = mSettings.mPackages.get(packageName);
4416        if (ps != null) {
4417            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4418                return null;
4419            }
4420            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4421                return null;
4422            }
4423            if (ps.pkg == null) {
4424                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4425                if (pInfo != null) {
4426                    return pInfo.applicationInfo;
4427                }
4428                return null;
4429            }
4430            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4431                    ps.readUserState(userId), userId);
4432            if (ai != null) {
4433                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4434            }
4435            return ai;
4436        }
4437        return null;
4438    }
4439
4440    @Override
4441    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4442        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4443    }
4444
4445    /**
4446     * Important: The provided filterCallingUid is used exclusively to filter out applications
4447     * that can be seen based on user state. It's typically the original caller uid prior
4448     * to clearing. Because it can only be provided by trusted code, it's value can be
4449     * trusted and will be used as-is; unlike userId which will be validated by this method.
4450     */
4451    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4452            int filterCallingUid, int userId) {
4453        if (!sUserManager.exists(userId)) return null;
4454        flags = updateFlagsForApplication(flags, userId, packageName);
4455        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4456                false /* requireFullPermission */, false /* checkShell */, "get application info");
4457
4458        // writer
4459        synchronized (mPackages) {
4460            // Normalize package name to handle renamed packages and static libs
4461            packageName = resolveInternalPackageNameLPr(packageName,
4462                    PackageManager.VERSION_CODE_HIGHEST);
4463
4464            PackageParser.Package p = mPackages.get(packageName);
4465            if (DEBUG_PACKAGE_INFO) Log.v(
4466                    TAG, "getApplicationInfo " + packageName
4467                    + ": " + p);
4468            if (p != null) {
4469                PackageSetting ps = mSettings.mPackages.get(packageName);
4470                if (ps == null) return null;
4471                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4472                    return null;
4473                }
4474                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4475                    return null;
4476                }
4477                // Note: isEnabledLP() does not apply here - always return info
4478                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4479                        p, flags, ps.readUserState(userId), userId);
4480                if (ai != null) {
4481                    ai.packageName = resolveExternalPackageNameLPr(p);
4482                }
4483                return ai;
4484            }
4485            if ("android".equals(packageName)||"system".equals(packageName)) {
4486                return mAndroidApplication;
4487            }
4488            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4489                // Already generates the external package name
4490                return generateApplicationInfoFromSettingsLPw(packageName,
4491                        flags, filterCallingUid, userId);
4492            }
4493        }
4494        return null;
4495    }
4496
4497    private String normalizePackageNameLPr(String packageName) {
4498        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4499        return normalizedPackageName != null ? normalizedPackageName : packageName;
4500    }
4501
4502    @Override
4503    public void deletePreloadsFileCache() {
4504        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4505            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4506        }
4507        File dir = Environment.getDataPreloadsFileCacheDirectory();
4508        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4509        FileUtils.deleteContents(dir);
4510    }
4511
4512    @Override
4513    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4514            final int storageFlags, final IPackageDataObserver observer) {
4515        mContext.enforceCallingOrSelfPermission(
4516                android.Manifest.permission.CLEAR_APP_CACHE, null);
4517        mHandler.post(() -> {
4518            boolean success = false;
4519            try {
4520                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4521                success = true;
4522            } catch (IOException e) {
4523                Slog.w(TAG, e);
4524            }
4525            if (observer != null) {
4526                try {
4527                    observer.onRemoveCompleted(null, success);
4528                } catch (RemoteException e) {
4529                    Slog.w(TAG, e);
4530                }
4531            }
4532        });
4533    }
4534
4535    @Override
4536    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4537            final int storageFlags, final IntentSender pi) {
4538        mContext.enforceCallingOrSelfPermission(
4539                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4540        mHandler.post(() -> {
4541            boolean success = false;
4542            try {
4543                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4544                success = true;
4545            } catch (IOException e) {
4546                Slog.w(TAG, e);
4547            }
4548            if (pi != null) {
4549                try {
4550                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4551                } catch (SendIntentException e) {
4552                    Slog.w(TAG, e);
4553                }
4554            }
4555        });
4556    }
4557
4558    /**
4559     * Blocking call to clear various types of cached data across the system
4560     * until the requested bytes are available.
4561     */
4562    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4563        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4564        final File file = storage.findPathForUuid(volumeUuid);
4565        if (file.getUsableSpace() >= bytes) return;
4566
4567        if (ENABLE_FREE_CACHE_V2) {
4568            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4569                    volumeUuid);
4570            final boolean aggressive = (storageFlags
4571                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4572            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4573
4574            // 1. Pre-flight to determine if we have any chance to succeed
4575            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4576            if (internalVolume && (aggressive || SystemProperties
4577                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4578                deletePreloadsFileCache();
4579                if (file.getUsableSpace() >= bytes) return;
4580            }
4581
4582            // 3. Consider parsed APK data (aggressive only)
4583            if (internalVolume && aggressive) {
4584                FileUtils.deleteContents(mCacheDir);
4585                if (file.getUsableSpace() >= bytes) return;
4586            }
4587
4588            // 4. Consider cached app data (above quotas)
4589            try {
4590                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4591                        Installer.FLAG_FREE_CACHE_V2);
4592            } catch (InstallerException ignored) {
4593            }
4594            if (file.getUsableSpace() >= bytes) return;
4595
4596            // 5. Consider shared libraries with refcount=0 and age>min cache period
4597            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4598                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4599                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4600                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4601                return;
4602            }
4603
4604            // 6. Consider dexopt output (aggressive only)
4605            // TODO: Implement
4606
4607            // 7. Consider installed instant apps unused longer than min cache period
4608            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4609                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4610                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4611                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4612                return;
4613            }
4614
4615            // 8. Consider cached app data (below quotas)
4616            try {
4617                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4618                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4619            } catch (InstallerException ignored) {
4620            }
4621            if (file.getUsableSpace() >= bytes) return;
4622
4623            // 9. Consider DropBox entries
4624            // TODO: Implement
4625
4626            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4627            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4628                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4629                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4630                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4631                return;
4632            }
4633        } else {
4634            try {
4635                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4636            } catch (InstallerException ignored) {
4637            }
4638            if (file.getUsableSpace() >= bytes) return;
4639        }
4640
4641        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4642    }
4643
4644    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4645            throws IOException {
4646        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4647        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4648
4649        List<VersionedPackage> packagesToDelete = null;
4650        final long now = System.currentTimeMillis();
4651
4652        synchronized (mPackages) {
4653            final int[] allUsers = sUserManager.getUserIds();
4654            final int libCount = mSharedLibraries.size();
4655            for (int i = 0; i < libCount; i++) {
4656                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4657                if (versionedLib == null) {
4658                    continue;
4659                }
4660                final int versionCount = versionedLib.size();
4661                for (int j = 0; j < versionCount; j++) {
4662                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4663                    // Skip packages that are not static shared libs.
4664                    if (!libInfo.isStatic()) {
4665                        break;
4666                    }
4667                    // Important: We skip static shared libs used for some user since
4668                    // in such a case we need to keep the APK on the device. The check for
4669                    // a lib being used for any user is performed by the uninstall call.
4670                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4671                    // Resolve the package name - we use synthetic package names internally
4672                    final String internalPackageName = resolveInternalPackageNameLPr(
4673                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4674                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4675                    // Skip unused static shared libs cached less than the min period
4676                    // to prevent pruning a lib needed by a subsequently installed package.
4677                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4678                        continue;
4679                    }
4680                    if (packagesToDelete == null) {
4681                        packagesToDelete = new ArrayList<>();
4682                    }
4683                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4684                            declaringPackage.getVersionCode()));
4685                }
4686            }
4687        }
4688
4689        if (packagesToDelete != null) {
4690            final int packageCount = packagesToDelete.size();
4691            for (int i = 0; i < packageCount; i++) {
4692                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4693                // Delete the package synchronously (will fail of the lib used for any user).
4694                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4695                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4696                                == PackageManager.DELETE_SUCCEEDED) {
4697                    if (volume.getUsableSpace() >= neededSpace) {
4698                        return true;
4699                    }
4700                }
4701            }
4702        }
4703
4704        return false;
4705    }
4706
4707    /**
4708     * Update given flags based on encryption status of current user.
4709     */
4710    private int updateFlags(int flags, int userId) {
4711        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4712                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4713            // Caller expressed an explicit opinion about what encryption
4714            // aware/unaware components they want to see, so fall through and
4715            // give them what they want
4716        } else {
4717            // Caller expressed no opinion, so match based on user state
4718            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4719                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4720            } else {
4721                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4722            }
4723        }
4724        return flags;
4725    }
4726
4727    private UserManagerInternal getUserManagerInternal() {
4728        if (mUserManagerInternal == null) {
4729            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4730        }
4731        return mUserManagerInternal;
4732    }
4733
4734    private DeviceIdleController.LocalService getDeviceIdleController() {
4735        if (mDeviceIdleController == null) {
4736            mDeviceIdleController =
4737                    LocalServices.getService(DeviceIdleController.LocalService.class);
4738        }
4739        return mDeviceIdleController;
4740    }
4741
4742    /**
4743     * Update given flags when being used to request {@link PackageInfo}.
4744     */
4745    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4746        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4747        boolean triaged = true;
4748        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4749                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4750            // Caller is asking for component details, so they'd better be
4751            // asking for specific encryption matching behavior, or be triaged
4752            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4753                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4754                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4755                triaged = false;
4756            }
4757        }
4758        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4759                | PackageManager.MATCH_SYSTEM_ONLY
4760                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4761            triaged = false;
4762        }
4763        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4764            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4765                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4766                    + Debug.getCallers(5));
4767        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4768                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4769            // If the caller wants all packages and has a restricted profile associated with it,
4770            // then match all users. This is to make sure that launchers that need to access work
4771            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4772            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4773            flags |= PackageManager.MATCH_ANY_USER;
4774        }
4775        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4776            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4777                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4778        }
4779        return updateFlags(flags, userId);
4780    }
4781
4782    /**
4783     * Update given flags when being used to request {@link ApplicationInfo}.
4784     */
4785    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4786        return updateFlagsForPackage(flags, userId, cookie);
4787    }
4788
4789    /**
4790     * Update given flags when being used to request {@link ComponentInfo}.
4791     */
4792    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4793        if (cookie instanceof Intent) {
4794            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4795                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4796            }
4797        }
4798
4799        boolean triaged = true;
4800        // Caller is asking for component details, so they'd better be
4801        // asking for specific encryption matching behavior, or be triaged
4802        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4803                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4804                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4805            triaged = false;
4806        }
4807        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4808            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4809                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4810        }
4811
4812        return updateFlags(flags, userId);
4813    }
4814
4815    /**
4816     * Update given intent when being used to request {@link ResolveInfo}.
4817     */
4818    private Intent updateIntentForResolve(Intent intent) {
4819        if (intent.getSelector() != null) {
4820            intent = intent.getSelector();
4821        }
4822        if (DEBUG_PREFERRED) {
4823            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4824        }
4825        return intent;
4826    }
4827
4828    /**
4829     * Update given flags when being used to request {@link ResolveInfo}.
4830     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4831     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4832     * flag set. However, this flag is only honoured in three circumstances:
4833     * <ul>
4834     * <li>when called from a system process</li>
4835     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4836     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4837     * action and a {@code android.intent.category.BROWSABLE} category</li>
4838     * </ul>
4839     */
4840    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4841        return updateFlagsForResolve(flags, userId, intent, callingUid,
4842                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4843    }
4844    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4845            boolean wantInstantApps) {
4846        return updateFlagsForResolve(flags, userId, intent, callingUid,
4847                wantInstantApps, false /*onlyExposedExplicitly*/);
4848    }
4849    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4850            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4851        // Safe mode means we shouldn't match any third-party components
4852        if (mSafeMode) {
4853            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4854        }
4855        if (getInstantAppPackageName(callingUid) != null) {
4856            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4857            if (onlyExposedExplicitly) {
4858                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4859            }
4860            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4861            flags |= PackageManager.MATCH_INSTANT;
4862        } else {
4863            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4864            final boolean allowMatchInstant =
4865                    (wantInstantApps
4866                            && Intent.ACTION_VIEW.equals(intent.getAction())
4867                            && hasWebURI(intent))
4868                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4869            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4870                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4871            if (!allowMatchInstant) {
4872                flags &= ~PackageManager.MATCH_INSTANT;
4873            }
4874        }
4875        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4876    }
4877
4878    @Override
4879    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4880        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4881    }
4882
4883    /**
4884     * Important: The provided filterCallingUid is used exclusively to filter out activities
4885     * that can be seen based on user state. It's typically the original caller uid prior
4886     * to clearing. Because it can only be provided by trusted code, it's value can be
4887     * trusted and will be used as-is; unlike userId which will be validated by this method.
4888     */
4889    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4890            int filterCallingUid, int userId) {
4891        if (!sUserManager.exists(userId)) return null;
4892        flags = updateFlagsForComponent(flags, userId, component);
4893        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4894                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4895        synchronized (mPackages) {
4896            PackageParser.Activity a = mActivities.mActivities.get(component);
4897
4898            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4899            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4900                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4901                if (ps == null) return null;
4902                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4903                    return null;
4904                }
4905                return PackageParser.generateActivityInfo(
4906                        a, flags, ps.readUserState(userId), userId);
4907            }
4908            if (mResolveComponentName.equals(component)) {
4909                return PackageParser.generateActivityInfo(
4910                        mResolveActivity, flags, new PackageUserState(), userId);
4911            }
4912        }
4913        return null;
4914    }
4915
4916    @Override
4917    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4918            String resolvedType) {
4919        synchronized (mPackages) {
4920            if (component.equals(mResolveComponentName)) {
4921                // The resolver supports EVERYTHING!
4922                return true;
4923            }
4924            final int callingUid = Binder.getCallingUid();
4925            final int callingUserId = UserHandle.getUserId(callingUid);
4926            PackageParser.Activity a = mActivities.mActivities.get(component);
4927            if (a == null) {
4928                return false;
4929            }
4930            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4931            if (ps == null) {
4932                return false;
4933            }
4934            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4935                return false;
4936            }
4937            for (int i=0; i<a.intents.size(); i++) {
4938                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4939                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4940                    return true;
4941                }
4942            }
4943            return false;
4944        }
4945    }
4946
4947    @Override
4948    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4949        if (!sUserManager.exists(userId)) return null;
4950        final int callingUid = Binder.getCallingUid();
4951        flags = updateFlagsForComponent(flags, userId, component);
4952        enforceCrossUserPermission(callingUid, userId,
4953                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4954        synchronized (mPackages) {
4955            PackageParser.Activity a = mReceivers.mActivities.get(component);
4956            if (DEBUG_PACKAGE_INFO) Log.v(
4957                TAG, "getReceiverInfo " + component + ": " + a);
4958            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4959                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4960                if (ps == null) return null;
4961                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4962                    return null;
4963                }
4964                return PackageParser.generateActivityInfo(
4965                        a, flags, ps.readUserState(userId), userId);
4966            }
4967        }
4968        return null;
4969    }
4970
4971    @Override
4972    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4973            int flags, int userId) {
4974        if (!sUserManager.exists(userId)) return null;
4975        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4976        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4977            return null;
4978        }
4979
4980        flags = updateFlagsForPackage(flags, userId, null);
4981
4982        final boolean canSeeStaticLibraries =
4983                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4984                        == PERMISSION_GRANTED
4985                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4986                        == PERMISSION_GRANTED
4987                || canRequestPackageInstallsInternal(packageName,
4988                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4989                        false  /* throwIfPermNotDeclared*/)
4990                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4991                        == PERMISSION_GRANTED;
4992
4993        synchronized (mPackages) {
4994            List<SharedLibraryInfo> result = null;
4995
4996            final int libCount = mSharedLibraries.size();
4997            for (int i = 0; i < libCount; i++) {
4998                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4999                if (versionedLib == null) {
5000                    continue;
5001                }
5002
5003                final int versionCount = versionedLib.size();
5004                for (int j = 0; j < versionCount; j++) {
5005                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5006                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
5007                        break;
5008                    }
5009                    final long identity = Binder.clearCallingIdentity();
5010                    try {
5011                        PackageInfo packageInfo = getPackageInfoVersioned(
5012                                libInfo.getDeclaringPackage(), flags
5013                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5014                        if (packageInfo == null) {
5015                            continue;
5016                        }
5017                    } finally {
5018                        Binder.restoreCallingIdentity(identity);
5019                    }
5020
5021                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5022                            libInfo.getVersion(), libInfo.getType(),
5023                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5024                            flags, userId));
5025
5026                    if (result == null) {
5027                        result = new ArrayList<>();
5028                    }
5029                    result.add(resLibInfo);
5030                }
5031            }
5032
5033            return result != null ? new ParceledListSlice<>(result) : null;
5034        }
5035    }
5036
5037    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5038            SharedLibraryInfo libInfo, int flags, int userId) {
5039        List<VersionedPackage> versionedPackages = null;
5040        final int packageCount = mSettings.mPackages.size();
5041        for (int i = 0; i < packageCount; i++) {
5042            PackageSetting ps = mSettings.mPackages.valueAt(i);
5043
5044            if (ps == null) {
5045                continue;
5046            }
5047
5048            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5049                continue;
5050            }
5051
5052            final String libName = libInfo.getName();
5053            if (libInfo.isStatic()) {
5054                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5055                if (libIdx < 0) {
5056                    continue;
5057                }
5058                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
5059                    continue;
5060                }
5061                if (versionedPackages == null) {
5062                    versionedPackages = new ArrayList<>();
5063                }
5064                // If the dependent is a static shared lib, use the public package name
5065                String dependentPackageName = ps.name;
5066                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5067                    dependentPackageName = ps.pkg.manifestPackageName;
5068                }
5069                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5070            } else if (ps.pkg != null) {
5071                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5072                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5073                    if (versionedPackages == null) {
5074                        versionedPackages = new ArrayList<>();
5075                    }
5076                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5077                }
5078            }
5079        }
5080
5081        return versionedPackages;
5082    }
5083
5084    @Override
5085    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5086        if (!sUserManager.exists(userId)) return null;
5087        final int callingUid = Binder.getCallingUid();
5088        flags = updateFlagsForComponent(flags, userId, component);
5089        enforceCrossUserPermission(callingUid, userId,
5090                false /* requireFullPermission */, false /* checkShell */, "get service info");
5091        synchronized (mPackages) {
5092            PackageParser.Service s = mServices.mServices.get(component);
5093            if (DEBUG_PACKAGE_INFO) Log.v(
5094                TAG, "getServiceInfo " + component + ": " + s);
5095            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5096                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5097                if (ps == null) return null;
5098                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5099                    return null;
5100                }
5101                return PackageParser.generateServiceInfo(
5102                        s, flags, ps.readUserState(userId), userId);
5103            }
5104        }
5105        return null;
5106    }
5107
5108    @Override
5109    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5110        if (!sUserManager.exists(userId)) return null;
5111        final int callingUid = Binder.getCallingUid();
5112        flags = updateFlagsForComponent(flags, userId, component);
5113        enforceCrossUserPermission(callingUid, userId,
5114                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5115        synchronized (mPackages) {
5116            PackageParser.Provider p = mProviders.mProviders.get(component);
5117            if (DEBUG_PACKAGE_INFO) Log.v(
5118                TAG, "getProviderInfo " + component + ": " + p);
5119            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5120                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5121                if (ps == null) return null;
5122                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5123                    return null;
5124                }
5125                return PackageParser.generateProviderInfo(
5126                        p, flags, ps.readUserState(userId), userId);
5127            }
5128        }
5129        return null;
5130    }
5131
5132    @Override
5133    public String[] getSystemSharedLibraryNames() {
5134        // allow instant applications
5135        synchronized (mPackages) {
5136            Set<String> libs = null;
5137            final int libCount = mSharedLibraries.size();
5138            for (int i = 0; i < libCount; i++) {
5139                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5140                if (versionedLib == null) {
5141                    continue;
5142                }
5143                final int versionCount = versionedLib.size();
5144                for (int j = 0; j < versionCount; j++) {
5145                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5146                    if (!libEntry.info.isStatic()) {
5147                        if (libs == null) {
5148                            libs = new ArraySet<>();
5149                        }
5150                        libs.add(libEntry.info.getName());
5151                        break;
5152                    }
5153                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5154                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5155                            UserHandle.getUserId(Binder.getCallingUid()),
5156                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5157                        if (libs == null) {
5158                            libs = new ArraySet<>();
5159                        }
5160                        libs.add(libEntry.info.getName());
5161                        break;
5162                    }
5163                }
5164            }
5165
5166            if (libs != null) {
5167                String[] libsArray = new String[libs.size()];
5168                libs.toArray(libsArray);
5169                return libsArray;
5170            }
5171
5172            return null;
5173        }
5174    }
5175
5176    @Override
5177    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5178        // allow instant applications
5179        synchronized (mPackages) {
5180            return mServicesSystemSharedLibraryPackageName;
5181        }
5182    }
5183
5184    @Override
5185    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5186        // allow instant applications
5187        synchronized (mPackages) {
5188            return mSharedSystemSharedLibraryPackageName;
5189        }
5190    }
5191
5192    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5193        for (int i = userList.length - 1; i >= 0; --i) {
5194            final int userId = userList[i];
5195            // don't add instant app to the list of updates
5196            if (pkgSetting.getInstantApp(userId)) {
5197                continue;
5198            }
5199            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5200            if (changedPackages == null) {
5201                changedPackages = new SparseArray<>();
5202                mChangedPackages.put(userId, changedPackages);
5203            }
5204            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5205            if (sequenceNumbers == null) {
5206                sequenceNumbers = new HashMap<>();
5207                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5208            }
5209            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5210            if (sequenceNumber != null) {
5211                changedPackages.remove(sequenceNumber);
5212            }
5213            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5214            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5215        }
5216        mChangedPackagesSequenceNumber++;
5217    }
5218
5219    @Override
5220    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5221        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5222            return null;
5223        }
5224        synchronized (mPackages) {
5225            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5226                return null;
5227            }
5228            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5229            if (changedPackages == null) {
5230                return null;
5231            }
5232            final List<String> packageNames =
5233                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5234            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5235                final String packageName = changedPackages.get(i);
5236                if (packageName != null) {
5237                    packageNames.add(packageName);
5238                }
5239            }
5240            return packageNames.isEmpty()
5241                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5242        }
5243    }
5244
5245    @Override
5246    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5247        // allow instant applications
5248        ArrayList<FeatureInfo> res;
5249        synchronized (mAvailableFeatures) {
5250            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5251            res.addAll(mAvailableFeatures.values());
5252        }
5253        final FeatureInfo fi = new FeatureInfo();
5254        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5255                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5256        res.add(fi);
5257
5258        return new ParceledListSlice<>(res);
5259    }
5260
5261    @Override
5262    public boolean hasSystemFeature(String name, int version) {
5263        // allow instant applications
5264        synchronized (mAvailableFeatures) {
5265            final FeatureInfo feat = mAvailableFeatures.get(name);
5266            if (feat == null) {
5267                return false;
5268            } else {
5269                return feat.version >= version;
5270            }
5271        }
5272    }
5273
5274    @Override
5275    public int checkPermission(String permName, String pkgName, int userId) {
5276        if (!sUserManager.exists(userId)) {
5277            return PackageManager.PERMISSION_DENIED;
5278        }
5279        final int callingUid = Binder.getCallingUid();
5280
5281        synchronized (mPackages) {
5282            final PackageParser.Package p = mPackages.get(pkgName);
5283            if (p != null && p.mExtras != null) {
5284                final PackageSetting ps = (PackageSetting) p.mExtras;
5285                if (filterAppAccessLPr(ps, callingUid, userId)) {
5286                    return PackageManager.PERMISSION_DENIED;
5287                }
5288                final boolean instantApp = ps.getInstantApp(userId);
5289                final PermissionsState permissionsState = ps.getPermissionsState();
5290                if (permissionsState.hasPermission(permName, userId)) {
5291                    if (instantApp) {
5292                        BasePermission bp = mSettings.mPermissions.get(permName);
5293                        if (bp != null && bp.isInstant()) {
5294                            return PackageManager.PERMISSION_GRANTED;
5295                        }
5296                    } else {
5297                        return PackageManager.PERMISSION_GRANTED;
5298                    }
5299                }
5300                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5301                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5302                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5303                    return PackageManager.PERMISSION_GRANTED;
5304                }
5305            }
5306        }
5307
5308        return PackageManager.PERMISSION_DENIED;
5309    }
5310
5311    @Override
5312    public int checkUidPermission(String permName, int uid) {
5313        final int callingUid = Binder.getCallingUid();
5314        final int callingUserId = UserHandle.getUserId(callingUid);
5315        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5316        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5317        final int userId = UserHandle.getUserId(uid);
5318        if (!sUserManager.exists(userId)) {
5319            return PackageManager.PERMISSION_DENIED;
5320        }
5321
5322        synchronized (mPackages) {
5323            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5324            if (obj != null) {
5325                if (obj instanceof SharedUserSetting) {
5326                    if (isCallerInstantApp) {
5327                        return PackageManager.PERMISSION_DENIED;
5328                    }
5329                } else if (obj instanceof PackageSetting) {
5330                    final PackageSetting ps = (PackageSetting) obj;
5331                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5332                        return PackageManager.PERMISSION_DENIED;
5333                    }
5334                }
5335                final SettingBase settingBase = (SettingBase) obj;
5336                final PermissionsState permissionsState = settingBase.getPermissionsState();
5337                if (permissionsState.hasPermission(permName, userId)) {
5338                    if (isUidInstantApp) {
5339                        BasePermission bp = mSettings.mPermissions.get(permName);
5340                        if (bp != null && bp.isInstant()) {
5341                            return PackageManager.PERMISSION_GRANTED;
5342                        }
5343                    } else {
5344                        return PackageManager.PERMISSION_GRANTED;
5345                    }
5346                }
5347                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5348                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5349                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5350                    return PackageManager.PERMISSION_GRANTED;
5351                }
5352            } else {
5353                ArraySet<String> perms = mSystemPermissions.get(uid);
5354                if (perms != null) {
5355                    if (perms.contains(permName)) {
5356                        return PackageManager.PERMISSION_GRANTED;
5357                    }
5358                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5359                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5360                        return PackageManager.PERMISSION_GRANTED;
5361                    }
5362                }
5363            }
5364        }
5365
5366        return PackageManager.PERMISSION_DENIED;
5367    }
5368
5369    @Override
5370    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5371        if (UserHandle.getCallingUserId() != userId) {
5372            mContext.enforceCallingPermission(
5373                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5374                    "isPermissionRevokedByPolicy for user " + userId);
5375        }
5376
5377        if (checkPermission(permission, packageName, userId)
5378                == PackageManager.PERMISSION_GRANTED) {
5379            return false;
5380        }
5381
5382        final int callingUid = Binder.getCallingUid();
5383        if (getInstantAppPackageName(callingUid) != null) {
5384            if (!isCallerSameApp(packageName, callingUid)) {
5385                return false;
5386            }
5387        } else {
5388            if (isInstantApp(packageName, userId)) {
5389                return false;
5390            }
5391        }
5392
5393        final long identity = Binder.clearCallingIdentity();
5394        try {
5395            final int flags = getPermissionFlags(permission, packageName, userId);
5396            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5397        } finally {
5398            Binder.restoreCallingIdentity(identity);
5399        }
5400    }
5401
5402    @Override
5403    public String getPermissionControllerPackageName() {
5404        synchronized (mPackages) {
5405            return mRequiredInstallerPackage;
5406        }
5407    }
5408
5409    /**
5410     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5411     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5412     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5413     * @param message the message to log on security exception
5414     */
5415    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5416            boolean checkShell, String message) {
5417        if (userId < 0) {
5418            throw new IllegalArgumentException("Invalid userId " + userId);
5419        }
5420        if (checkShell) {
5421            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5422        }
5423        if (userId == UserHandle.getUserId(callingUid)) return;
5424        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5425            if (requireFullPermission) {
5426                mContext.enforceCallingOrSelfPermission(
5427                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5428            } else {
5429                try {
5430                    mContext.enforceCallingOrSelfPermission(
5431                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5432                } catch (SecurityException se) {
5433                    mContext.enforceCallingOrSelfPermission(
5434                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5435                }
5436            }
5437        }
5438    }
5439
5440    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5441        if (callingUid == Process.SHELL_UID) {
5442            if (userHandle >= 0
5443                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5444                throw new SecurityException("Shell does not have permission to access user "
5445                        + userHandle);
5446            } else if (userHandle < 0) {
5447                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5448                        + Debug.getCallers(3));
5449            }
5450        }
5451    }
5452
5453    private BasePermission findPermissionTreeLP(String permName) {
5454        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5455            if (permName.startsWith(bp.name) &&
5456                    permName.length() > bp.name.length() &&
5457                    permName.charAt(bp.name.length()) == '.') {
5458                return bp;
5459            }
5460        }
5461        return null;
5462    }
5463
5464    private BasePermission checkPermissionTreeLP(String permName) {
5465        if (permName != null) {
5466            BasePermission bp = findPermissionTreeLP(permName);
5467            if (bp != null) {
5468                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5469                    return bp;
5470                }
5471                throw new SecurityException("Calling uid "
5472                        + Binder.getCallingUid()
5473                        + " is not allowed to add to permission tree "
5474                        + bp.name + " owned by uid " + bp.uid);
5475            }
5476        }
5477        throw new SecurityException("No permission tree found for " + permName);
5478    }
5479
5480    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5481        if (s1 == null) {
5482            return s2 == null;
5483        }
5484        if (s2 == null) {
5485            return false;
5486        }
5487        if (s1.getClass() != s2.getClass()) {
5488            return false;
5489        }
5490        return s1.equals(s2);
5491    }
5492
5493    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5494        if (pi1.icon != pi2.icon) return false;
5495        if (pi1.logo != pi2.logo) return false;
5496        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5497        if (!compareStrings(pi1.name, pi2.name)) return false;
5498        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5499        // We'll take care of setting this one.
5500        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5501        // These are not currently stored in settings.
5502        //if (!compareStrings(pi1.group, pi2.group)) return false;
5503        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5504        //if (pi1.labelRes != pi2.labelRes) return false;
5505        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5506        return true;
5507    }
5508
5509    int permissionInfoFootprint(PermissionInfo info) {
5510        int size = info.name.length();
5511        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5512        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5513        return size;
5514    }
5515
5516    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5517        int size = 0;
5518        for (BasePermission perm : mSettings.mPermissions.values()) {
5519            if (perm.uid == tree.uid) {
5520                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5521            }
5522        }
5523        return size;
5524    }
5525
5526    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5527        // We calculate the max size of permissions defined by this uid and throw
5528        // if that plus the size of 'info' would exceed our stated maximum.
5529        if (tree.uid != Process.SYSTEM_UID) {
5530            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5531            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5532                throw new SecurityException("Permission tree size cap exceeded");
5533            }
5534        }
5535    }
5536
5537    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5538        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5539            throw new SecurityException("Instant apps can't add permissions");
5540        }
5541        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5542            throw new SecurityException("Label must be specified in permission");
5543        }
5544        BasePermission tree = checkPermissionTreeLP(info.name);
5545        BasePermission bp = mSettings.mPermissions.get(info.name);
5546        boolean added = bp == null;
5547        boolean changed = true;
5548        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5549        if (added) {
5550            enforcePermissionCapLocked(info, tree);
5551            bp = new BasePermission(info.name, tree.sourcePackage,
5552                    BasePermission.TYPE_DYNAMIC);
5553        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5554            throw new SecurityException(
5555                    "Not allowed to modify non-dynamic permission "
5556                    + info.name);
5557        } else {
5558            if (bp.protectionLevel == fixedLevel
5559                    && bp.perm.owner.equals(tree.perm.owner)
5560                    && bp.uid == tree.uid
5561                    && comparePermissionInfos(bp.perm.info, info)) {
5562                changed = false;
5563            }
5564        }
5565        bp.protectionLevel = fixedLevel;
5566        info = new PermissionInfo(info);
5567        info.protectionLevel = fixedLevel;
5568        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5569        bp.perm.info.packageName = tree.perm.info.packageName;
5570        bp.uid = tree.uid;
5571        if (added) {
5572            mSettings.mPermissions.put(info.name, bp);
5573        }
5574        if (changed) {
5575            if (!async) {
5576                mSettings.writeLPr();
5577            } else {
5578                scheduleWriteSettingsLocked();
5579            }
5580        }
5581        return added;
5582    }
5583
5584    @Override
5585    public boolean addPermission(PermissionInfo info) {
5586        synchronized (mPackages) {
5587            return addPermissionLocked(info, false);
5588        }
5589    }
5590
5591    @Override
5592    public boolean addPermissionAsync(PermissionInfo info) {
5593        synchronized (mPackages) {
5594            return addPermissionLocked(info, true);
5595        }
5596    }
5597
5598    @Override
5599    public void removePermission(String name) {
5600        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5601            throw new SecurityException("Instant applications don't have access to this method");
5602        }
5603        synchronized (mPackages) {
5604            checkPermissionTreeLP(name);
5605            BasePermission bp = mSettings.mPermissions.get(name);
5606            if (bp != null) {
5607                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5608                    throw new SecurityException(
5609                            "Not allowed to modify non-dynamic permission "
5610                            + name);
5611                }
5612                mSettings.mPermissions.remove(name);
5613                mSettings.writeLPr();
5614            }
5615        }
5616    }
5617
5618    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5619            PackageParser.Package pkg, BasePermission bp) {
5620        int index = pkg.requestedPermissions.indexOf(bp.name);
5621        if (index == -1) {
5622            throw new SecurityException("Package " + pkg.packageName
5623                    + " has not requested permission " + bp.name);
5624        }
5625        if (!bp.isRuntime() && !bp.isDevelopment()) {
5626            throw new SecurityException("Permission " + bp.name
5627                    + " is not a changeable permission type");
5628        }
5629    }
5630
5631    @Override
5632    public void grantRuntimePermission(String packageName, String name, final int userId) {
5633        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5634    }
5635
5636    private void grantRuntimePermission(String packageName, String name, final int userId,
5637            boolean overridePolicy) {
5638        if (!sUserManager.exists(userId)) {
5639            Log.e(TAG, "No such user:" + userId);
5640            return;
5641        }
5642        final int callingUid = Binder.getCallingUid();
5643
5644        mContext.enforceCallingOrSelfPermission(
5645                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5646                "grantRuntimePermission");
5647
5648        enforceCrossUserPermission(callingUid, userId,
5649                true /* requireFullPermission */, true /* checkShell */,
5650                "grantRuntimePermission");
5651
5652        final int uid;
5653        final PackageSetting ps;
5654
5655        synchronized (mPackages) {
5656            final PackageParser.Package pkg = mPackages.get(packageName);
5657            if (pkg == null) {
5658                throw new IllegalArgumentException("Unknown package: " + packageName);
5659            }
5660            final BasePermission bp = mSettings.mPermissions.get(name);
5661            if (bp == null) {
5662                throw new IllegalArgumentException("Unknown permission: " + name);
5663            }
5664            ps = (PackageSetting) pkg.mExtras;
5665            if (ps == null
5666                    || filterAppAccessLPr(ps, callingUid, userId)) {
5667                throw new IllegalArgumentException("Unknown package: " + packageName);
5668            }
5669
5670            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5671
5672            // If a permission review is required for legacy apps we represent
5673            // their permissions as always granted runtime ones since we need
5674            // to keep the review required permission flag per user while an
5675            // install permission's state is shared across all users.
5676            if (mPermissionReviewRequired
5677                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5678                    && bp.isRuntime()) {
5679                return;
5680            }
5681
5682            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5683
5684            final PermissionsState permissionsState = ps.getPermissionsState();
5685
5686            final int flags = permissionsState.getPermissionFlags(name, userId);
5687            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5688                throw new SecurityException("Cannot grant system fixed permission "
5689                        + name + " for package " + packageName);
5690            }
5691            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5692                throw new SecurityException("Cannot grant policy fixed permission "
5693                        + name + " for package " + packageName);
5694            }
5695
5696            if (bp.isDevelopment()) {
5697                // Development permissions must be handled specially, since they are not
5698                // normal runtime permissions.  For now they apply to all users.
5699                if (permissionsState.grantInstallPermission(bp) !=
5700                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5701                    scheduleWriteSettingsLocked();
5702                }
5703                return;
5704            }
5705
5706            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5707                throw new SecurityException("Cannot grant non-ephemeral permission"
5708                        + name + " for package " + packageName);
5709            }
5710
5711            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5712                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5713                return;
5714            }
5715
5716            final int result = permissionsState.grantRuntimePermission(bp, userId);
5717            switch (result) {
5718                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5719                    return;
5720                }
5721
5722                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5723                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5724                    mHandler.post(new Runnable() {
5725                        @Override
5726                        public void run() {
5727                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5728                        }
5729                    });
5730                }
5731                break;
5732            }
5733
5734            if (bp.isRuntime()) {
5735                logPermissionGranted(mContext, name, packageName);
5736            }
5737
5738            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5739
5740            // Not critical if that is lost - app has to request again.
5741            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5742        }
5743
5744        // Only need to do this if user is initialized. Otherwise it's a new user
5745        // and there are no processes running as the user yet and there's no need
5746        // to make an expensive call to remount processes for the changed permissions.
5747        if (READ_EXTERNAL_STORAGE.equals(name)
5748                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5749            final long token = Binder.clearCallingIdentity();
5750            try {
5751                if (sUserManager.isInitialized(userId)) {
5752                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5753                            StorageManagerInternal.class);
5754                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5755                }
5756            } finally {
5757                Binder.restoreCallingIdentity(token);
5758            }
5759        }
5760    }
5761
5762    @Override
5763    public void revokeRuntimePermission(String packageName, String name, int userId) {
5764        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5765    }
5766
5767    private void revokeRuntimePermission(String packageName, String name, int userId,
5768            boolean overridePolicy) {
5769        if (!sUserManager.exists(userId)) {
5770            Log.e(TAG, "No such user:" + userId);
5771            return;
5772        }
5773
5774        mContext.enforceCallingOrSelfPermission(
5775                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5776                "revokeRuntimePermission");
5777
5778        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5779                true /* requireFullPermission */, true /* checkShell */,
5780                "revokeRuntimePermission");
5781
5782        final int appId;
5783
5784        synchronized (mPackages) {
5785            final PackageParser.Package pkg = mPackages.get(packageName);
5786            if (pkg == null) {
5787                throw new IllegalArgumentException("Unknown package: " + packageName);
5788            }
5789            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5790            if (ps == null
5791                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5792                throw new IllegalArgumentException("Unknown package: " + packageName);
5793            }
5794            final BasePermission bp = mSettings.mPermissions.get(name);
5795            if (bp == null) {
5796                throw new IllegalArgumentException("Unknown permission: " + name);
5797            }
5798
5799            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5800
5801            // If a permission review is required for legacy apps we represent
5802            // their permissions as always granted runtime ones since we need
5803            // to keep the review required permission flag per user while an
5804            // install permission's state is shared across all users.
5805            if (mPermissionReviewRequired
5806                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5807                    && bp.isRuntime()) {
5808                return;
5809            }
5810
5811            final PermissionsState permissionsState = ps.getPermissionsState();
5812
5813            final int flags = permissionsState.getPermissionFlags(name, userId);
5814            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5815                throw new SecurityException("Cannot revoke system fixed permission "
5816                        + name + " for package " + packageName);
5817            }
5818            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5819                throw new SecurityException("Cannot revoke policy fixed permission "
5820                        + name + " for package " + packageName);
5821            }
5822
5823            if (bp.isDevelopment()) {
5824                // Development permissions must be handled specially, since they are not
5825                // normal runtime permissions.  For now they apply to all users.
5826                if (permissionsState.revokeInstallPermission(bp) !=
5827                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5828                    scheduleWriteSettingsLocked();
5829                }
5830                return;
5831            }
5832
5833            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5834                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5835                return;
5836            }
5837
5838            if (bp.isRuntime()) {
5839                logPermissionRevoked(mContext, name, packageName);
5840            }
5841
5842            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5843
5844            // Critical, after this call app should never have the permission.
5845            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5846
5847            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5848        }
5849
5850        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5851    }
5852
5853    /**
5854     * We might auto-grant permissions if any permission of the group is already granted. Hence if
5855     * the group of a granted permission changes we need to revoke it to avoid having permissions of
5856     * the new group auto-granted.
5857     *
5858     * @param newPackage The new package that was installed
5859     * @param oldPackage The old package that was updated
5860     * @param allPackageNames All package names
5861     */
5862    private void revokeRuntimePermissionsIfGroupChanged(
5863            PackageParser.Package newPackage,
5864            PackageParser.Package oldPackage,
5865            ArrayList<String> allPackageNames) {
5866        final int numOldPackagePermissions = oldPackage.permissions.size();
5867        final ArrayMap<String, String> oldPermissionNameToGroupName
5868                = new ArrayMap<>(numOldPackagePermissions);
5869
5870        for (int i = 0; i < numOldPackagePermissions; i++) {
5871            final PackageParser.Permission permission = oldPackage.permissions.get(i);
5872
5873            if (permission.group != null) {
5874                oldPermissionNameToGroupName.put(permission.info.name,
5875                        permission.group.info.name);
5876            }
5877        }
5878
5879        final int numNewPackagePermissions = newPackage.permissions.size();
5880        for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
5881                newPermissionNum++) {
5882            final PackageParser.Permission newPermission =
5883                    newPackage.permissions.get(newPermissionNum);
5884            final int newProtection = newPermission.info.protectionLevel;
5885
5886            if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
5887                final String permissionName = newPermission.info.name;
5888                final String newPermissionGroupName =
5889                        newPermission.group == null ? null : newPermission.group.info.name;
5890                final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
5891                        permissionName);
5892
5893                if (newPermissionGroupName != null
5894                        && !newPermissionGroupName.equals(oldPermissionGroupName)) {
5895                    final List<UserInfo> users = mContext.getSystemService(UserManager.class)
5896                            .getUsers();
5897
5898                    final int numUsers = users.size();
5899                    for (int userNum = 0; userNum < numUsers; userNum++) {
5900                        final int userId = users.get(userNum).id;
5901                        final int numPackages = allPackageNames.size();
5902
5903                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
5904                            final String packageName = allPackageNames.get(packageNum);
5905
5906                            if (checkPermission(permissionName, packageName, userId)
5907                                    == PackageManager.PERMISSION_GRANTED) {
5908                                EventLog.writeEvent(0x534e4554, "72710897",
5909                                        newPackage.applicationInfo.uid,
5910                                        "Revoking permission", permissionName, "from package",
5911                                        packageName, "as the group changed from",
5912                                        oldPermissionGroupName, "to", newPermissionGroupName);
5913
5914                                try {
5915                                    revokeRuntimePermission(packageName, permissionName, userId,
5916                                           false);
5917                                } catch (IllegalArgumentException e) {
5918                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
5919                                            + packageName, e);
5920                                }
5921                            }
5922                        }
5923                    }
5924                }
5925            }
5926        }
5927    }
5928
5929
5930    /**
5931     * Get the first event id for the permission.
5932     *
5933     * <p>There are four events for each permission: <ul>
5934     *     <li>Request permission: first id + 0</li>
5935     *     <li>Grant permission: first id + 1</li>
5936     *     <li>Request for permission denied: first id + 2</li>
5937     *     <li>Revoke permission: first id + 3</li>
5938     * </ul></p>
5939     *
5940     * @param name name of the permission
5941     *
5942     * @return The first event id for the permission
5943     */
5944    private static int getBaseEventId(@NonNull String name) {
5945        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5946
5947        if (eventIdIndex == -1) {
5948            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5949                    || Build.IS_USER) {
5950                Log.i(TAG, "Unknown permission " + name);
5951
5952                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5953            } else {
5954                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5955                //
5956                // Also update
5957                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5958                // - metrics_constants.proto
5959                throw new IllegalStateException("Unknown permission " + name);
5960            }
5961        }
5962
5963        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5964    }
5965
5966    /**
5967     * Log that a permission was revoked.
5968     *
5969     * @param context Context of the caller
5970     * @param name name of the permission
5971     * @param packageName package permission if for
5972     */
5973    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5974            @NonNull String packageName) {
5975        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5976    }
5977
5978    /**
5979     * Log that a permission request was granted.
5980     *
5981     * @param context Context of the caller
5982     * @param name name of the permission
5983     * @param packageName package permission if for
5984     */
5985    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5986            @NonNull String packageName) {
5987        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5988    }
5989
5990    @Override
5991    public void resetRuntimePermissions() {
5992        mContext.enforceCallingOrSelfPermission(
5993                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5994                "revokeRuntimePermission");
5995
5996        int callingUid = Binder.getCallingUid();
5997        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5998            mContext.enforceCallingOrSelfPermission(
5999                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6000                    "resetRuntimePermissions");
6001        }
6002
6003        synchronized (mPackages) {
6004            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
6005            for (int userId : UserManagerService.getInstance().getUserIds()) {
6006                final int packageCount = mPackages.size();
6007                for (int i = 0; i < packageCount; i++) {
6008                    PackageParser.Package pkg = mPackages.valueAt(i);
6009                    if (!(pkg.mExtras instanceof PackageSetting)) {
6010                        continue;
6011                    }
6012                    PackageSetting ps = (PackageSetting) pkg.mExtras;
6013                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
6014                }
6015            }
6016        }
6017    }
6018
6019    @Override
6020    public int getPermissionFlags(String name, String packageName, int userId) {
6021        if (!sUserManager.exists(userId)) {
6022            return 0;
6023        }
6024
6025        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
6026
6027        final int callingUid = Binder.getCallingUid();
6028        enforceCrossUserPermission(callingUid, userId,
6029                true /* requireFullPermission */, false /* checkShell */,
6030                "getPermissionFlags");
6031
6032        synchronized (mPackages) {
6033            final PackageParser.Package pkg = mPackages.get(packageName);
6034            if (pkg == null) {
6035                return 0;
6036            }
6037            final BasePermission bp = mSettings.mPermissions.get(name);
6038            if (bp == null) {
6039                return 0;
6040            }
6041            final PackageSetting ps = (PackageSetting) pkg.mExtras;
6042            if (ps == null
6043                    || filterAppAccessLPr(ps, callingUid, userId)) {
6044                return 0;
6045            }
6046            PermissionsState permissionsState = ps.getPermissionsState();
6047            return permissionsState.getPermissionFlags(name, userId);
6048        }
6049    }
6050
6051    @Override
6052    public void updatePermissionFlags(String name, String packageName, int flagMask,
6053            int flagValues, int userId) {
6054        if (!sUserManager.exists(userId)) {
6055            return;
6056        }
6057
6058        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
6059
6060        final int callingUid = Binder.getCallingUid();
6061        enforceCrossUserPermission(callingUid, userId,
6062                true /* requireFullPermission */, true /* checkShell */,
6063                "updatePermissionFlags");
6064
6065        // Only the system can change these flags and nothing else.
6066        if (getCallingUid() != Process.SYSTEM_UID) {
6067            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6068            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6069            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6070            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
6071            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
6072        }
6073
6074        synchronized (mPackages) {
6075            final PackageParser.Package pkg = mPackages.get(packageName);
6076            if (pkg == null) {
6077                throw new IllegalArgumentException("Unknown package: " + packageName);
6078            }
6079            final PackageSetting ps = (PackageSetting) pkg.mExtras;
6080            if (ps == null
6081                    || filterAppAccessLPr(ps, callingUid, userId)) {
6082                throw new IllegalArgumentException("Unknown package: " + packageName);
6083            }
6084
6085            final BasePermission bp = mSettings.mPermissions.get(name);
6086            if (bp == null) {
6087                throw new IllegalArgumentException("Unknown permission: " + name);
6088            }
6089
6090            PermissionsState permissionsState = ps.getPermissionsState();
6091
6092            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
6093
6094            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
6095                // Install and runtime permissions are stored in different places,
6096                // so figure out what permission changed and persist the change.
6097                if (permissionsState.getInstallPermissionState(name) != null) {
6098                    scheduleWriteSettingsLocked();
6099                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
6100                        || hadState) {
6101                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6102                }
6103            }
6104        }
6105    }
6106
6107    /**
6108     * Update the permission flags for all packages and runtime permissions of a user in order
6109     * to allow device or profile owner to remove POLICY_FIXED.
6110     */
6111    @Override
6112    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
6113        if (!sUserManager.exists(userId)) {
6114            return;
6115        }
6116
6117        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
6118
6119        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6120                true /* requireFullPermission */, true /* checkShell */,
6121                "updatePermissionFlagsForAllApps");
6122
6123        // Only the system can change system fixed flags.
6124        if (getCallingUid() != Process.SYSTEM_UID) {
6125            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6126            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6127        }
6128
6129        synchronized (mPackages) {
6130            boolean changed = false;
6131            final int packageCount = mPackages.size();
6132            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
6133                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
6134                final PackageSetting ps = (PackageSetting) pkg.mExtras;
6135                if (ps == null) {
6136                    continue;
6137                }
6138                PermissionsState permissionsState = ps.getPermissionsState();
6139                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
6140                        userId, flagMask, flagValues);
6141            }
6142            if (changed) {
6143                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6144            }
6145        }
6146    }
6147
6148    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6149        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6150                != PackageManager.PERMISSION_GRANTED
6151            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6152                != PackageManager.PERMISSION_GRANTED) {
6153            throw new SecurityException(message + " requires "
6154                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6155                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6156        }
6157    }
6158
6159    @Override
6160    public boolean shouldShowRequestPermissionRationale(String permissionName,
6161            String packageName, int userId) {
6162        if (UserHandle.getCallingUserId() != userId) {
6163            mContext.enforceCallingPermission(
6164                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6165                    "canShowRequestPermissionRationale for user " + userId);
6166        }
6167
6168        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6169        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6170            return false;
6171        }
6172
6173        if (checkPermission(permissionName, packageName, userId)
6174                == PackageManager.PERMISSION_GRANTED) {
6175            return false;
6176        }
6177
6178        final int flags;
6179
6180        final long identity = Binder.clearCallingIdentity();
6181        try {
6182            flags = getPermissionFlags(permissionName,
6183                    packageName, userId);
6184        } finally {
6185            Binder.restoreCallingIdentity(identity);
6186        }
6187
6188        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6189                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6190                | PackageManager.FLAG_PERMISSION_USER_FIXED;
6191
6192        if ((flags & fixedFlags) != 0) {
6193            return false;
6194        }
6195
6196        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6197    }
6198
6199    @Override
6200    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6201        mContext.enforceCallingOrSelfPermission(
6202                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6203                "addOnPermissionsChangeListener");
6204
6205        synchronized (mPackages) {
6206            mOnPermissionChangeListeners.addListenerLocked(listener);
6207        }
6208    }
6209
6210    @Override
6211    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6212        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6213            throw new SecurityException("Instant applications don't have access to this method");
6214        }
6215        synchronized (mPackages) {
6216            mOnPermissionChangeListeners.removeListenerLocked(listener);
6217        }
6218    }
6219
6220    @Override
6221    public boolean isProtectedBroadcast(String actionName) {
6222        // allow instant applications
6223        synchronized (mProtectedBroadcasts) {
6224            if (mProtectedBroadcasts.contains(actionName)) {
6225                return true;
6226            } else if (actionName != null) {
6227                // TODO: remove these terrible hacks
6228                if (actionName.startsWith("android.net.netmon.lingerExpired")
6229                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6230                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6231                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6232                    return true;
6233                }
6234            }
6235        }
6236        return false;
6237    }
6238
6239    @Override
6240    public int checkSignatures(String pkg1, String pkg2) {
6241        synchronized (mPackages) {
6242            final PackageParser.Package p1 = mPackages.get(pkg1);
6243            final PackageParser.Package p2 = mPackages.get(pkg2);
6244            if (p1 == null || p1.mExtras == null
6245                    || p2 == null || p2.mExtras == null) {
6246                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6247            }
6248            final int callingUid = Binder.getCallingUid();
6249            final int callingUserId = UserHandle.getUserId(callingUid);
6250            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6251            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6252            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6253                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6254                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6255            }
6256            return compareSignatures(p1.mSignatures, p2.mSignatures);
6257        }
6258    }
6259
6260    @Override
6261    public int checkUidSignatures(int uid1, int uid2) {
6262        final int callingUid = Binder.getCallingUid();
6263        final int callingUserId = UserHandle.getUserId(callingUid);
6264        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6265        // Map to base uids.
6266        uid1 = UserHandle.getAppId(uid1);
6267        uid2 = UserHandle.getAppId(uid2);
6268        // reader
6269        synchronized (mPackages) {
6270            Signature[] s1;
6271            Signature[] s2;
6272            Object obj = mSettings.getUserIdLPr(uid1);
6273            if (obj != null) {
6274                if (obj instanceof SharedUserSetting) {
6275                    if (isCallerInstantApp) {
6276                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6277                    }
6278                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6279                } else if (obj instanceof PackageSetting) {
6280                    final PackageSetting ps = (PackageSetting) obj;
6281                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6282                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6283                    }
6284                    s1 = ps.signatures.mSignatures;
6285                } else {
6286                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6287                }
6288            } else {
6289                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6290            }
6291            obj = mSettings.getUserIdLPr(uid2);
6292            if (obj != null) {
6293                if (obj instanceof SharedUserSetting) {
6294                    if (isCallerInstantApp) {
6295                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6296                    }
6297                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6298                } else if (obj instanceof PackageSetting) {
6299                    final PackageSetting ps = (PackageSetting) obj;
6300                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6301                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6302                    }
6303                    s2 = ps.signatures.mSignatures;
6304                } else {
6305                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6306                }
6307            } else {
6308                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6309            }
6310            return compareSignatures(s1, s2);
6311        }
6312    }
6313
6314    /**
6315     * This method should typically only be used when granting or revoking
6316     * permissions, since the app may immediately restart after this call.
6317     * <p>
6318     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6319     * guard your work against the app being relaunched.
6320     */
6321    private void killUid(int appId, int userId, String reason) {
6322        final long identity = Binder.clearCallingIdentity();
6323        try {
6324            IActivityManager am = ActivityManager.getService();
6325            if (am != null) {
6326                try {
6327                    am.killUid(appId, userId, reason);
6328                } catch (RemoteException e) {
6329                    /* ignore - same process */
6330                }
6331            }
6332        } finally {
6333            Binder.restoreCallingIdentity(identity);
6334        }
6335    }
6336
6337    /**
6338     * Compares two sets of signatures. Returns:
6339     * <br />
6340     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6341     * <br />
6342     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6343     * <br />
6344     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6345     * <br />
6346     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6347     * <br />
6348     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6349     */
6350    static int compareSignatures(Signature[] s1, Signature[] s2) {
6351        if (s1 == null) {
6352            return s2 == null
6353                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
6354                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6355        }
6356
6357        if (s2 == null) {
6358            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6359        }
6360
6361        if (s1.length != s2.length) {
6362            return PackageManager.SIGNATURE_NO_MATCH;
6363        }
6364
6365        // Since both signature sets are of size 1, we can compare without HashSets.
6366        if (s1.length == 1) {
6367            return s1[0].equals(s2[0]) ?
6368                    PackageManager.SIGNATURE_MATCH :
6369                    PackageManager.SIGNATURE_NO_MATCH;
6370        }
6371
6372        ArraySet<Signature> set1 = new ArraySet<Signature>();
6373        for (Signature sig : s1) {
6374            set1.add(sig);
6375        }
6376        ArraySet<Signature> set2 = new ArraySet<Signature>();
6377        for (Signature sig : s2) {
6378            set2.add(sig);
6379        }
6380        // Make sure s2 contains all signatures in s1.
6381        if (set1.equals(set2)) {
6382            return PackageManager.SIGNATURE_MATCH;
6383        }
6384        return PackageManager.SIGNATURE_NO_MATCH;
6385    }
6386
6387    /**
6388     * If the database version for this type of package (internal storage or
6389     * external storage) is less than the version where package signatures
6390     * were updated, return true.
6391     */
6392    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6393        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6394        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6395    }
6396
6397    /**
6398     * Used for backward compatibility to make sure any packages with
6399     * certificate chains get upgraded to the new style. {@code existingSigs}
6400     * will be in the old format (since they were stored on disk from before the
6401     * system upgrade) and {@code scannedSigs} will be in the newer format.
6402     */
6403    private int compareSignaturesCompat(PackageSignatures existingSigs,
6404            PackageParser.Package scannedPkg) {
6405        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6406            return PackageManager.SIGNATURE_NO_MATCH;
6407        }
6408
6409        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6410        for (Signature sig : existingSigs.mSignatures) {
6411            existingSet.add(sig);
6412        }
6413        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6414        for (Signature sig : scannedPkg.mSignatures) {
6415            try {
6416                Signature[] chainSignatures = sig.getChainSignatures();
6417                for (Signature chainSig : chainSignatures) {
6418                    scannedCompatSet.add(chainSig);
6419                }
6420            } catch (CertificateEncodingException e) {
6421                scannedCompatSet.add(sig);
6422            }
6423        }
6424        /*
6425         * Make sure the expanded scanned set contains all signatures in the
6426         * existing one.
6427         */
6428        if (scannedCompatSet.equals(existingSet)) {
6429            // Migrate the old signatures to the new scheme.
6430            existingSigs.assignSignatures(scannedPkg.mSignatures);
6431            // The new KeySets will be re-added later in the scanning process.
6432            synchronized (mPackages) {
6433                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6434            }
6435            return PackageManager.SIGNATURE_MATCH;
6436        }
6437        return PackageManager.SIGNATURE_NO_MATCH;
6438    }
6439
6440    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6441        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6442        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6443    }
6444
6445    private int compareSignaturesRecover(PackageSignatures existingSigs,
6446            PackageParser.Package scannedPkg) {
6447        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6448            return PackageManager.SIGNATURE_NO_MATCH;
6449        }
6450
6451        String msg = null;
6452        try {
6453            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6454                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6455                        + scannedPkg.packageName);
6456                return PackageManager.SIGNATURE_MATCH;
6457            }
6458        } catch (CertificateException e) {
6459            msg = e.getMessage();
6460        }
6461
6462        logCriticalInfo(Log.INFO,
6463                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6464        return PackageManager.SIGNATURE_NO_MATCH;
6465    }
6466
6467    @Override
6468    public List<String> getAllPackages() {
6469        final int callingUid = Binder.getCallingUid();
6470        final int callingUserId = UserHandle.getUserId(callingUid);
6471        synchronized (mPackages) {
6472            if (canViewInstantApps(callingUid, callingUserId)) {
6473                return new ArrayList<String>(mPackages.keySet());
6474            }
6475            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6476            final List<String> result = new ArrayList<>();
6477            if (instantAppPkgName != null) {
6478                // caller is an instant application; filter unexposed applications
6479                for (PackageParser.Package pkg : mPackages.values()) {
6480                    if (!pkg.visibleToInstantApps) {
6481                        continue;
6482                    }
6483                    result.add(pkg.packageName);
6484                }
6485            } else {
6486                // caller is a normal application; filter instant applications
6487                for (PackageParser.Package pkg : mPackages.values()) {
6488                    final PackageSetting ps =
6489                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6490                    if (ps != null
6491                            && ps.getInstantApp(callingUserId)
6492                            && !mInstantAppRegistry.isInstantAccessGranted(
6493                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6494                        continue;
6495                    }
6496                    result.add(pkg.packageName);
6497                }
6498            }
6499            return result;
6500        }
6501    }
6502
6503    @Override
6504    public String[] getPackagesForUid(int uid) {
6505        final int callingUid = Binder.getCallingUid();
6506        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6507        final int userId = UserHandle.getUserId(uid);
6508        uid = UserHandle.getAppId(uid);
6509        // reader
6510        synchronized (mPackages) {
6511            Object obj = mSettings.getUserIdLPr(uid);
6512            if (obj instanceof SharedUserSetting) {
6513                if (isCallerInstantApp) {
6514                    return null;
6515                }
6516                final SharedUserSetting sus = (SharedUserSetting) obj;
6517                final int N = sus.packages.size();
6518                String[] res = new String[N];
6519                final Iterator<PackageSetting> it = sus.packages.iterator();
6520                int i = 0;
6521                while (it.hasNext()) {
6522                    PackageSetting ps = it.next();
6523                    if (ps.getInstalled(userId)) {
6524                        res[i++] = ps.name;
6525                    } else {
6526                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6527                    }
6528                }
6529                return res;
6530            } else if (obj instanceof PackageSetting) {
6531                final PackageSetting ps = (PackageSetting) obj;
6532                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6533                    return new String[]{ps.name};
6534                }
6535            }
6536        }
6537        return null;
6538    }
6539
6540    @Override
6541    public String getNameForUid(int uid) {
6542        final int callingUid = Binder.getCallingUid();
6543        if (getInstantAppPackageName(callingUid) != null) {
6544            return null;
6545        }
6546        synchronized (mPackages) {
6547            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6548            if (obj instanceof SharedUserSetting) {
6549                final SharedUserSetting sus = (SharedUserSetting) obj;
6550                return sus.name + ":" + sus.userId;
6551            } else if (obj instanceof PackageSetting) {
6552                final PackageSetting ps = (PackageSetting) obj;
6553                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6554                    return null;
6555                }
6556                return ps.name;
6557            }
6558            return null;
6559        }
6560    }
6561
6562    @Override
6563    public String[] getNamesForUids(int[] uids) {
6564        if (uids == null || uids.length == 0) {
6565            return null;
6566        }
6567        final int callingUid = Binder.getCallingUid();
6568        if (getInstantAppPackageName(callingUid) != null) {
6569            return null;
6570        }
6571        final String[] names = new String[uids.length];
6572        synchronized (mPackages) {
6573            for (int i = uids.length - 1; i >= 0; i--) {
6574                final int uid = uids[i];
6575                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6576                if (obj instanceof SharedUserSetting) {
6577                    final SharedUserSetting sus = (SharedUserSetting) obj;
6578                    names[i] = "shared:" + sus.name;
6579                } else if (obj instanceof PackageSetting) {
6580                    final PackageSetting ps = (PackageSetting) obj;
6581                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6582                        names[i] = null;
6583                    } else {
6584                        names[i] = ps.name;
6585                    }
6586                } else {
6587                    names[i] = null;
6588                }
6589            }
6590        }
6591        return names;
6592    }
6593
6594    @Override
6595    public int getUidForSharedUser(String sharedUserName) {
6596        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6597            return -1;
6598        }
6599        if (sharedUserName == null) {
6600            return -1;
6601        }
6602        // reader
6603        synchronized (mPackages) {
6604            SharedUserSetting suid;
6605            try {
6606                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6607                if (suid != null) {
6608                    return suid.userId;
6609                }
6610            } catch (PackageManagerException ignore) {
6611                // can't happen, but, still need to catch it
6612            }
6613            return -1;
6614        }
6615    }
6616
6617    @Override
6618    public int getFlagsForUid(int uid) {
6619        final int callingUid = Binder.getCallingUid();
6620        if (getInstantAppPackageName(callingUid) != null) {
6621            return 0;
6622        }
6623        synchronized (mPackages) {
6624            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6625            if (obj instanceof SharedUserSetting) {
6626                final SharedUserSetting sus = (SharedUserSetting) obj;
6627                return sus.pkgFlags;
6628            } else if (obj instanceof PackageSetting) {
6629                final PackageSetting ps = (PackageSetting) obj;
6630                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6631                    return 0;
6632                }
6633                return ps.pkgFlags;
6634            }
6635        }
6636        return 0;
6637    }
6638
6639    @Override
6640    public int getPrivateFlagsForUid(int uid) {
6641        final int callingUid = Binder.getCallingUid();
6642        if (getInstantAppPackageName(callingUid) != null) {
6643            return 0;
6644        }
6645        synchronized (mPackages) {
6646            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6647            if (obj instanceof SharedUserSetting) {
6648                final SharedUserSetting sus = (SharedUserSetting) obj;
6649                return sus.pkgPrivateFlags;
6650            } else if (obj instanceof PackageSetting) {
6651                final PackageSetting ps = (PackageSetting) obj;
6652                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6653                    return 0;
6654                }
6655                return ps.pkgPrivateFlags;
6656            }
6657        }
6658        return 0;
6659    }
6660
6661    @Override
6662    public boolean isUidPrivileged(int uid) {
6663        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6664            return false;
6665        }
6666        uid = UserHandle.getAppId(uid);
6667        // reader
6668        synchronized (mPackages) {
6669            Object obj = mSettings.getUserIdLPr(uid);
6670            if (obj instanceof SharedUserSetting) {
6671                final SharedUserSetting sus = (SharedUserSetting) obj;
6672                final Iterator<PackageSetting> it = sus.packages.iterator();
6673                while (it.hasNext()) {
6674                    if (it.next().isPrivileged()) {
6675                        return true;
6676                    }
6677                }
6678            } else if (obj instanceof PackageSetting) {
6679                final PackageSetting ps = (PackageSetting) obj;
6680                return ps.isPrivileged();
6681            }
6682        }
6683        return false;
6684    }
6685
6686    @Override
6687    public String[] getAppOpPermissionPackages(String permissionName) {
6688        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6689            return null;
6690        }
6691        synchronized (mPackages) {
6692            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6693            if (pkgs == null) {
6694                return null;
6695            }
6696            return pkgs.toArray(new String[pkgs.size()]);
6697        }
6698    }
6699
6700    @Override
6701    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6702            int flags, int userId) {
6703        return resolveIntentInternal(
6704                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6705    }
6706
6707    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6708            int flags, int userId, boolean resolveForStart) {
6709        try {
6710            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6711
6712            if (!sUserManager.exists(userId)) return null;
6713            final int callingUid = Binder.getCallingUid();
6714            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6715            enforceCrossUserPermission(callingUid, userId,
6716                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6717
6718            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6719            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6720                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6721            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6722
6723            final ResolveInfo bestChoice =
6724                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6725            return bestChoice;
6726        } finally {
6727            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6728        }
6729    }
6730
6731    @Override
6732    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6733        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6734            throw new SecurityException(
6735                    "findPersistentPreferredActivity can only be run by the system");
6736        }
6737        if (!sUserManager.exists(userId)) {
6738            return null;
6739        }
6740        final int callingUid = Binder.getCallingUid();
6741        intent = updateIntentForResolve(intent);
6742        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6743        final int flags = updateFlagsForResolve(
6744                0, userId, intent, callingUid, false /*includeInstantApps*/);
6745        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6746                userId);
6747        synchronized (mPackages) {
6748            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6749                    userId);
6750        }
6751    }
6752
6753    @Override
6754    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6755            IntentFilter filter, int match, ComponentName activity) {
6756        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6757            return;
6758        }
6759        final int userId = UserHandle.getCallingUserId();
6760        if (DEBUG_PREFERRED) {
6761            Log.v(TAG, "setLastChosenActivity intent=" + intent
6762                + " resolvedType=" + resolvedType
6763                + " flags=" + flags
6764                + " filter=" + filter
6765                + " match=" + match
6766                + " activity=" + activity);
6767            filter.dump(new PrintStreamPrinter(System.out), "    ");
6768        }
6769        intent.setComponent(null);
6770        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6771                userId);
6772        // Find any earlier preferred or last chosen entries and nuke them
6773        findPreferredActivity(intent, resolvedType,
6774                flags, query, 0, false, true, false, userId);
6775        // Add the new activity as the last chosen for this filter
6776        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6777                "Setting last chosen");
6778    }
6779
6780    @Override
6781    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6782        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6783            return null;
6784        }
6785        final int userId = UserHandle.getCallingUserId();
6786        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6787        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6788                userId);
6789        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6790                false, false, false, userId);
6791    }
6792
6793    /**
6794     * Returns whether or not instant apps have been disabled remotely.
6795     */
6796    private boolean isEphemeralDisabled() {
6797        return mEphemeralAppsDisabled;
6798    }
6799
6800    private boolean isInstantAppAllowed(
6801            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6802            boolean skipPackageCheck) {
6803        if (mInstantAppResolverConnection == null) {
6804            return false;
6805        }
6806        if (mInstantAppInstallerActivity == null) {
6807            return false;
6808        }
6809        if (intent.getComponent() != null) {
6810            return false;
6811        }
6812        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6813            return false;
6814        }
6815        if (!skipPackageCheck && intent.getPackage() != null) {
6816            return false;
6817        }
6818        final boolean isWebUri = hasWebURI(intent);
6819        if (!isWebUri || intent.getData().getHost() == null) {
6820            return false;
6821        }
6822        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6823        // Or if there's already an ephemeral app installed that handles the action
6824        synchronized (mPackages) {
6825            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6826            for (int n = 0; n < count; n++) {
6827                final ResolveInfo info = resolvedActivities.get(n);
6828                final String packageName = info.activityInfo.packageName;
6829                final PackageSetting ps = mSettings.mPackages.get(packageName);
6830                if (ps != null) {
6831                    // only check domain verification status if the app is not a browser
6832                    if (!info.handleAllWebDataURI) {
6833                        // Try to get the status from User settings first
6834                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6835                        final int status = (int) (packedStatus >> 32);
6836                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6837                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6838                            if (DEBUG_EPHEMERAL) {
6839                                Slog.v(TAG, "DENY instant app;"
6840                                    + " pkg: " + packageName + ", status: " + status);
6841                            }
6842                            return false;
6843                        }
6844                    }
6845                    if (ps.getInstantApp(userId)) {
6846                        if (DEBUG_EPHEMERAL) {
6847                            Slog.v(TAG, "DENY instant app installed;"
6848                                    + " pkg: " + packageName);
6849                        }
6850                        return false;
6851                    }
6852                }
6853            }
6854        }
6855        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6856        return true;
6857    }
6858
6859    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6860            Intent origIntent, String resolvedType, String callingPackage,
6861            Bundle verificationBundle, int userId) {
6862        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6863                new InstantAppRequest(responseObj, origIntent, resolvedType,
6864                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6865        mHandler.sendMessage(msg);
6866    }
6867
6868    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6869            int flags, List<ResolveInfo> query, int userId) {
6870        if (query != null) {
6871            final int N = query.size();
6872            if (N == 1) {
6873                return query.get(0);
6874            } else if (N > 1) {
6875                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6876                // If there is more than one activity with the same priority,
6877                // then let the user decide between them.
6878                ResolveInfo r0 = query.get(0);
6879                ResolveInfo r1 = query.get(1);
6880                if (DEBUG_INTENT_MATCHING || debug) {
6881                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6882                            + r1.activityInfo.name + "=" + r1.priority);
6883                }
6884                // If the first activity has a higher priority, or a different
6885                // default, then it is always desirable to pick it.
6886                if (r0.priority != r1.priority
6887                        || r0.preferredOrder != r1.preferredOrder
6888                        || r0.isDefault != r1.isDefault) {
6889                    return query.get(0);
6890                }
6891                // If we have saved a preference for a preferred activity for
6892                // this Intent, use that.
6893                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6894                        flags, query, r0.priority, true, false, debug, userId);
6895                if (ri != null) {
6896                    return ri;
6897                }
6898                // If we have an ephemeral app, use it
6899                for (int i = 0; i < N; i++) {
6900                    ri = query.get(i);
6901                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6902                        final String packageName = ri.activityInfo.packageName;
6903                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6904                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6905                        final int status = (int)(packedStatus >> 32);
6906                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6907                            return ri;
6908                        }
6909                    }
6910                }
6911                ri = new ResolveInfo(mResolveInfo);
6912                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6913                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6914                // If all of the options come from the same package, show the application's
6915                // label and icon instead of the generic resolver's.
6916                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6917                // and then throw away the ResolveInfo itself, meaning that the caller loses
6918                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6919                // a fallback for this case; we only set the target package's resources on
6920                // the ResolveInfo, not the ActivityInfo.
6921                final String intentPackage = intent.getPackage();
6922                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6923                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6924                    ri.resolvePackageName = intentPackage;
6925                    if (userNeedsBadging(userId)) {
6926                        ri.noResourceId = true;
6927                    } else {
6928                        ri.icon = appi.icon;
6929                    }
6930                    ri.iconResourceId = appi.icon;
6931                    ri.labelRes = appi.labelRes;
6932                }
6933                ri.activityInfo.applicationInfo = new ApplicationInfo(
6934                        ri.activityInfo.applicationInfo);
6935                if (userId != 0) {
6936                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6937                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6938                }
6939                // Make sure that the resolver is displayable in car mode
6940                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6941                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6942                return ri;
6943            }
6944        }
6945        return null;
6946    }
6947
6948    /**
6949     * Return true if the given list is not empty and all of its contents have
6950     * an activityInfo with the given package name.
6951     */
6952    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6953        if (ArrayUtils.isEmpty(list)) {
6954            return false;
6955        }
6956        for (int i = 0, N = list.size(); i < N; i++) {
6957            final ResolveInfo ri = list.get(i);
6958            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6959            if (ai == null || !packageName.equals(ai.packageName)) {
6960                return false;
6961            }
6962        }
6963        return true;
6964    }
6965
6966    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6967            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6968        final int N = query.size();
6969        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6970                .get(userId);
6971        // Get the list of persistent preferred activities that handle the intent
6972        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6973        List<PersistentPreferredActivity> pprefs = ppir != null
6974                ? ppir.queryIntent(intent, resolvedType,
6975                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6976                        userId)
6977                : null;
6978        if (pprefs != null && pprefs.size() > 0) {
6979            final int M = pprefs.size();
6980            for (int i=0; i<M; i++) {
6981                final PersistentPreferredActivity ppa = pprefs.get(i);
6982                if (DEBUG_PREFERRED || debug) {
6983                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6984                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6985                            + "\n  component=" + ppa.mComponent);
6986                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6987                }
6988                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6989                        flags | MATCH_DISABLED_COMPONENTS, userId);
6990                if (DEBUG_PREFERRED || debug) {
6991                    Slog.v(TAG, "Found persistent preferred activity:");
6992                    if (ai != null) {
6993                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6994                    } else {
6995                        Slog.v(TAG, "  null");
6996                    }
6997                }
6998                if (ai == null) {
6999                    // This previously registered persistent preferred activity
7000                    // component is no longer known. Ignore it and do NOT remove it.
7001                    continue;
7002                }
7003                for (int j=0; j<N; j++) {
7004                    final ResolveInfo ri = query.get(j);
7005                    if (!ri.activityInfo.applicationInfo.packageName
7006                            .equals(ai.applicationInfo.packageName)) {
7007                        continue;
7008                    }
7009                    if (!ri.activityInfo.name.equals(ai.name)) {
7010                        continue;
7011                    }
7012                    //  Found a persistent preference that can handle the intent.
7013                    if (DEBUG_PREFERRED || debug) {
7014                        Slog.v(TAG, "Returning persistent preferred activity: " +
7015                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7016                    }
7017                    return ri;
7018                }
7019            }
7020        }
7021        return null;
7022    }
7023
7024    // TODO: handle preferred activities missing while user has amnesia
7025    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
7026            List<ResolveInfo> query, int priority, boolean always,
7027            boolean removeMatches, boolean debug, int userId) {
7028        if (!sUserManager.exists(userId)) return null;
7029        final int callingUid = Binder.getCallingUid();
7030        flags = updateFlagsForResolve(
7031                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7032        intent = updateIntentForResolve(intent);
7033        // writer
7034        synchronized (mPackages) {
7035            // Try to find a matching persistent preferred activity.
7036            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
7037                    debug, userId);
7038
7039            // If a persistent preferred activity matched, use it.
7040            if (pri != null) {
7041                return pri;
7042            }
7043
7044            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
7045            // Get the list of preferred activities that handle the intent
7046            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
7047            List<PreferredActivity> prefs = pir != null
7048                    ? pir.queryIntent(intent, resolvedType,
7049                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
7050                            userId)
7051                    : null;
7052            if (prefs != null && prefs.size() > 0) {
7053                boolean changed = false;
7054                try {
7055                    // First figure out how good the original match set is.
7056                    // We will only allow preferred activities that came
7057                    // from the same match quality.
7058                    int match = 0;
7059
7060                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
7061
7062                    final int N = query.size();
7063                    for (int j=0; j<N; j++) {
7064                        final ResolveInfo ri = query.get(j);
7065                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
7066                                + ": 0x" + Integer.toHexString(match));
7067                        if (ri.match > match) {
7068                            match = ri.match;
7069                        }
7070                    }
7071
7072                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
7073                            + Integer.toHexString(match));
7074
7075                    match &= IntentFilter.MATCH_CATEGORY_MASK;
7076                    final int M = prefs.size();
7077                    for (int i=0; i<M; i++) {
7078                        final PreferredActivity pa = prefs.get(i);
7079                        if (DEBUG_PREFERRED || debug) {
7080                            Slog.v(TAG, "Checking PreferredActivity ds="
7081                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
7082                                    + "\n  component=" + pa.mPref.mComponent);
7083                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7084                        }
7085                        if (pa.mPref.mMatch != match) {
7086                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
7087                                    + Integer.toHexString(pa.mPref.mMatch));
7088                            continue;
7089                        }
7090                        // If it's not an "always" type preferred activity and that's what we're
7091                        // looking for, skip it.
7092                        if (always && !pa.mPref.mAlways) {
7093                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
7094                            continue;
7095                        }
7096                        final ActivityInfo ai = getActivityInfo(
7097                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
7098                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
7099                                userId);
7100                        if (DEBUG_PREFERRED || debug) {
7101                            Slog.v(TAG, "Found preferred activity:");
7102                            if (ai != null) {
7103                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7104                            } else {
7105                                Slog.v(TAG, "  null");
7106                            }
7107                        }
7108                        if (ai == null) {
7109                            // This previously registered preferred activity
7110                            // component is no longer known.  Most likely an update
7111                            // to the app was installed and in the new version this
7112                            // component no longer exists.  Clean it up by removing
7113                            // it from the preferred activities list, and skip it.
7114                            Slog.w(TAG, "Removing dangling preferred activity: "
7115                                    + pa.mPref.mComponent);
7116                            pir.removeFilter(pa);
7117                            changed = true;
7118                            continue;
7119                        }
7120                        for (int j=0; j<N; j++) {
7121                            final ResolveInfo ri = query.get(j);
7122                            if (!ri.activityInfo.applicationInfo.packageName
7123                                    .equals(ai.applicationInfo.packageName)) {
7124                                continue;
7125                            }
7126                            if (!ri.activityInfo.name.equals(ai.name)) {
7127                                continue;
7128                            }
7129
7130                            if (removeMatches) {
7131                                pir.removeFilter(pa);
7132                                changed = true;
7133                                if (DEBUG_PREFERRED) {
7134                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
7135                                }
7136                                break;
7137                            }
7138
7139                            // Okay we found a previously set preferred or last chosen app.
7140                            // If the result set is different from when this
7141                            // was created, and is not a subset of the preferred set, we need to
7142                            // clear it and re-ask the user their preference, if we're looking for
7143                            // an "always" type entry.
7144                            if (always && !pa.mPref.sameSet(query)) {
7145                                if (pa.mPref.isSuperset(query)) {
7146                                    // some components of the set are no longer present in
7147                                    // the query, but the preferred activity can still be reused
7148                                    if (DEBUG_PREFERRED) {
7149                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
7150                                                + " still valid as only non-preferred components"
7151                                                + " were removed for " + intent + " type "
7152                                                + resolvedType);
7153                                    }
7154                                    // remove obsolete components and re-add the up-to-date filter
7155                                    PreferredActivity freshPa = new PreferredActivity(pa,
7156                                            pa.mPref.mMatch,
7157                                            pa.mPref.discardObsoleteComponents(query),
7158                                            pa.mPref.mComponent,
7159                                            pa.mPref.mAlways);
7160                                    pir.removeFilter(pa);
7161                                    pir.addFilter(freshPa);
7162                                    changed = true;
7163                                } else {
7164                                    Slog.i(TAG,
7165                                            "Result set changed, dropping preferred activity for "
7166                                                    + intent + " type " + resolvedType);
7167                                    if (DEBUG_PREFERRED) {
7168                                        Slog.v(TAG, "Removing preferred activity since set changed "
7169                                                + pa.mPref.mComponent);
7170                                    }
7171                                    pir.removeFilter(pa);
7172                                    // Re-add the filter as a "last chosen" entry (!always)
7173                                    PreferredActivity lastChosen = new PreferredActivity(
7174                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7175                                    pir.addFilter(lastChosen);
7176                                    changed = true;
7177                                    return null;
7178                                }
7179                            }
7180
7181                            // Yay! Either the set matched or we're looking for the last chosen
7182                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7183                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7184                            return ri;
7185                        }
7186                    }
7187                } finally {
7188                    if (changed) {
7189                        if (DEBUG_PREFERRED) {
7190                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7191                        }
7192                        scheduleWritePackageRestrictionsLocked(userId);
7193                    }
7194                }
7195            }
7196        }
7197        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7198        return null;
7199    }
7200
7201    /*
7202     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7203     */
7204    @Override
7205    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7206            int targetUserId) {
7207        mContext.enforceCallingOrSelfPermission(
7208                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7209        List<CrossProfileIntentFilter> matches =
7210                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7211        if (matches != null) {
7212            int size = matches.size();
7213            for (int i = 0; i < size; i++) {
7214                if (matches.get(i).getTargetUserId() == targetUserId) return true;
7215            }
7216        }
7217        if (hasWebURI(intent)) {
7218            // cross-profile app linking works only towards the parent.
7219            final int callingUid = Binder.getCallingUid();
7220            final UserInfo parent = getProfileParent(sourceUserId);
7221            synchronized(mPackages) {
7222                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7223                        false /*includeInstantApps*/);
7224                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7225                        intent, resolvedType, flags, sourceUserId, parent.id);
7226                return xpDomainInfo != null;
7227            }
7228        }
7229        return false;
7230    }
7231
7232    private UserInfo getProfileParent(int userId) {
7233        final long identity = Binder.clearCallingIdentity();
7234        try {
7235            return sUserManager.getProfileParent(userId);
7236        } finally {
7237            Binder.restoreCallingIdentity(identity);
7238        }
7239    }
7240
7241    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7242            String resolvedType, int userId) {
7243        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7244        if (resolver != null) {
7245            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7246        }
7247        return null;
7248    }
7249
7250    @Override
7251    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7252            String resolvedType, int flags, int userId) {
7253        try {
7254            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7255
7256            return new ParceledListSlice<>(
7257                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7258        } finally {
7259            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7260        }
7261    }
7262
7263    /**
7264     * Returns the package name of the calling Uid if it's an instant app. If it isn't
7265     * instant, returns {@code null}.
7266     */
7267    private String getInstantAppPackageName(int callingUid) {
7268        synchronized (mPackages) {
7269            // If the caller is an isolated app use the owner's uid for the lookup.
7270            if (Process.isIsolated(callingUid)) {
7271                callingUid = mIsolatedOwners.get(callingUid);
7272            }
7273            final int appId = UserHandle.getAppId(callingUid);
7274            final Object obj = mSettings.getUserIdLPr(appId);
7275            if (obj instanceof PackageSetting) {
7276                final PackageSetting ps = (PackageSetting) obj;
7277                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7278                return isInstantApp ? ps.pkg.packageName : null;
7279            }
7280        }
7281        return null;
7282    }
7283
7284    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7285            String resolvedType, int flags, int userId) {
7286        return queryIntentActivitiesInternal(
7287                intent, resolvedType, flags, Binder.getCallingUid(), userId,
7288                false /*resolveForStart*/, true /*allowDynamicSplits*/);
7289    }
7290
7291    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7292            String resolvedType, int flags, int filterCallingUid, int userId,
7293            boolean resolveForStart, boolean allowDynamicSplits) {
7294        if (!sUserManager.exists(userId)) return Collections.emptyList();
7295        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7296        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7297                false /* requireFullPermission */, false /* checkShell */,
7298                "query intent activities");
7299        final String pkgName = intent.getPackage();
7300        ComponentName comp = intent.getComponent();
7301        if (comp == null) {
7302            if (intent.getSelector() != null) {
7303                intent = intent.getSelector();
7304                comp = intent.getComponent();
7305            }
7306        }
7307
7308        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7309                comp != null || pkgName != null /*onlyExposedExplicitly*/);
7310        if (comp != null) {
7311            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7312            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7313            if (ai != null) {
7314                // When specifying an explicit component, we prevent the activity from being
7315                // used when either 1) the calling package is normal and the activity is within
7316                // an ephemeral application or 2) the calling package is ephemeral and the
7317                // activity is not visible to ephemeral applications.
7318                final boolean matchInstantApp =
7319                        (flags & PackageManager.MATCH_INSTANT) != 0;
7320                final boolean matchVisibleToInstantAppOnly =
7321                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7322                final boolean matchExplicitlyVisibleOnly =
7323                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7324                final boolean isCallerInstantApp =
7325                        instantAppPkgName != null;
7326                final boolean isTargetSameInstantApp =
7327                        comp.getPackageName().equals(instantAppPkgName);
7328                final boolean isTargetInstantApp =
7329                        (ai.applicationInfo.privateFlags
7330                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7331                final boolean isTargetVisibleToInstantApp =
7332                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7333                final boolean isTargetExplicitlyVisibleToInstantApp =
7334                        isTargetVisibleToInstantApp
7335                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7336                final boolean isTargetHiddenFromInstantApp =
7337                        !isTargetVisibleToInstantApp
7338                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7339                final boolean blockResolution =
7340                        !isTargetSameInstantApp
7341                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7342                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7343                                        && isTargetHiddenFromInstantApp));
7344                if (!blockResolution) {
7345                    final ResolveInfo ri = new ResolveInfo();
7346                    ri.activityInfo = ai;
7347                    list.add(ri);
7348                }
7349            }
7350            return applyPostResolutionFilter(
7351                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7352        }
7353
7354        // reader
7355        boolean sortResult = false;
7356        boolean addEphemeral = false;
7357        List<ResolveInfo> result;
7358        final boolean ephemeralDisabled = isEphemeralDisabled();
7359        synchronized (mPackages) {
7360            if (pkgName == null) {
7361                List<CrossProfileIntentFilter> matchingFilters =
7362                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7363                // Check for results that need to skip the current profile.
7364                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7365                        resolvedType, flags, userId);
7366                if (xpResolveInfo != null) {
7367                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7368                    xpResult.add(xpResolveInfo);
7369                    return applyPostResolutionFilter(
7370                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7371                            allowDynamicSplits, filterCallingUid, userId);
7372                }
7373
7374                // Check for results in the current profile.
7375                result = filterIfNotSystemUser(mActivities.queryIntent(
7376                        intent, resolvedType, flags, userId), userId);
7377                addEphemeral = !ephemeralDisabled
7378                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7379                // Check for cross profile results.
7380                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7381                xpResolveInfo = queryCrossProfileIntents(
7382                        matchingFilters, intent, resolvedType, flags, userId,
7383                        hasNonNegativePriorityResult);
7384                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7385                    boolean isVisibleToUser = filterIfNotSystemUser(
7386                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
7387                    if (isVisibleToUser) {
7388                        result.add(xpResolveInfo);
7389                        sortResult = true;
7390                    }
7391                }
7392                if (hasWebURI(intent)) {
7393                    CrossProfileDomainInfo xpDomainInfo = null;
7394                    final UserInfo parent = getProfileParent(userId);
7395                    if (parent != null) {
7396                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7397                                flags, userId, parent.id);
7398                    }
7399                    if (xpDomainInfo != null) {
7400                        if (xpResolveInfo != null) {
7401                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
7402                            // in the result.
7403                            result.remove(xpResolveInfo);
7404                        }
7405                        if (result.size() == 0 && !addEphemeral) {
7406                            // No result in current profile, but found candidate in parent user.
7407                            // And we are not going to add emphemeral app, so we can return the
7408                            // result straight away.
7409                            result.add(xpDomainInfo.resolveInfo);
7410                            return applyPostResolutionFilter(result, instantAppPkgName,
7411                                    allowDynamicSplits, filterCallingUid, userId);
7412                        }
7413                    } else if (result.size() <= 1 && !addEphemeral) {
7414                        // No result in parent user and <= 1 result in current profile, and we
7415                        // are not going to add emphemeral app, so we can return the result without
7416                        // further processing.
7417                        return applyPostResolutionFilter(result, instantAppPkgName,
7418                                allowDynamicSplits, filterCallingUid, userId);
7419                    }
7420                    // We have more than one candidate (combining results from current and parent
7421                    // profile), so we need filtering and sorting.
7422                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7423                            intent, flags, result, xpDomainInfo, userId);
7424                    sortResult = true;
7425                }
7426            } else {
7427                final PackageParser.Package pkg = mPackages.get(pkgName);
7428                result = null;
7429                if (pkg != null) {
7430                    result = filterIfNotSystemUser(
7431                            mActivities.queryIntentForPackage(
7432                                    intent, resolvedType, flags, pkg.activities, userId),
7433                            userId);
7434                }
7435                if (result == null || result.size() == 0) {
7436                    // the caller wants to resolve for a particular package; however, there
7437                    // were no installed results, so, try to find an ephemeral result
7438                    addEphemeral = !ephemeralDisabled
7439                            && isInstantAppAllowed(
7440                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7441                    if (result == null) {
7442                        result = new ArrayList<>();
7443                    }
7444                }
7445            }
7446        }
7447        if (addEphemeral) {
7448            result = maybeAddInstantAppInstaller(
7449                    result, intent, resolvedType, flags, userId, resolveForStart);
7450        }
7451        if (sortResult) {
7452            Collections.sort(result, mResolvePrioritySorter);
7453        }
7454        return applyPostResolutionFilter(
7455                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7456    }
7457
7458    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7459            String resolvedType, int flags, int userId, boolean resolveForStart) {
7460        // first, check to see if we've got an instant app already installed
7461        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7462        ResolveInfo localInstantApp = null;
7463        boolean blockResolution = false;
7464        if (!alreadyResolvedLocally) {
7465            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7466                    flags
7467                        | PackageManager.GET_RESOLVED_FILTER
7468                        | PackageManager.MATCH_INSTANT
7469                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7470                    userId);
7471            for (int i = instantApps.size() - 1; i >= 0; --i) {
7472                final ResolveInfo info = instantApps.get(i);
7473                final String packageName = info.activityInfo.packageName;
7474                final PackageSetting ps = mSettings.mPackages.get(packageName);
7475                if (ps.getInstantApp(userId)) {
7476                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7477                    final int status = (int)(packedStatus >> 32);
7478                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7479                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7480                        // there's a local instant application installed, but, the user has
7481                        // chosen to never use it; skip resolution and don't acknowledge
7482                        // an instant application is even available
7483                        if (DEBUG_EPHEMERAL) {
7484                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7485                        }
7486                        blockResolution = true;
7487                        break;
7488                    } else {
7489                        // we have a locally installed instant application; skip resolution
7490                        // but acknowledge there's an instant application available
7491                        if (DEBUG_EPHEMERAL) {
7492                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7493                        }
7494                        localInstantApp = info;
7495                        break;
7496                    }
7497                }
7498            }
7499        }
7500        // no app installed, let's see if one's available
7501        AuxiliaryResolveInfo auxiliaryResponse = null;
7502        if (!blockResolution) {
7503            if (localInstantApp == null) {
7504                // we don't have an instant app locally, resolve externally
7505                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7506                final InstantAppRequest requestObject = new InstantAppRequest(
7507                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7508                        null /*callingPackage*/, userId, null /*verificationBundle*/,
7509                        resolveForStart);
7510                auxiliaryResponse =
7511                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7512                                mContext, mInstantAppResolverConnection, requestObject);
7513                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7514            } else {
7515                // we have an instant application locally, but, we can't admit that since
7516                // callers shouldn't be able to determine prior browsing. create a dummy
7517                // auxiliary response so the downstream code behaves as if there's an
7518                // instant application available externally. when it comes time to start
7519                // the instant application, we'll do the right thing.
7520                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7521                auxiliaryResponse = new AuxiliaryResolveInfo(
7522                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
7523                        ai.versionCode, null /*failureIntent*/);
7524            }
7525        }
7526        if (auxiliaryResponse != null) {
7527            if (DEBUG_EPHEMERAL) {
7528                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7529            }
7530            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7531            final PackageSetting ps =
7532                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7533            if (ps != null) {
7534                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7535                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7536                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7537                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7538                // make sure this resolver is the default
7539                ephemeralInstaller.isDefault = true;
7540                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7541                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7542                // add a non-generic filter
7543                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7544                ephemeralInstaller.filter.addDataPath(
7545                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7546                ephemeralInstaller.isInstantAppAvailable = true;
7547                result.add(ephemeralInstaller);
7548            }
7549        }
7550        return result;
7551    }
7552
7553    private static class CrossProfileDomainInfo {
7554        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7555        ResolveInfo resolveInfo;
7556        /* Best domain verification status of the activities found in the other profile */
7557        int bestDomainVerificationStatus;
7558    }
7559
7560    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7561            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7562        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7563                sourceUserId)) {
7564            return null;
7565        }
7566        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7567                resolvedType, flags, parentUserId);
7568
7569        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7570            return null;
7571        }
7572        CrossProfileDomainInfo result = null;
7573        int size = resultTargetUser.size();
7574        for (int i = 0; i < size; i++) {
7575            ResolveInfo riTargetUser = resultTargetUser.get(i);
7576            // Intent filter verification is only for filters that specify a host. So don't return
7577            // those that handle all web uris.
7578            if (riTargetUser.handleAllWebDataURI) {
7579                continue;
7580            }
7581            String packageName = riTargetUser.activityInfo.packageName;
7582            PackageSetting ps = mSettings.mPackages.get(packageName);
7583            if (ps == null) {
7584                continue;
7585            }
7586            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7587            int status = (int)(verificationState >> 32);
7588            if (result == null) {
7589                result = new CrossProfileDomainInfo();
7590                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7591                        sourceUserId, parentUserId);
7592                result.bestDomainVerificationStatus = status;
7593            } else {
7594                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7595                        result.bestDomainVerificationStatus);
7596            }
7597        }
7598        // Don't consider matches with status NEVER across profiles.
7599        if (result != null && result.bestDomainVerificationStatus
7600                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7601            return null;
7602        }
7603        return result;
7604    }
7605
7606    /**
7607     * Verification statuses are ordered from the worse to the best, except for
7608     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7609     */
7610    private int bestDomainVerificationStatus(int status1, int status2) {
7611        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7612            return status2;
7613        }
7614        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7615            return status1;
7616        }
7617        return (int) MathUtils.max(status1, status2);
7618    }
7619
7620    private boolean isUserEnabled(int userId) {
7621        long callingId = Binder.clearCallingIdentity();
7622        try {
7623            UserInfo userInfo = sUserManager.getUserInfo(userId);
7624            return userInfo != null && userInfo.isEnabled();
7625        } finally {
7626            Binder.restoreCallingIdentity(callingId);
7627        }
7628    }
7629
7630    /**
7631     * Filter out activities with systemUserOnly flag set, when current user is not System.
7632     *
7633     * @return filtered list
7634     */
7635    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7636        if (userId == UserHandle.USER_SYSTEM) {
7637            return resolveInfos;
7638        }
7639        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7640            ResolveInfo info = resolveInfos.get(i);
7641            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7642                resolveInfos.remove(i);
7643            }
7644        }
7645        return resolveInfos;
7646    }
7647
7648    /**
7649     * Filters out ephemeral activities.
7650     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7651     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7652     *
7653     * @param resolveInfos The pre-filtered list of resolved activities
7654     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7655     *          is performed.
7656     * @return A filtered list of resolved activities.
7657     */
7658    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7659            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
7660        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7661            final ResolveInfo info = resolveInfos.get(i);
7662            // allow activities that are defined in the provided package
7663            if (allowDynamicSplits
7664                    && info.activityInfo.splitName != null
7665                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7666                            info.activityInfo.splitName)) {
7667                if (mInstantAppInstallerInfo == null) {
7668                    if (DEBUG_INSTALL) {
7669                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
7670                    }
7671                    resolveInfos.remove(i);
7672                    continue;
7673                }
7674                // requested activity is defined in a split that hasn't been installed yet.
7675                // add the installer to the resolve list
7676                if (DEBUG_INSTALL) {
7677                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
7678                }
7679                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7680                final ComponentName installFailureActivity = findInstallFailureActivity(
7681                        info.activityInfo.packageName,  filterCallingUid, userId);
7682                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7683                        info.activityInfo.packageName, info.activityInfo.splitName,
7684                        installFailureActivity,
7685                        info.activityInfo.applicationInfo.versionCode,
7686                        null /*failureIntent*/);
7687                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7688                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7689                // add a non-generic filter
7690                installerInfo.filter = new IntentFilter();
7691
7692                // This resolve info may appear in the chooser UI, so let us make it
7693                // look as the one it replaces as far as the user is concerned which
7694                // requires loading the correct label and icon for the resolve info.
7695                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7696                installerInfo.labelRes = info.resolveLabelResId();
7697                installerInfo.icon = info.resolveIconResId();
7698
7699                // propagate priority/preferred order/default
7700                installerInfo.priority = info.priority;
7701                installerInfo.preferredOrder = info.preferredOrder;
7702                installerInfo.isDefault = info.isDefault;
7703                resolveInfos.set(i, installerInfo);
7704                continue;
7705            }
7706            // caller is a full app, don't need to apply any other filtering
7707            if (ephemeralPkgName == null) {
7708                continue;
7709            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7710                // caller is same app; don't need to apply any other filtering
7711                continue;
7712            }
7713            // allow activities that have been explicitly exposed to ephemeral apps
7714            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7715            if (!isEphemeralApp
7716                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7717                continue;
7718            }
7719            resolveInfos.remove(i);
7720        }
7721        return resolveInfos;
7722    }
7723
7724    /**
7725     * Returns the activity component that can handle install failures.
7726     * <p>By default, the instant application installer handles failures. However, an
7727     * application may want to handle failures on its own. Applications do this by
7728     * creating an activity with an intent filter that handles the action
7729     * {@link Intent#ACTION_INSTALL_FAILURE}.
7730     */
7731    private @Nullable ComponentName findInstallFailureActivity(
7732            String packageName, int filterCallingUid, int userId) {
7733        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7734        failureActivityIntent.setPackage(packageName);
7735        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7736        final List<ResolveInfo> result = queryIntentActivitiesInternal(
7737                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7738                false /*resolveForStart*/, false /*allowDynamicSplits*/);
7739        final int NR = result.size();
7740        if (NR > 0) {
7741            for (int i = 0; i < NR; i++) {
7742                final ResolveInfo info = result.get(i);
7743                if (info.activityInfo.splitName != null) {
7744                    continue;
7745                }
7746                return new ComponentName(packageName, info.activityInfo.name);
7747            }
7748        }
7749        return null;
7750    }
7751
7752    /**
7753     * @param resolveInfos list of resolve infos in descending priority order
7754     * @return if the list contains a resolve info with non-negative priority
7755     */
7756    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7757        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7758    }
7759
7760    private static boolean hasWebURI(Intent intent) {
7761        if (intent.getData() == null) {
7762            return false;
7763        }
7764        final String scheme = intent.getScheme();
7765        if (TextUtils.isEmpty(scheme)) {
7766            return false;
7767        }
7768        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7769    }
7770
7771    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7772            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7773            int userId) {
7774        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7775
7776        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7777            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7778                    candidates.size());
7779        }
7780
7781        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7782        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7783        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7784        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7785        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7786        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7787
7788        synchronized (mPackages) {
7789            final int count = candidates.size();
7790            // First, try to use linked apps. Partition the candidates into four lists:
7791            // one for the final results, one for the "do not use ever", one for "undefined status"
7792            // and finally one for "browser app type".
7793            for (int n=0; n<count; n++) {
7794                ResolveInfo info = candidates.get(n);
7795                String packageName = info.activityInfo.packageName;
7796                PackageSetting ps = mSettings.mPackages.get(packageName);
7797                if (ps != null) {
7798                    // Add to the special match all list (Browser use case)
7799                    if (info.handleAllWebDataURI) {
7800                        matchAllList.add(info);
7801                        continue;
7802                    }
7803                    // Try to get the status from User settings first
7804                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7805                    int status = (int)(packedStatus >> 32);
7806                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7807                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7808                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7809                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7810                                    + " : linkgen=" + linkGeneration);
7811                        }
7812                        // Use link-enabled generation as preferredOrder, i.e.
7813                        // prefer newly-enabled over earlier-enabled.
7814                        info.preferredOrder = linkGeneration;
7815                        alwaysList.add(info);
7816                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7817                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7818                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7819                        }
7820                        neverList.add(info);
7821                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7822                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7823                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7824                        }
7825                        alwaysAskList.add(info);
7826                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7827                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7828                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7829                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7830                        }
7831                        undefinedList.add(info);
7832                    }
7833                }
7834            }
7835
7836            // We'll want to include browser possibilities in a few cases
7837            boolean includeBrowser = false;
7838
7839            // First try to add the "always" resolution(s) for the current user, if any
7840            if (alwaysList.size() > 0) {
7841                result.addAll(alwaysList);
7842            } else {
7843                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7844                result.addAll(undefinedList);
7845                // Maybe add one for the other profile.
7846                if (xpDomainInfo != null && (
7847                        xpDomainInfo.bestDomainVerificationStatus
7848                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7849                    result.add(xpDomainInfo.resolveInfo);
7850                }
7851                includeBrowser = true;
7852            }
7853
7854            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7855            // If there were 'always' entries their preferred order has been set, so we also
7856            // back that off to make the alternatives equivalent
7857            if (alwaysAskList.size() > 0) {
7858                for (ResolveInfo i : result) {
7859                    i.preferredOrder = 0;
7860                }
7861                result.addAll(alwaysAskList);
7862                includeBrowser = true;
7863            }
7864
7865            if (includeBrowser) {
7866                // Also add browsers (all of them or only the default one)
7867                if (DEBUG_DOMAIN_VERIFICATION) {
7868                    Slog.v(TAG, "   ...including browsers in candidate set");
7869                }
7870                if ((matchFlags & MATCH_ALL) != 0) {
7871                    result.addAll(matchAllList);
7872                } else {
7873                    // Browser/generic handling case.  If there's a default browser, go straight
7874                    // to that (but only if there is no other higher-priority match).
7875                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7876                    int maxMatchPrio = 0;
7877                    ResolveInfo defaultBrowserMatch = null;
7878                    final int numCandidates = matchAllList.size();
7879                    for (int n = 0; n < numCandidates; n++) {
7880                        ResolveInfo info = matchAllList.get(n);
7881                        // track the highest overall match priority...
7882                        if (info.priority > maxMatchPrio) {
7883                            maxMatchPrio = info.priority;
7884                        }
7885                        // ...and the highest-priority default browser match
7886                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7887                            if (defaultBrowserMatch == null
7888                                    || (defaultBrowserMatch.priority < info.priority)) {
7889                                if (debug) {
7890                                    Slog.v(TAG, "Considering default browser match " + info);
7891                                }
7892                                defaultBrowserMatch = info;
7893                            }
7894                        }
7895                    }
7896                    if (defaultBrowserMatch != null
7897                            && defaultBrowserMatch.priority >= maxMatchPrio
7898                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7899                    {
7900                        if (debug) {
7901                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7902                        }
7903                        result.add(defaultBrowserMatch);
7904                    } else {
7905                        result.addAll(matchAllList);
7906                    }
7907                }
7908
7909                // If there is nothing selected, add all candidates and remove the ones that the user
7910                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7911                if (result.size() == 0) {
7912                    result.addAll(candidates);
7913                    result.removeAll(neverList);
7914                }
7915            }
7916        }
7917        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7918            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7919                    result.size());
7920            for (ResolveInfo info : result) {
7921                Slog.v(TAG, "  + " + info.activityInfo);
7922            }
7923        }
7924        return result;
7925    }
7926
7927    // Returns a packed value as a long:
7928    //
7929    // high 'int'-sized word: link status: undefined/ask/never/always.
7930    // low 'int'-sized word: relative priority among 'always' results.
7931    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7932        long result = ps.getDomainVerificationStatusForUser(userId);
7933        // if none available, get the master status
7934        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7935            if (ps.getIntentFilterVerificationInfo() != null) {
7936                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7937            }
7938        }
7939        return result;
7940    }
7941
7942    private ResolveInfo querySkipCurrentProfileIntents(
7943            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7944            int flags, int sourceUserId) {
7945        if (matchingFilters != null) {
7946            int size = matchingFilters.size();
7947            for (int i = 0; i < size; i ++) {
7948                CrossProfileIntentFilter filter = matchingFilters.get(i);
7949                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7950                    // Checking if there are activities in the target user that can handle the
7951                    // intent.
7952                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7953                            resolvedType, flags, sourceUserId);
7954                    if (resolveInfo != null) {
7955                        return resolveInfo;
7956                    }
7957                }
7958            }
7959        }
7960        return null;
7961    }
7962
7963    // Return matching ResolveInfo in target user if any.
7964    private ResolveInfo queryCrossProfileIntents(
7965            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7966            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7967        if (matchingFilters != null) {
7968            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7969            // match the same intent. For performance reasons, it is better not to
7970            // run queryIntent twice for the same userId
7971            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7972            int size = matchingFilters.size();
7973            for (int i = 0; i < size; i++) {
7974                CrossProfileIntentFilter filter = matchingFilters.get(i);
7975                int targetUserId = filter.getTargetUserId();
7976                boolean skipCurrentProfile =
7977                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7978                boolean skipCurrentProfileIfNoMatchFound =
7979                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7980                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7981                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7982                    // Checking if there are activities in the target user that can handle the
7983                    // intent.
7984                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7985                            resolvedType, flags, sourceUserId);
7986                    if (resolveInfo != null) return resolveInfo;
7987                    alreadyTriedUserIds.put(targetUserId, true);
7988                }
7989            }
7990        }
7991        return null;
7992    }
7993
7994    /**
7995     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7996     * will forward the intent to the filter's target user.
7997     * Otherwise, returns null.
7998     */
7999    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
8000            String resolvedType, int flags, int sourceUserId) {
8001        int targetUserId = filter.getTargetUserId();
8002        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
8003                resolvedType, flags, targetUserId);
8004        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
8005            // If all the matches in the target profile are suspended, return null.
8006            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
8007                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
8008                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
8009                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
8010                            targetUserId);
8011                }
8012            }
8013        }
8014        return null;
8015    }
8016
8017    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
8018            int sourceUserId, int targetUserId) {
8019        ResolveInfo forwardingResolveInfo = new ResolveInfo();
8020        long ident = Binder.clearCallingIdentity();
8021        boolean targetIsProfile;
8022        try {
8023            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
8024        } finally {
8025            Binder.restoreCallingIdentity(ident);
8026        }
8027        String className;
8028        if (targetIsProfile) {
8029            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
8030        } else {
8031            className = FORWARD_INTENT_TO_PARENT;
8032        }
8033        ComponentName forwardingActivityComponentName = new ComponentName(
8034                mAndroidApplication.packageName, className);
8035        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
8036                sourceUserId);
8037        if (!targetIsProfile) {
8038            forwardingActivityInfo.showUserIcon = targetUserId;
8039            forwardingResolveInfo.noResourceId = true;
8040        }
8041        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
8042        forwardingResolveInfo.priority = 0;
8043        forwardingResolveInfo.preferredOrder = 0;
8044        forwardingResolveInfo.match = 0;
8045        forwardingResolveInfo.isDefault = true;
8046        forwardingResolveInfo.filter = filter;
8047        forwardingResolveInfo.targetUserId = targetUserId;
8048        return forwardingResolveInfo;
8049    }
8050
8051    @Override
8052    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
8053            Intent[] specifics, String[] specificTypes, Intent intent,
8054            String resolvedType, int flags, int userId) {
8055        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
8056                specificTypes, intent, resolvedType, flags, userId));
8057    }
8058
8059    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
8060            Intent[] specifics, String[] specificTypes, Intent intent,
8061            String resolvedType, int flags, int userId) {
8062        if (!sUserManager.exists(userId)) return Collections.emptyList();
8063        final int callingUid = Binder.getCallingUid();
8064        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8065                false /*includeInstantApps*/);
8066        enforceCrossUserPermission(callingUid, userId,
8067                false /*requireFullPermission*/, false /*checkShell*/,
8068                "query intent activity options");
8069        final String resultsAction = intent.getAction();
8070
8071        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
8072                | PackageManager.GET_RESOLVED_FILTER, userId);
8073
8074        if (DEBUG_INTENT_MATCHING) {
8075            Log.v(TAG, "Query " + intent + ": " + results);
8076        }
8077
8078        int specificsPos = 0;
8079        int N;
8080
8081        // todo: note that the algorithm used here is O(N^2).  This
8082        // isn't a problem in our current environment, but if we start running
8083        // into situations where we have more than 5 or 10 matches then this
8084        // should probably be changed to something smarter...
8085
8086        // First we go through and resolve each of the specific items
8087        // that were supplied, taking care of removing any corresponding
8088        // duplicate items in the generic resolve list.
8089        if (specifics != null) {
8090            for (int i=0; i<specifics.length; i++) {
8091                final Intent sintent = specifics[i];
8092                if (sintent == null) {
8093                    continue;
8094                }
8095
8096                if (DEBUG_INTENT_MATCHING) {
8097                    Log.v(TAG, "Specific #" + i + ": " + sintent);
8098                }
8099
8100                String action = sintent.getAction();
8101                if (resultsAction != null && resultsAction.equals(action)) {
8102                    // If this action was explicitly requested, then don't
8103                    // remove things that have it.
8104                    action = null;
8105                }
8106
8107                ResolveInfo ri = null;
8108                ActivityInfo ai = null;
8109
8110                ComponentName comp = sintent.getComponent();
8111                if (comp == null) {
8112                    ri = resolveIntent(
8113                        sintent,
8114                        specificTypes != null ? specificTypes[i] : null,
8115                            flags, userId);
8116                    if (ri == null) {
8117                        continue;
8118                    }
8119                    if (ri == mResolveInfo) {
8120                        // ACK!  Must do something better with this.
8121                    }
8122                    ai = ri.activityInfo;
8123                    comp = new ComponentName(ai.applicationInfo.packageName,
8124                            ai.name);
8125                } else {
8126                    ai = getActivityInfo(comp, flags, userId);
8127                    if (ai == null) {
8128                        continue;
8129                    }
8130                }
8131
8132                // Look for any generic query activities that are duplicates
8133                // of this specific one, and remove them from the results.
8134                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
8135                N = results.size();
8136                int j;
8137                for (j=specificsPos; j<N; j++) {
8138                    ResolveInfo sri = results.get(j);
8139                    if ((sri.activityInfo.name.equals(comp.getClassName())
8140                            && sri.activityInfo.applicationInfo.packageName.equals(
8141                                    comp.getPackageName()))
8142                        || (action != null && sri.filter.matchAction(action))) {
8143                        results.remove(j);
8144                        if (DEBUG_INTENT_MATCHING) Log.v(
8145                            TAG, "Removing duplicate item from " + j
8146                            + " due to specific " + specificsPos);
8147                        if (ri == null) {
8148                            ri = sri;
8149                        }
8150                        j--;
8151                        N--;
8152                    }
8153                }
8154
8155                // Add this specific item to its proper place.
8156                if (ri == null) {
8157                    ri = new ResolveInfo();
8158                    ri.activityInfo = ai;
8159                }
8160                results.add(specificsPos, ri);
8161                ri.specificIndex = i;
8162                specificsPos++;
8163            }
8164        }
8165
8166        // Now we go through the remaining generic results and remove any
8167        // duplicate actions that are found here.
8168        N = results.size();
8169        for (int i=specificsPos; i<N-1; i++) {
8170            final ResolveInfo rii = results.get(i);
8171            if (rii.filter == null) {
8172                continue;
8173            }
8174
8175            // Iterate over all of the actions of this result's intent
8176            // filter...  typically this should be just one.
8177            final Iterator<String> it = rii.filter.actionsIterator();
8178            if (it == null) {
8179                continue;
8180            }
8181            while (it.hasNext()) {
8182                final String action = it.next();
8183                if (resultsAction != null && resultsAction.equals(action)) {
8184                    // If this action was explicitly requested, then don't
8185                    // remove things that have it.
8186                    continue;
8187                }
8188                for (int j=i+1; j<N; j++) {
8189                    final ResolveInfo rij = results.get(j);
8190                    if (rij.filter != null && rij.filter.hasAction(action)) {
8191                        results.remove(j);
8192                        if (DEBUG_INTENT_MATCHING) Log.v(
8193                            TAG, "Removing duplicate item from " + j
8194                            + " due to action " + action + " at " + i);
8195                        j--;
8196                        N--;
8197                    }
8198                }
8199            }
8200
8201            // If the caller didn't request filter information, drop it now
8202            // so we don't have to marshall/unmarshall it.
8203            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8204                rii.filter = null;
8205            }
8206        }
8207
8208        // Filter out the caller activity if so requested.
8209        if (caller != null) {
8210            N = results.size();
8211            for (int i=0; i<N; i++) {
8212                ActivityInfo ainfo = results.get(i).activityInfo;
8213                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
8214                        && caller.getClassName().equals(ainfo.name)) {
8215                    results.remove(i);
8216                    break;
8217                }
8218            }
8219        }
8220
8221        // If the caller didn't request filter information,
8222        // drop them now so we don't have to
8223        // marshall/unmarshall it.
8224        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8225            N = results.size();
8226            for (int i=0; i<N; i++) {
8227                results.get(i).filter = null;
8228            }
8229        }
8230
8231        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8232        return results;
8233    }
8234
8235    @Override
8236    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8237            String resolvedType, int flags, int userId) {
8238        return new ParceledListSlice<>(
8239                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8240                        false /*allowDynamicSplits*/));
8241    }
8242
8243    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8244            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8245        if (!sUserManager.exists(userId)) return Collections.emptyList();
8246        final int callingUid = Binder.getCallingUid();
8247        enforceCrossUserPermission(callingUid, userId,
8248                false /*requireFullPermission*/, false /*checkShell*/,
8249                "query intent receivers");
8250        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8251        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8252                false /*includeInstantApps*/);
8253        ComponentName comp = intent.getComponent();
8254        if (comp == null) {
8255            if (intent.getSelector() != null) {
8256                intent = intent.getSelector();
8257                comp = intent.getComponent();
8258            }
8259        }
8260        if (comp != null) {
8261            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8262            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8263            if (ai != null) {
8264                // When specifying an explicit component, we prevent the activity from being
8265                // used when either 1) the calling package is normal and the activity is within
8266                // an instant application or 2) the calling package is ephemeral and the
8267                // activity is not visible to instant applications.
8268                final boolean matchInstantApp =
8269                        (flags & PackageManager.MATCH_INSTANT) != 0;
8270                final boolean matchVisibleToInstantAppOnly =
8271                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8272                final boolean matchExplicitlyVisibleOnly =
8273                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8274                final boolean isCallerInstantApp =
8275                        instantAppPkgName != null;
8276                final boolean isTargetSameInstantApp =
8277                        comp.getPackageName().equals(instantAppPkgName);
8278                final boolean isTargetInstantApp =
8279                        (ai.applicationInfo.privateFlags
8280                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8281                final boolean isTargetVisibleToInstantApp =
8282                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8283                final boolean isTargetExplicitlyVisibleToInstantApp =
8284                        isTargetVisibleToInstantApp
8285                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8286                final boolean isTargetHiddenFromInstantApp =
8287                        !isTargetVisibleToInstantApp
8288                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8289                final boolean blockResolution =
8290                        !isTargetSameInstantApp
8291                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8292                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8293                                        && isTargetHiddenFromInstantApp));
8294                if (!blockResolution) {
8295                    ResolveInfo ri = new ResolveInfo();
8296                    ri.activityInfo = ai;
8297                    list.add(ri);
8298                }
8299            }
8300            return applyPostResolutionFilter(
8301                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8302        }
8303
8304        // reader
8305        synchronized (mPackages) {
8306            String pkgName = intent.getPackage();
8307            if (pkgName == null) {
8308                final List<ResolveInfo> result =
8309                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
8310                return applyPostResolutionFilter(
8311                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8312            }
8313            final PackageParser.Package pkg = mPackages.get(pkgName);
8314            if (pkg != null) {
8315                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8316                        intent, resolvedType, flags, pkg.receivers, userId);
8317                return applyPostResolutionFilter(
8318                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8319            }
8320            return Collections.emptyList();
8321        }
8322    }
8323
8324    @Override
8325    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8326        final int callingUid = Binder.getCallingUid();
8327        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8328    }
8329
8330    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8331            int userId, int callingUid) {
8332        if (!sUserManager.exists(userId)) return null;
8333        flags = updateFlagsForResolve(
8334                flags, userId, intent, callingUid, false /*includeInstantApps*/);
8335        List<ResolveInfo> query = queryIntentServicesInternal(
8336                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8337        if (query != null) {
8338            if (query.size() >= 1) {
8339                // If there is more than one service with the same priority,
8340                // just arbitrarily pick the first one.
8341                return query.get(0);
8342            }
8343        }
8344        return null;
8345    }
8346
8347    @Override
8348    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8349            String resolvedType, int flags, int userId) {
8350        final int callingUid = Binder.getCallingUid();
8351        return new ParceledListSlice<>(queryIntentServicesInternal(
8352                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8353    }
8354
8355    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8356            String resolvedType, int flags, int userId, int callingUid,
8357            boolean includeInstantApps) {
8358        if (!sUserManager.exists(userId)) return Collections.emptyList();
8359        enforceCrossUserPermission(callingUid, userId,
8360                false /*requireFullPermission*/, false /*checkShell*/,
8361                "query intent receivers");
8362        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8363        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8364        ComponentName comp = intent.getComponent();
8365        if (comp == null) {
8366            if (intent.getSelector() != null) {
8367                intent = intent.getSelector();
8368                comp = intent.getComponent();
8369            }
8370        }
8371        if (comp != null) {
8372            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8373            final ServiceInfo si = getServiceInfo(comp, flags, userId);
8374            if (si != null) {
8375                // When specifying an explicit component, we prevent the service from being
8376                // used when either 1) the service is in an instant application and the
8377                // caller is not the same instant application or 2) the calling package is
8378                // ephemeral and the activity is not visible to ephemeral applications.
8379                final boolean matchInstantApp =
8380                        (flags & PackageManager.MATCH_INSTANT) != 0;
8381                final boolean matchVisibleToInstantAppOnly =
8382                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8383                final boolean isCallerInstantApp =
8384                        instantAppPkgName != null;
8385                final boolean isTargetSameInstantApp =
8386                        comp.getPackageName().equals(instantAppPkgName);
8387                final boolean isTargetInstantApp =
8388                        (si.applicationInfo.privateFlags
8389                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8390                final boolean isTargetHiddenFromInstantApp =
8391                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8392                final boolean blockResolution =
8393                        !isTargetSameInstantApp
8394                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8395                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8396                                        && isTargetHiddenFromInstantApp));
8397                if (!blockResolution) {
8398                    final ResolveInfo ri = new ResolveInfo();
8399                    ri.serviceInfo = si;
8400                    list.add(ri);
8401                }
8402            }
8403            return list;
8404        }
8405
8406        // reader
8407        synchronized (mPackages) {
8408            String pkgName = intent.getPackage();
8409            if (pkgName == null) {
8410                return applyPostServiceResolutionFilter(
8411                        mServices.queryIntent(intent, resolvedType, flags, userId),
8412                        instantAppPkgName);
8413            }
8414            final PackageParser.Package pkg = mPackages.get(pkgName);
8415            if (pkg != null) {
8416                return applyPostServiceResolutionFilter(
8417                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8418                                userId),
8419                        instantAppPkgName);
8420            }
8421            return Collections.emptyList();
8422        }
8423    }
8424
8425    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8426            String instantAppPkgName) {
8427        if (instantAppPkgName == null) {
8428            return resolveInfos;
8429        }
8430        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8431            final ResolveInfo info = resolveInfos.get(i);
8432            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8433            // allow services that are defined in the provided package
8434            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8435                if (info.serviceInfo.splitName != null
8436                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8437                                info.serviceInfo.splitName)) {
8438                    // requested service is defined in a split that hasn't been installed yet.
8439                    // add the installer to the resolve list
8440                    if (DEBUG_EPHEMERAL) {
8441                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8442                    }
8443                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8444                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8445                            info.serviceInfo.packageName, info.serviceInfo.splitName,
8446                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
8447                            null /*failureIntent*/);
8448                    // make sure this resolver is the default
8449                    installerInfo.isDefault = true;
8450                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8451                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8452                    // add a non-generic filter
8453                    installerInfo.filter = new IntentFilter();
8454                    // load resources from the correct package
8455                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8456                    resolveInfos.set(i, installerInfo);
8457                }
8458                continue;
8459            }
8460            // allow services that have been explicitly exposed to ephemeral apps
8461            if (!isEphemeralApp
8462                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8463                continue;
8464            }
8465            resolveInfos.remove(i);
8466        }
8467        return resolveInfos;
8468    }
8469
8470    @Override
8471    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8472            String resolvedType, int flags, int userId) {
8473        return new ParceledListSlice<>(
8474                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8475    }
8476
8477    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8478            Intent intent, String resolvedType, int flags, int userId) {
8479        if (!sUserManager.exists(userId)) return Collections.emptyList();
8480        final int callingUid = Binder.getCallingUid();
8481        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8482        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8483                false /*includeInstantApps*/);
8484        ComponentName comp = intent.getComponent();
8485        if (comp == null) {
8486            if (intent.getSelector() != null) {
8487                intent = intent.getSelector();
8488                comp = intent.getComponent();
8489            }
8490        }
8491        if (comp != null) {
8492            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8493            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8494            if (pi != null) {
8495                // When specifying an explicit component, we prevent the provider from being
8496                // used when either 1) the provider is in an instant application and the
8497                // caller is not the same instant application or 2) the calling package is an
8498                // instant application and the provider is not visible to instant applications.
8499                final boolean matchInstantApp =
8500                        (flags & PackageManager.MATCH_INSTANT) != 0;
8501                final boolean matchVisibleToInstantAppOnly =
8502                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8503                final boolean isCallerInstantApp =
8504                        instantAppPkgName != null;
8505                final boolean isTargetSameInstantApp =
8506                        comp.getPackageName().equals(instantAppPkgName);
8507                final boolean isTargetInstantApp =
8508                        (pi.applicationInfo.privateFlags
8509                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8510                final boolean isTargetHiddenFromInstantApp =
8511                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8512                final boolean blockResolution =
8513                        !isTargetSameInstantApp
8514                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8515                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8516                                        && isTargetHiddenFromInstantApp));
8517                if (!blockResolution) {
8518                    final ResolveInfo ri = new ResolveInfo();
8519                    ri.providerInfo = pi;
8520                    list.add(ri);
8521                }
8522            }
8523            return list;
8524        }
8525
8526        // reader
8527        synchronized (mPackages) {
8528            String pkgName = intent.getPackage();
8529            if (pkgName == null) {
8530                return applyPostContentProviderResolutionFilter(
8531                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8532                        instantAppPkgName);
8533            }
8534            final PackageParser.Package pkg = mPackages.get(pkgName);
8535            if (pkg != null) {
8536                return applyPostContentProviderResolutionFilter(
8537                        mProviders.queryIntentForPackage(
8538                        intent, resolvedType, flags, pkg.providers, userId),
8539                        instantAppPkgName);
8540            }
8541            return Collections.emptyList();
8542        }
8543    }
8544
8545    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8546            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8547        if (instantAppPkgName == null) {
8548            return resolveInfos;
8549        }
8550        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8551            final ResolveInfo info = resolveInfos.get(i);
8552            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8553            // allow providers that are defined in the provided package
8554            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8555                if (info.providerInfo.splitName != null
8556                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8557                                info.providerInfo.splitName)) {
8558                    // requested provider is defined in a split that hasn't been installed yet.
8559                    // add the installer to the resolve list
8560                    if (DEBUG_EPHEMERAL) {
8561                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8562                    }
8563                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8564                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8565                            info.providerInfo.packageName, info.providerInfo.splitName,
8566                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
8567                            null /*failureIntent*/);
8568                    // make sure this resolver is the default
8569                    installerInfo.isDefault = true;
8570                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8571                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8572                    // add a non-generic filter
8573                    installerInfo.filter = new IntentFilter();
8574                    // load resources from the correct package
8575                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8576                    resolveInfos.set(i, installerInfo);
8577                }
8578                continue;
8579            }
8580            // allow providers that have been explicitly exposed to instant applications
8581            if (!isEphemeralApp
8582                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8583                continue;
8584            }
8585            resolveInfos.remove(i);
8586        }
8587        return resolveInfos;
8588    }
8589
8590    @Override
8591    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8592        final int callingUid = Binder.getCallingUid();
8593        if (getInstantAppPackageName(callingUid) != null) {
8594            return ParceledListSlice.emptyList();
8595        }
8596        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8597        flags = updateFlagsForPackage(flags, userId, null);
8598        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8599        enforceCrossUserPermission(callingUid, userId,
8600                true /* requireFullPermission */, false /* checkShell */,
8601                "get installed packages");
8602
8603        // writer
8604        synchronized (mPackages) {
8605            ArrayList<PackageInfo> list;
8606            if (listUninstalled) {
8607                list = new ArrayList<>(mSettings.mPackages.size());
8608                for (PackageSetting ps : mSettings.mPackages.values()) {
8609                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8610                        continue;
8611                    }
8612                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8613                        continue;
8614                    }
8615                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8616                    if (pi != null) {
8617                        list.add(pi);
8618                    }
8619                }
8620            } else {
8621                list = new ArrayList<>(mPackages.size());
8622                for (PackageParser.Package p : mPackages.values()) {
8623                    final PackageSetting ps = (PackageSetting) p.mExtras;
8624                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8625                        continue;
8626                    }
8627                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8628                        continue;
8629                    }
8630                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8631                            p.mExtras, flags, userId);
8632                    if (pi != null) {
8633                        list.add(pi);
8634                    }
8635                }
8636            }
8637
8638            return new ParceledListSlice<>(list);
8639        }
8640    }
8641
8642    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8643            String[] permissions, boolean[] tmp, int flags, int userId) {
8644        int numMatch = 0;
8645        final PermissionsState permissionsState = ps.getPermissionsState();
8646        for (int i=0; i<permissions.length; i++) {
8647            final String permission = permissions[i];
8648            if (permissionsState.hasPermission(permission, userId)) {
8649                tmp[i] = true;
8650                numMatch++;
8651            } else {
8652                tmp[i] = false;
8653            }
8654        }
8655        if (numMatch == 0) {
8656            return;
8657        }
8658        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8659
8660        // The above might return null in cases of uninstalled apps or install-state
8661        // skew across users/profiles.
8662        if (pi != null) {
8663            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8664                if (numMatch == permissions.length) {
8665                    pi.requestedPermissions = permissions;
8666                } else {
8667                    pi.requestedPermissions = new String[numMatch];
8668                    numMatch = 0;
8669                    for (int i=0; i<permissions.length; i++) {
8670                        if (tmp[i]) {
8671                            pi.requestedPermissions[numMatch] = permissions[i];
8672                            numMatch++;
8673                        }
8674                    }
8675                }
8676            }
8677            list.add(pi);
8678        }
8679    }
8680
8681    @Override
8682    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8683            String[] permissions, int flags, int userId) {
8684        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8685        flags = updateFlagsForPackage(flags, userId, permissions);
8686        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8687                true /* requireFullPermission */, false /* checkShell */,
8688                "get packages holding permissions");
8689        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8690
8691        // writer
8692        synchronized (mPackages) {
8693            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8694            boolean[] tmpBools = new boolean[permissions.length];
8695            if (listUninstalled) {
8696                for (PackageSetting ps : mSettings.mPackages.values()) {
8697                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8698                            userId);
8699                }
8700            } else {
8701                for (PackageParser.Package pkg : mPackages.values()) {
8702                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8703                    if (ps != null) {
8704                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8705                                userId);
8706                    }
8707                }
8708            }
8709
8710            return new ParceledListSlice<PackageInfo>(list);
8711        }
8712    }
8713
8714    @Override
8715    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8716        final int callingUid = Binder.getCallingUid();
8717        if (getInstantAppPackageName(callingUid) != null) {
8718            return ParceledListSlice.emptyList();
8719        }
8720        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8721        flags = updateFlagsForApplication(flags, userId, null);
8722        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8723
8724        // writer
8725        synchronized (mPackages) {
8726            ArrayList<ApplicationInfo> list;
8727            if (listUninstalled) {
8728                list = new ArrayList<>(mSettings.mPackages.size());
8729                for (PackageSetting ps : mSettings.mPackages.values()) {
8730                    ApplicationInfo ai;
8731                    int effectiveFlags = flags;
8732                    if (ps.isSystem()) {
8733                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8734                    }
8735                    if (ps.pkg != null) {
8736                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8737                            continue;
8738                        }
8739                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8740                            continue;
8741                        }
8742                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8743                                ps.readUserState(userId), userId);
8744                        if (ai != null) {
8745                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8746                        }
8747                    } else {
8748                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8749                        // and already converts to externally visible package name
8750                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8751                                callingUid, effectiveFlags, userId);
8752                    }
8753                    if (ai != null) {
8754                        list.add(ai);
8755                    }
8756                }
8757            } else {
8758                list = new ArrayList<>(mPackages.size());
8759                for (PackageParser.Package p : mPackages.values()) {
8760                    if (p.mExtras != null) {
8761                        PackageSetting ps = (PackageSetting) p.mExtras;
8762                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8763                            continue;
8764                        }
8765                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8766                            continue;
8767                        }
8768                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8769                                ps.readUserState(userId), userId);
8770                        if (ai != null) {
8771                            ai.packageName = resolveExternalPackageNameLPr(p);
8772                            list.add(ai);
8773                        }
8774                    }
8775                }
8776            }
8777
8778            return new ParceledListSlice<>(list);
8779        }
8780    }
8781
8782    @Override
8783    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8784        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8785            return null;
8786        }
8787        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8788            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8789                    "getEphemeralApplications");
8790        }
8791        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8792                true /* requireFullPermission */, false /* checkShell */,
8793                "getEphemeralApplications");
8794        synchronized (mPackages) {
8795            List<InstantAppInfo> instantApps = mInstantAppRegistry
8796                    .getInstantAppsLPr(userId);
8797            if (instantApps != null) {
8798                return new ParceledListSlice<>(instantApps);
8799            }
8800        }
8801        return null;
8802    }
8803
8804    @Override
8805    public boolean isInstantApp(String packageName, int userId) {
8806        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8807                true /* requireFullPermission */, false /* checkShell */,
8808                "isInstantApp");
8809        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8810            return false;
8811        }
8812
8813        synchronized (mPackages) {
8814            int callingUid = Binder.getCallingUid();
8815            if (Process.isIsolated(callingUid)) {
8816                callingUid = mIsolatedOwners.get(callingUid);
8817            }
8818            final PackageSetting ps = mSettings.mPackages.get(packageName);
8819            PackageParser.Package pkg = mPackages.get(packageName);
8820            final boolean returnAllowed =
8821                    ps != null
8822                    && (isCallerSameApp(packageName, callingUid)
8823                            || canViewInstantApps(callingUid, userId)
8824                            || mInstantAppRegistry.isInstantAccessGranted(
8825                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8826            if (returnAllowed) {
8827                return ps.getInstantApp(userId);
8828            }
8829        }
8830        return false;
8831    }
8832
8833    @Override
8834    public byte[] getInstantAppCookie(String packageName, int userId) {
8835        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8836            return null;
8837        }
8838
8839        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8840                true /* requireFullPermission */, false /* checkShell */,
8841                "getInstantAppCookie");
8842        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8843            return null;
8844        }
8845        synchronized (mPackages) {
8846            return mInstantAppRegistry.getInstantAppCookieLPw(
8847                    packageName, userId);
8848        }
8849    }
8850
8851    @Override
8852    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8853        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8854            return true;
8855        }
8856
8857        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8858                true /* requireFullPermission */, true /* checkShell */,
8859                "setInstantAppCookie");
8860        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8861            return false;
8862        }
8863        synchronized (mPackages) {
8864            return mInstantAppRegistry.setInstantAppCookieLPw(
8865                    packageName, cookie, userId);
8866        }
8867    }
8868
8869    @Override
8870    public Bitmap getInstantAppIcon(String packageName, int userId) {
8871        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8872            return null;
8873        }
8874
8875        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8876            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8877                    "getInstantAppIcon");
8878        }
8879        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8880                true /* requireFullPermission */, false /* checkShell */,
8881                "getInstantAppIcon");
8882
8883        synchronized (mPackages) {
8884            return mInstantAppRegistry.getInstantAppIconLPw(
8885                    packageName, userId);
8886        }
8887    }
8888
8889    private boolean isCallerSameApp(String packageName, int uid) {
8890        PackageParser.Package pkg = mPackages.get(packageName);
8891        return pkg != null
8892                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8893    }
8894
8895    @Override
8896    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8897        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8898            return ParceledListSlice.emptyList();
8899        }
8900        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8901    }
8902
8903    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8904        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8905
8906        // reader
8907        synchronized (mPackages) {
8908            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8909            final int userId = UserHandle.getCallingUserId();
8910            while (i.hasNext()) {
8911                final PackageParser.Package p = i.next();
8912                if (p.applicationInfo == null) continue;
8913
8914                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8915                        && !p.applicationInfo.isDirectBootAware();
8916                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8917                        && p.applicationInfo.isDirectBootAware();
8918
8919                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8920                        && (!mSafeMode || isSystemApp(p))
8921                        && (matchesUnaware || matchesAware)) {
8922                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8923                    if (ps != null) {
8924                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8925                                ps.readUserState(userId), userId);
8926                        if (ai != null) {
8927                            finalList.add(ai);
8928                        }
8929                    }
8930                }
8931            }
8932        }
8933
8934        return finalList;
8935    }
8936
8937    @Override
8938    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8939        if (!sUserManager.exists(userId)) return null;
8940        flags = updateFlagsForComponent(flags, userId, name);
8941        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8942        // reader
8943        synchronized (mPackages) {
8944            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8945            PackageSetting ps = provider != null
8946                    ? mSettings.mPackages.get(provider.owner.packageName)
8947                    : null;
8948            if (ps != null) {
8949                final boolean isInstantApp = ps.getInstantApp(userId);
8950                // normal application; filter out instant application provider
8951                if (instantAppPkgName == null && isInstantApp) {
8952                    return null;
8953                }
8954                // instant application; filter out other instant applications
8955                if (instantAppPkgName != null
8956                        && isInstantApp
8957                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8958                    return null;
8959                }
8960                // instant application; filter out non-exposed provider
8961                if (instantAppPkgName != null
8962                        && !isInstantApp
8963                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8964                    return null;
8965                }
8966                // provider not enabled
8967                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8968                    return null;
8969                }
8970                return PackageParser.generateProviderInfo(
8971                        provider, flags, ps.readUserState(userId), userId);
8972            }
8973            return null;
8974        }
8975    }
8976
8977    /**
8978     * @deprecated
8979     */
8980    @Deprecated
8981    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8982        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8983            return;
8984        }
8985        // reader
8986        synchronized (mPackages) {
8987            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8988                    .entrySet().iterator();
8989            final int userId = UserHandle.getCallingUserId();
8990            while (i.hasNext()) {
8991                Map.Entry<String, PackageParser.Provider> entry = i.next();
8992                PackageParser.Provider p = entry.getValue();
8993                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8994
8995                if (ps != null && p.syncable
8996                        && (!mSafeMode || (p.info.applicationInfo.flags
8997                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8998                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8999                            ps.readUserState(userId), userId);
9000                    if (info != null) {
9001                        outNames.add(entry.getKey());
9002                        outInfo.add(info);
9003                    }
9004                }
9005            }
9006        }
9007    }
9008
9009    @Override
9010    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
9011            int uid, int flags, String metaDataKey) {
9012        final int callingUid = Binder.getCallingUid();
9013        final int userId = processName != null ? UserHandle.getUserId(uid)
9014                : UserHandle.getCallingUserId();
9015        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
9016        flags = updateFlagsForComponent(flags, userId, processName);
9017        ArrayList<ProviderInfo> finalList = null;
9018        // reader
9019        synchronized (mPackages) {
9020            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
9021            while (i.hasNext()) {
9022                final PackageParser.Provider p = i.next();
9023                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
9024                if (ps != null && p.info.authority != null
9025                        && (processName == null
9026                                || (p.info.processName.equals(processName)
9027                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
9028                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
9029
9030                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
9031                    // parameter.
9032                    if (metaDataKey != null
9033                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
9034                        continue;
9035                    }
9036                    final ComponentName component =
9037                            new ComponentName(p.info.packageName, p.info.name);
9038                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
9039                        continue;
9040                    }
9041                    if (finalList == null) {
9042                        finalList = new ArrayList<ProviderInfo>(3);
9043                    }
9044                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
9045                            ps.readUserState(userId), userId);
9046                    if (info != null) {
9047                        finalList.add(info);
9048                    }
9049                }
9050            }
9051        }
9052
9053        if (finalList != null) {
9054            Collections.sort(finalList, mProviderInitOrderSorter);
9055            return new ParceledListSlice<ProviderInfo>(finalList);
9056        }
9057
9058        return ParceledListSlice.emptyList();
9059    }
9060
9061    @Override
9062    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
9063        // reader
9064        synchronized (mPackages) {
9065            final int callingUid = Binder.getCallingUid();
9066            final int callingUserId = UserHandle.getUserId(callingUid);
9067            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
9068            if (ps == null) return null;
9069            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
9070                return null;
9071            }
9072            final PackageParser.Instrumentation i = mInstrumentation.get(component);
9073            return PackageParser.generateInstrumentationInfo(i, flags);
9074        }
9075    }
9076
9077    @Override
9078    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
9079            String targetPackage, int flags) {
9080        final int callingUid = Binder.getCallingUid();
9081        final int callingUserId = UserHandle.getUserId(callingUid);
9082        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
9083        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
9084            return ParceledListSlice.emptyList();
9085        }
9086        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
9087    }
9088
9089    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
9090            int flags) {
9091        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
9092
9093        // reader
9094        synchronized (mPackages) {
9095            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
9096            while (i.hasNext()) {
9097                final PackageParser.Instrumentation p = i.next();
9098                if (targetPackage == null
9099                        || targetPackage.equals(p.info.targetPackage)) {
9100                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
9101                            flags);
9102                    if (ii != null) {
9103                        finalList.add(ii);
9104                    }
9105                }
9106            }
9107        }
9108
9109        return finalList;
9110    }
9111
9112    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
9113        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
9114        try {
9115            scanDirLI(dir, parseFlags, scanFlags, currentTime);
9116        } finally {
9117            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9118        }
9119    }
9120
9121    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
9122        final File[] files = dir.listFiles();
9123        if (ArrayUtils.isEmpty(files)) {
9124            Log.d(TAG, "No files in app dir " + dir);
9125            return;
9126        }
9127
9128        if (DEBUG_PACKAGE_SCANNING) {
9129            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
9130                    + " flags=0x" + Integer.toHexString(parseFlags));
9131        }
9132        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
9133                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
9134                mParallelPackageParserCallback);
9135
9136        // Submit files for parsing in parallel
9137        int fileCount = 0;
9138        for (File file : files) {
9139            final boolean isPackage = (isApkFile(file) || file.isDirectory())
9140                    && !PackageInstallerService.isStageName(file.getName());
9141            if (!isPackage) {
9142                // Ignore entries which are not packages
9143                continue;
9144            }
9145            parallelPackageParser.submit(file, parseFlags);
9146            fileCount++;
9147        }
9148
9149        // Process results one by one
9150        for (; fileCount > 0; fileCount--) {
9151            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
9152            Throwable throwable = parseResult.throwable;
9153            int errorCode = PackageManager.INSTALL_SUCCEEDED;
9154
9155            if (throwable == null) {
9156                // Static shared libraries have synthetic package names
9157                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
9158                    renameStaticSharedLibraryPackage(parseResult.pkg);
9159                }
9160                try {
9161                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
9162                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
9163                                currentTime, null);
9164                    }
9165                } catch (PackageManagerException e) {
9166                    errorCode = e.error;
9167                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
9168                }
9169            } else if (throwable instanceof PackageParser.PackageParserException) {
9170                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
9171                        throwable;
9172                errorCode = e.error;
9173                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
9174            } else {
9175                throw new IllegalStateException("Unexpected exception occurred while parsing "
9176                        + parseResult.scanFile, throwable);
9177            }
9178
9179            // Delete invalid userdata apps
9180            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
9181                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
9182                logCriticalInfo(Log.WARN,
9183                        "Deleting invalid package at " + parseResult.scanFile);
9184                removeCodePathLI(parseResult.scanFile);
9185            }
9186        }
9187        parallelPackageParser.close();
9188    }
9189
9190    private static File getSettingsProblemFile() {
9191        File dataDir = Environment.getDataDirectory();
9192        File systemDir = new File(dataDir, "system");
9193        File fname = new File(systemDir, "uiderrors.txt");
9194        return fname;
9195    }
9196
9197    static void reportSettingsProblem(int priority, String msg) {
9198        logCriticalInfo(priority, msg);
9199    }
9200
9201    public static void logCriticalInfo(int priority, String msg) {
9202        Slog.println(priority, TAG, msg);
9203        EventLogTags.writePmCriticalInfo(msg);
9204        try {
9205            File fname = getSettingsProblemFile();
9206            FileOutputStream out = new FileOutputStream(fname, true);
9207            PrintWriter pw = new FastPrintWriter(out);
9208            SimpleDateFormat formatter = new SimpleDateFormat();
9209            String dateString = formatter.format(new Date(System.currentTimeMillis()));
9210            pw.println(dateString + ": " + msg);
9211            pw.close();
9212            FileUtils.setPermissions(
9213                    fname.toString(),
9214                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
9215                    -1, -1);
9216        } catch (java.io.IOException e) {
9217        }
9218    }
9219
9220    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
9221        if (srcFile.isDirectory()) {
9222            final File baseFile = new File(pkg.baseCodePath);
9223            long maxModifiedTime = baseFile.lastModified();
9224            if (pkg.splitCodePaths != null) {
9225                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
9226                    final File splitFile = new File(pkg.splitCodePaths[i]);
9227                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
9228                }
9229            }
9230            return maxModifiedTime;
9231        }
9232        return srcFile.lastModified();
9233    }
9234
9235    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9236            final int policyFlags) throws PackageManagerException {
9237        // When upgrading from pre-N MR1, verify the package time stamp using the package
9238        // directory and not the APK file.
9239        final long lastModifiedTime = mIsPreNMR1Upgrade
9240                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9241        if (ps != null
9242                && ps.codePath.equals(srcFile)
9243                && ps.timeStamp == lastModifiedTime
9244                && !isCompatSignatureUpdateNeeded(pkg)
9245                && !isRecoverSignatureUpdateNeeded(pkg)) {
9246            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9247            KeySetManagerService ksms = mSettings.mKeySetManagerService;
9248            ArraySet<PublicKey> signingKs;
9249            synchronized (mPackages) {
9250                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9251            }
9252            if (ps.signatures.mSignatures != null
9253                    && ps.signatures.mSignatures.length != 0
9254                    && signingKs != null) {
9255                // Optimization: reuse the existing cached certificates
9256                // if the package appears to be unchanged.
9257                pkg.mSignatures = ps.signatures.mSignatures;
9258                pkg.mSigningKeys = signingKs;
9259                return;
9260            }
9261
9262            Slog.w(TAG, "PackageSetting for " + ps.name
9263                    + " is missing signatures.  Collecting certs again to recover them.");
9264        } else {
9265            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9266        }
9267
9268        try {
9269            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9270            PackageParser.collectCertificates(pkg, policyFlags);
9271        } catch (PackageParserException e) {
9272            throw PackageManagerException.from(e);
9273        } finally {
9274            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9275        }
9276    }
9277
9278    /**
9279     *  Traces a package scan.
9280     *  @see #scanPackageLI(File, int, int, long, UserHandle)
9281     */
9282    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9283            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9284        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9285        try {
9286            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9287        } finally {
9288            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9289        }
9290    }
9291
9292    /**
9293     *  Scans a package and returns the newly parsed package.
9294     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9295     */
9296    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9297            long currentTime, UserHandle user) throws PackageManagerException {
9298        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9299        PackageParser pp = new PackageParser();
9300        pp.setSeparateProcesses(mSeparateProcesses);
9301        pp.setOnlyCoreApps(mOnlyCore);
9302        pp.setDisplayMetrics(mMetrics);
9303        pp.setCallback(mPackageParserCallback);
9304
9305        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9306            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9307        }
9308
9309        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9310        final PackageParser.Package pkg;
9311        try {
9312            pkg = pp.parsePackage(scanFile, parseFlags);
9313        } catch (PackageParserException e) {
9314            throw PackageManagerException.from(e);
9315        } finally {
9316            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9317        }
9318
9319        // Static shared libraries have synthetic package names
9320        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9321            renameStaticSharedLibraryPackage(pkg);
9322        }
9323
9324        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9325    }
9326
9327    /**
9328     *  Scans a package and returns the newly parsed package.
9329     *  @throws PackageManagerException on a parse error.
9330     */
9331    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9332            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9333            throws PackageManagerException {
9334        // If the package has children and this is the first dive in the function
9335        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9336        // packages (parent and children) would be successfully scanned before the
9337        // actual scan since scanning mutates internal state and we want to atomically
9338        // install the package and its children.
9339        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9340            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9341                scanFlags |= SCAN_CHECK_ONLY;
9342            }
9343        } else {
9344            scanFlags &= ~SCAN_CHECK_ONLY;
9345        }
9346
9347        // Scan the parent
9348        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9349                scanFlags, currentTime, user);
9350
9351        // Scan the children
9352        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9353        for (int i = 0; i < childCount; i++) {
9354            PackageParser.Package childPackage = pkg.childPackages.get(i);
9355            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9356                    currentTime, user);
9357        }
9358
9359
9360        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9361            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9362        }
9363
9364        return scannedPkg;
9365    }
9366
9367    /**
9368     *  Scans a package and returns the newly parsed package.
9369     *  @throws PackageManagerException on a parse error.
9370     */
9371    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9372            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9373            throws PackageManagerException {
9374        PackageSetting ps = null;
9375        PackageSetting updatedPkg;
9376        // reader
9377        synchronized (mPackages) {
9378            // Look to see if we already know about this package.
9379            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9380            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9381                // This package has been renamed to its original name.  Let's
9382                // use that.
9383                ps = mSettings.getPackageLPr(oldName);
9384            }
9385            // If there was no original package, see one for the real package name.
9386            if (ps == null) {
9387                ps = mSettings.getPackageLPr(pkg.packageName);
9388            }
9389            // Check to see if this package could be hiding/updating a system
9390            // package.  Must look for it either under the original or real
9391            // package name depending on our state.
9392            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9393            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9394
9395            // If this is a package we don't know about on the system partition, we
9396            // may need to remove disabled child packages on the system partition
9397            // or may need to not add child packages if the parent apk is updated
9398            // on the data partition and no longer defines this child package.
9399            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9400                // If this is a parent package for an updated system app and this system
9401                // app got an OTA update which no longer defines some of the child packages
9402                // we have to prune them from the disabled system packages.
9403                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9404                if (disabledPs != null) {
9405                    final int scannedChildCount = (pkg.childPackages != null)
9406                            ? pkg.childPackages.size() : 0;
9407                    final int disabledChildCount = disabledPs.childPackageNames != null
9408                            ? disabledPs.childPackageNames.size() : 0;
9409                    for (int i = 0; i < disabledChildCount; i++) {
9410                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9411                        boolean disabledPackageAvailable = false;
9412                        for (int j = 0; j < scannedChildCount; j++) {
9413                            PackageParser.Package childPkg = pkg.childPackages.get(j);
9414                            if (childPkg.packageName.equals(disabledChildPackageName)) {
9415                                disabledPackageAvailable = true;
9416                                break;
9417                            }
9418                         }
9419                         if (!disabledPackageAvailable) {
9420                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9421                         }
9422                    }
9423                }
9424            }
9425        }
9426
9427        final boolean isUpdatedPkg = updatedPkg != null;
9428        final boolean isUpdatedSystemPkg = isUpdatedPkg
9429                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9430        boolean isUpdatedPkgBetter = false;
9431        // First check if this is a system package that may involve an update
9432        if (isUpdatedSystemPkg) {
9433            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9434            // it needs to drop FLAG_PRIVILEGED.
9435            if (locationIsPrivileged(scanFile)) {
9436                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9437            } else {
9438                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9439            }
9440
9441            if (ps != null && !ps.codePath.equals(scanFile)) {
9442                // The path has changed from what was last scanned...  check the
9443                // version of the new path against what we have stored to determine
9444                // what to do.
9445                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9446                if (pkg.mVersionCode <= ps.versionCode) {
9447                    // The system package has been updated and the code path does not match
9448                    // Ignore entry. Skip it.
9449                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9450                            + " ignored: updated version " + ps.versionCode
9451                            + " better than this " + pkg.mVersionCode);
9452                    if (!updatedPkg.codePath.equals(scanFile)) {
9453                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9454                                + ps.name + " changing from " + updatedPkg.codePathString
9455                                + " to " + scanFile);
9456                        updatedPkg.codePath = scanFile;
9457                        updatedPkg.codePathString = scanFile.toString();
9458                        updatedPkg.resourcePath = scanFile;
9459                        updatedPkg.resourcePathString = scanFile.toString();
9460                    }
9461                    updatedPkg.pkg = pkg;
9462                    updatedPkg.versionCode = pkg.mVersionCode;
9463
9464                    // Update the disabled system child packages to point to the package too.
9465                    final int childCount = updatedPkg.childPackageNames != null
9466                            ? updatedPkg.childPackageNames.size() : 0;
9467                    for (int i = 0; i < childCount; i++) {
9468                        String childPackageName = updatedPkg.childPackageNames.get(i);
9469                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9470                                childPackageName);
9471                        if (updatedChildPkg != null) {
9472                            updatedChildPkg.pkg = pkg;
9473                            updatedChildPkg.versionCode = pkg.mVersionCode;
9474                        }
9475                    }
9476                } else {
9477                    // The current app on the system partition is better than
9478                    // what we have updated to on the data partition; switch
9479                    // back to the system partition version.
9480                    // At this point, its safely assumed that package installation for
9481                    // apps in system partition will go through. If not there won't be a working
9482                    // version of the app
9483                    // writer
9484                    synchronized (mPackages) {
9485                        // Just remove the loaded entries from package lists.
9486                        mPackages.remove(ps.name);
9487                    }
9488
9489                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9490                            + " reverting from " + ps.codePathString
9491                            + ": new version " + pkg.mVersionCode
9492                            + " better than installed " + ps.versionCode);
9493
9494                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9495                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9496                    synchronized (mInstallLock) {
9497                        args.cleanUpResourcesLI();
9498                    }
9499                    synchronized (mPackages) {
9500                        mSettings.enableSystemPackageLPw(ps.name);
9501                    }
9502                    isUpdatedPkgBetter = true;
9503                }
9504            }
9505        }
9506
9507        String resourcePath = null;
9508        String baseResourcePath = null;
9509        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9510            if (ps != null && ps.resourcePathString != null) {
9511                resourcePath = ps.resourcePathString;
9512                baseResourcePath = ps.resourcePathString;
9513            } else {
9514                // Should not happen at all. Just log an error.
9515                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9516            }
9517        } else {
9518            resourcePath = pkg.codePath;
9519            baseResourcePath = pkg.baseCodePath;
9520        }
9521
9522        // Set application objects path explicitly.
9523        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9524        pkg.setApplicationInfoCodePath(pkg.codePath);
9525        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9526        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9527        pkg.setApplicationInfoResourcePath(resourcePath);
9528        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9529        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9530
9531        // throw an exception if we have an update to a system application, but, it's not more
9532        // recent than the package we've already scanned
9533        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9534            // Set CPU Abis to application info.
9535            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9536                final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPkg);
9537                derivePackageAbi(pkg, scanFile, cpuAbiOverride, false, mAppLib32InstallDir);
9538            } else {
9539                pkg.applicationInfo.primaryCpuAbi = updatedPkg.primaryCpuAbiString;
9540                pkg.applicationInfo.secondaryCpuAbi = updatedPkg.secondaryCpuAbiString;
9541            }
9542
9543            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9544                    + scanFile + " ignored: updated version " + ps.versionCode
9545                    + " better than this " + pkg.mVersionCode);
9546        }
9547
9548        if (isUpdatedPkg) {
9549            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9550            // initially
9551            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9552
9553            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9554            // flag set initially
9555            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9556                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9557            }
9558        }
9559
9560        // Verify certificates against what was last scanned
9561        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9562
9563        /*
9564         * A new system app appeared, but we already had a non-system one of the
9565         * same name installed earlier.
9566         */
9567        boolean shouldHideSystemApp = false;
9568        if (!isUpdatedPkg && ps != null
9569                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9570            /*
9571             * Check to make sure the signatures match first. If they don't,
9572             * wipe the installed application and its data.
9573             */
9574            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9575                    != PackageManager.SIGNATURE_MATCH) {
9576                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9577                        + " signatures don't match existing userdata copy; removing");
9578                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9579                        "scanPackageInternalLI")) {
9580                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9581                }
9582                ps = null;
9583            } else {
9584                /*
9585                 * If the newly-added system app is an older version than the
9586                 * already installed version, hide it. It will be scanned later
9587                 * and re-added like an update.
9588                 */
9589                if (pkg.mVersionCode <= ps.versionCode) {
9590                    shouldHideSystemApp = true;
9591                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9592                            + " but new version " + pkg.mVersionCode + " better than installed "
9593                            + ps.versionCode + "; hiding system");
9594                } else {
9595                    /*
9596                     * The newly found system app is a newer version that the
9597                     * one previously installed. Simply remove the
9598                     * already-installed application and replace it with our own
9599                     * while keeping the application data.
9600                     */
9601                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9602                            + " reverting from " + ps.codePathString + ": new version "
9603                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9604                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9605                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9606                    synchronized (mInstallLock) {
9607                        args.cleanUpResourcesLI();
9608                    }
9609                }
9610            }
9611        }
9612
9613        // The apk is forward locked (not public) if its code and resources
9614        // are kept in different files. (except for app in either system or
9615        // vendor path).
9616        // TODO grab this value from PackageSettings
9617        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9618            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9619                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9620            }
9621        }
9622
9623        final int userId = ((user == null) ? 0 : user.getIdentifier());
9624        if (ps != null && ps.getInstantApp(userId)) {
9625            scanFlags |= SCAN_AS_INSTANT_APP;
9626        }
9627        if (ps != null && ps.getVirtulalPreload(userId)) {
9628            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9629        }
9630
9631        // Note that we invoke the following method only if we are about to unpack an application
9632        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9633                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9634
9635        /*
9636         * If the system app should be overridden by a previously installed
9637         * data, hide the system app now and let the /data/app scan pick it up
9638         * again.
9639         */
9640        if (shouldHideSystemApp) {
9641            synchronized (mPackages) {
9642                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9643            }
9644        }
9645
9646        return scannedPkg;
9647    }
9648
9649    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9650        // Derive the new package synthetic package name
9651        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9652                + pkg.staticSharedLibVersion);
9653    }
9654
9655    private static String fixProcessName(String defProcessName,
9656            String processName) {
9657        if (processName == null) {
9658            return defProcessName;
9659        }
9660        return processName;
9661    }
9662
9663    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9664            throws PackageManagerException {
9665        if (pkgSetting.signatures.mSignatures != null) {
9666            // Already existing package. Make sure signatures match
9667            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9668                    == PackageManager.SIGNATURE_MATCH;
9669            if (!match) {
9670                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9671                        == PackageManager.SIGNATURE_MATCH;
9672            }
9673            if (!match) {
9674                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9675                        == PackageManager.SIGNATURE_MATCH;
9676            }
9677            if (!match) {
9678                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9679                        + pkg.packageName + " signatures do not match the "
9680                        + "previously installed version; ignoring!");
9681            }
9682        }
9683
9684        // Check for shared user signatures
9685        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9686            // Already existing package. Make sure signatures match
9687            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9688                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9689            if (!match) {
9690                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9691                        == PackageManager.SIGNATURE_MATCH;
9692            }
9693            if (!match) {
9694                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9695                        == PackageManager.SIGNATURE_MATCH;
9696            }
9697            if (!match) {
9698                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9699                        "Package " + pkg.packageName
9700                        + " has no signatures that match those in shared user "
9701                        + pkgSetting.sharedUser.name + "; ignoring!");
9702            }
9703        }
9704    }
9705
9706    /**
9707     * Enforces that only the system UID or root's UID can call a method exposed
9708     * via Binder.
9709     *
9710     * @param message used as message if SecurityException is thrown
9711     * @throws SecurityException if the caller is not system or root
9712     */
9713    private static final void enforceSystemOrRoot(String message) {
9714        final int uid = Binder.getCallingUid();
9715        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9716            throw new SecurityException(message);
9717        }
9718    }
9719
9720    @Override
9721    public void performFstrimIfNeeded() {
9722        enforceSystemOrRoot("Only the system can request fstrim");
9723
9724        // Before everything else, see whether we need to fstrim.
9725        try {
9726            IStorageManager sm = PackageHelper.getStorageManager();
9727            if (sm != null) {
9728                boolean doTrim = false;
9729                final long interval = android.provider.Settings.Global.getLong(
9730                        mContext.getContentResolver(),
9731                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9732                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9733                if (interval > 0) {
9734                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9735                    if (timeSinceLast > interval) {
9736                        doTrim = true;
9737                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9738                                + "; running immediately");
9739                    }
9740                }
9741                if (doTrim) {
9742                    final boolean dexOptDialogShown;
9743                    synchronized (mPackages) {
9744                        dexOptDialogShown = mDexOptDialogShown;
9745                    }
9746                    if (!isFirstBoot() && dexOptDialogShown) {
9747                        try {
9748                            ActivityManager.getService().showBootMessage(
9749                                    mContext.getResources().getString(
9750                                            R.string.android_upgrading_fstrim), true);
9751                        } catch (RemoteException e) {
9752                        }
9753                    }
9754                    sm.runMaintenance();
9755                }
9756            } else {
9757                Slog.e(TAG, "storageManager service unavailable!");
9758            }
9759        } catch (RemoteException e) {
9760            // Can't happen; StorageManagerService is local
9761        }
9762    }
9763
9764    @Override
9765    public void updatePackagesIfNeeded() {
9766        enforceSystemOrRoot("Only the system can request package update");
9767
9768        // We need to re-extract after an OTA.
9769        boolean causeUpgrade = isUpgrade();
9770
9771        // First boot or factory reset.
9772        // Note: we also handle devices that are upgrading to N right now as if it is their
9773        //       first boot, as they do not have profile data.
9774        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9775
9776        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9777        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9778
9779        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9780            return;
9781        }
9782
9783        List<PackageParser.Package> pkgs;
9784        synchronized (mPackages) {
9785            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9786        }
9787
9788        final long startTime = System.nanoTime();
9789        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9790                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9791                    false /* bootComplete */);
9792
9793        final int elapsedTimeSeconds =
9794                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9795
9796        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9797        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9798        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9799        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9800        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9801    }
9802
9803    /*
9804     * Return the prebuilt profile path given a package base code path.
9805     */
9806    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9807        return pkg.baseCodePath + ".prof";
9808    }
9809
9810    /**
9811     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9812     * containing statistics about the invocation. The array consists of three elements,
9813     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9814     * and {@code numberOfPackagesFailed}.
9815     */
9816    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9817            final String compilerFilter, boolean bootComplete) {
9818
9819        int numberOfPackagesVisited = 0;
9820        int numberOfPackagesOptimized = 0;
9821        int numberOfPackagesSkipped = 0;
9822        int numberOfPackagesFailed = 0;
9823        final int numberOfPackagesToDexopt = pkgs.size();
9824
9825        for (PackageParser.Package pkg : pkgs) {
9826            numberOfPackagesVisited++;
9827
9828            boolean useProfileForDexopt = false;
9829
9830            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9831                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9832                // that are already compiled.
9833                File profileFile = new File(getPrebuildProfilePath(pkg));
9834                // Copy profile if it exists.
9835                if (profileFile.exists()) {
9836                    try {
9837                        // We could also do this lazily before calling dexopt in
9838                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9839                        // is that we don't have a good way to say "do this only once".
9840                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9841                                pkg.applicationInfo.uid, pkg.packageName)) {
9842                            Log.e(TAG, "Installer failed to copy system profile!");
9843                        } else {
9844                            // Disabled as this causes speed-profile compilation during first boot
9845                            // even if things are already compiled.
9846                            // useProfileForDexopt = true;
9847                        }
9848                    } catch (Exception e) {
9849                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9850                                e);
9851                    }
9852                } else {
9853                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9854                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
9855                    // minimize the number off apps being speed-profile compiled during first boot.
9856                    // The other paths will not change the filter.
9857                    if (disabledPs != null && disabledPs.pkg.isStub) {
9858                        // The package is the stub one, remove the stub suffix to get the normal
9859                        // package and APK names.
9860                        String systemProfilePath =
9861                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9862                        profileFile = new File(systemProfilePath);
9863                        // If we have a profile for a compressed APK, copy it to the reference
9864                        // location.
9865                        // Note that copying the profile here will cause it to override the
9866                        // reference profile every OTA even though the existing reference profile
9867                        // may have more data. We can't copy during decompression since the
9868                        // directories are not set up at that point.
9869                        if (profileFile.exists()) {
9870                            try {
9871                                // We could also do this lazily before calling dexopt in
9872                                // PackageDexOptimizer to prevent this happening on first boot. The
9873                                // issue is that we don't have a good way to say "do this only
9874                                // once".
9875                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9876                                        pkg.applicationInfo.uid, pkg.packageName)) {
9877                                    Log.e(TAG, "Failed to copy system profile for stub package!");
9878                                } else {
9879                                    useProfileForDexopt = true;
9880                                }
9881                            } catch (Exception e) {
9882                                Log.e(TAG, "Failed to copy profile " +
9883                                        profileFile.getAbsolutePath() + " ", e);
9884                            }
9885                        }
9886                    }
9887                }
9888            }
9889
9890            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9891                if (DEBUG_DEXOPT) {
9892                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9893                }
9894                numberOfPackagesSkipped++;
9895                continue;
9896            }
9897
9898            if (DEBUG_DEXOPT) {
9899                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9900                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9901            }
9902
9903            if (showDialog) {
9904                try {
9905                    ActivityManager.getService().showBootMessage(
9906                            mContext.getResources().getString(R.string.android_upgrading_apk,
9907                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9908                } catch (RemoteException e) {
9909                }
9910                synchronized (mPackages) {
9911                    mDexOptDialogShown = true;
9912                }
9913            }
9914
9915            String pkgCompilerFilter = compilerFilter;
9916            if (useProfileForDexopt) {
9917                // Use background dexopt mode to try and use the profile. Note that this does not
9918                // guarantee usage of the profile.
9919                pkgCompilerFilter =
9920                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
9921                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
9922            }
9923
9924            // checkProfiles is false to avoid merging profiles during boot which
9925            // might interfere with background compilation (b/28612421).
9926            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9927            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9928            // trade-off worth doing to save boot time work.
9929            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9930            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9931                    pkg.packageName,
9932                    pkgCompilerFilter,
9933                    dexoptFlags));
9934
9935            switch (primaryDexOptStaus) {
9936                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9937                    numberOfPackagesOptimized++;
9938                    break;
9939                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9940                    numberOfPackagesSkipped++;
9941                    break;
9942                case PackageDexOptimizer.DEX_OPT_FAILED:
9943                    numberOfPackagesFailed++;
9944                    break;
9945                default:
9946                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9947                    break;
9948            }
9949        }
9950
9951        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9952                numberOfPackagesFailed };
9953    }
9954
9955    @Override
9956    public void notifyPackageUse(String packageName, int reason) {
9957        synchronized (mPackages) {
9958            final int callingUid = Binder.getCallingUid();
9959            final int callingUserId = UserHandle.getUserId(callingUid);
9960            if (getInstantAppPackageName(callingUid) != null) {
9961                if (!isCallerSameApp(packageName, callingUid)) {
9962                    return;
9963                }
9964            } else {
9965                if (isInstantApp(packageName, callingUserId)) {
9966                    return;
9967                }
9968            }
9969            notifyPackageUseLocked(packageName, reason);
9970        }
9971    }
9972
9973    private void notifyPackageUseLocked(String packageName, int reason) {
9974        final PackageParser.Package p = mPackages.get(packageName);
9975        if (p == null) {
9976            return;
9977        }
9978        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9979    }
9980
9981    @Override
9982    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9983            List<String> classPaths, String loaderIsa) {
9984        int userId = UserHandle.getCallingUserId();
9985        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9986        if (ai == null) {
9987            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9988                + loadingPackageName + ", user=" + userId);
9989            return;
9990        }
9991        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9992    }
9993
9994    @Override
9995    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9996            IDexModuleRegisterCallback callback) {
9997        int userId = UserHandle.getCallingUserId();
9998        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9999        DexManager.RegisterDexModuleResult result;
10000        if (ai == null) {
10001            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
10002                     " calling user. package=" + packageName + ", user=" + userId);
10003            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
10004        } else {
10005            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
10006        }
10007
10008        if (callback != null) {
10009            mHandler.post(() -> {
10010                try {
10011                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
10012                } catch (RemoteException e) {
10013                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
10014                }
10015            });
10016        }
10017    }
10018
10019    /**
10020     * Ask the package manager to perform a dex-opt with the given compiler filter.
10021     *
10022     * Note: exposed only for the shell command to allow moving packages explicitly to a
10023     *       definite state.
10024     */
10025    @Override
10026    public boolean performDexOptMode(String packageName,
10027            boolean checkProfiles, String targetCompilerFilter, boolean force,
10028            boolean bootComplete, String splitName) {
10029        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
10030                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
10031                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
10032        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
10033                splitName, flags));
10034    }
10035
10036    /**
10037     * Ask the package manager to perform a dex-opt with the given compiler filter on the
10038     * secondary dex files belonging to the given package.
10039     *
10040     * Note: exposed only for the shell command to allow moving packages explicitly to a
10041     *       definite state.
10042     */
10043    @Override
10044    public boolean performDexOptSecondary(String packageName, String compilerFilter,
10045            boolean force) {
10046        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
10047                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
10048                DexoptOptions.DEXOPT_BOOT_COMPLETE |
10049                (force ? DexoptOptions.DEXOPT_FORCE : 0);
10050        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
10051    }
10052
10053    /*package*/ boolean performDexOpt(DexoptOptions options) {
10054        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10055            return false;
10056        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
10057            return false;
10058        }
10059
10060        if (options.isDexoptOnlySecondaryDex()) {
10061            return mDexManager.dexoptSecondaryDex(options);
10062        } else {
10063            int dexoptStatus = performDexOptWithStatus(options);
10064            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
10065        }
10066    }
10067
10068    /**
10069     * Perform dexopt on the given package and return one of following result:
10070     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
10071     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
10072     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
10073     */
10074    /* package */ int performDexOptWithStatus(DexoptOptions options) {
10075        return performDexOptTraced(options);
10076    }
10077
10078    private int performDexOptTraced(DexoptOptions options) {
10079        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10080        try {
10081            return performDexOptInternal(options);
10082        } finally {
10083            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10084        }
10085    }
10086
10087    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
10088    // if the package can now be considered up to date for the given filter.
10089    private int performDexOptInternal(DexoptOptions options) {
10090        PackageParser.Package p;
10091        synchronized (mPackages) {
10092            p = mPackages.get(options.getPackageName());
10093            if (p == null) {
10094                // Package could not be found. Report failure.
10095                return PackageDexOptimizer.DEX_OPT_FAILED;
10096            }
10097            mPackageUsage.maybeWriteAsync(mPackages);
10098            mCompilerStats.maybeWriteAsync();
10099        }
10100        long callingId = Binder.clearCallingIdentity();
10101        try {
10102            synchronized (mInstallLock) {
10103                return performDexOptInternalWithDependenciesLI(p, options);
10104            }
10105        } finally {
10106            Binder.restoreCallingIdentity(callingId);
10107        }
10108    }
10109
10110    public ArraySet<String> getOptimizablePackages() {
10111        ArraySet<String> pkgs = new ArraySet<String>();
10112        synchronized (mPackages) {
10113            for (PackageParser.Package p : mPackages.values()) {
10114                if (PackageDexOptimizer.canOptimizePackage(p)) {
10115                    pkgs.add(p.packageName);
10116                }
10117            }
10118        }
10119        return pkgs;
10120    }
10121
10122    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
10123            DexoptOptions options) {
10124        // Select the dex optimizer based on the force parameter.
10125        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
10126        //       allocate an object here.
10127        PackageDexOptimizer pdo = options.isForce()
10128                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
10129                : mPackageDexOptimizer;
10130
10131        // Dexopt all dependencies first. Note: we ignore the return value and march on
10132        // on errors.
10133        // Note that we are going to call performDexOpt on those libraries as many times as
10134        // they are referenced in packages. When we do a batch of performDexOpt (for example
10135        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
10136        // and the first package that uses the library will dexopt it. The
10137        // others will see that the compiled code for the library is up to date.
10138        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
10139        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
10140        if (!deps.isEmpty()) {
10141            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
10142                    options.getCompilerFilter(), options.getSplitName(),
10143                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
10144            for (PackageParser.Package depPackage : deps) {
10145                // TODO: Analyze and investigate if we (should) profile libraries.
10146                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
10147                        getOrCreateCompilerPackageStats(depPackage),
10148                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
10149            }
10150        }
10151        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
10152                getOrCreateCompilerPackageStats(p),
10153                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
10154    }
10155
10156    /**
10157     * Reconcile the information we have about the secondary dex files belonging to
10158     * {@code packagName} and the actual dex files. For all dex files that were
10159     * deleted, update the internal records and delete the generated oat files.
10160     */
10161    @Override
10162    public void reconcileSecondaryDexFiles(String packageName) {
10163        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10164            return;
10165        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
10166            return;
10167        }
10168        mDexManager.reconcileSecondaryDexFiles(packageName);
10169    }
10170
10171    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
10172    // a reference there.
10173    /*package*/ DexManager getDexManager() {
10174        return mDexManager;
10175    }
10176
10177    /**
10178     * Execute the background dexopt job immediately.
10179     */
10180    @Override
10181    public boolean runBackgroundDexoptJob() {
10182        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10183            return false;
10184        }
10185        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
10186    }
10187
10188    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
10189        if (p.usesLibraries != null || p.usesOptionalLibraries != null
10190                || p.usesStaticLibraries != null) {
10191            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
10192            Set<String> collectedNames = new HashSet<>();
10193            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
10194
10195            retValue.remove(p);
10196
10197            return retValue;
10198        } else {
10199            return Collections.emptyList();
10200        }
10201    }
10202
10203    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
10204            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10205        if (!collectedNames.contains(p.packageName)) {
10206            collectedNames.add(p.packageName);
10207            collected.add(p);
10208
10209            if (p.usesLibraries != null) {
10210                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
10211                        null, collected, collectedNames);
10212            }
10213            if (p.usesOptionalLibraries != null) {
10214                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
10215                        null, collected, collectedNames);
10216            }
10217            if (p.usesStaticLibraries != null) {
10218                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
10219                        p.usesStaticLibrariesVersions, collected, collectedNames);
10220            }
10221        }
10222    }
10223
10224    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
10225            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10226        final int libNameCount = libs.size();
10227        for (int i = 0; i < libNameCount; i++) {
10228            String libName = libs.get(i);
10229            int version = (versions != null && versions.length == libNameCount)
10230                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
10231            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
10232            if (libPkg != null) {
10233                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
10234            }
10235        }
10236    }
10237
10238    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
10239        synchronized (mPackages) {
10240            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
10241            if (libEntry != null) {
10242                return mPackages.get(libEntry.apk);
10243            }
10244            return null;
10245        }
10246    }
10247
10248    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
10249        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10250        if (versionedLib == null) {
10251            return null;
10252        }
10253        return versionedLib.get(version);
10254    }
10255
10256    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10257        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10258                pkg.staticSharedLibName);
10259        if (versionedLib == null) {
10260            return null;
10261        }
10262        int previousLibVersion = -1;
10263        final int versionCount = versionedLib.size();
10264        for (int i = 0; i < versionCount; i++) {
10265            final int libVersion = versionedLib.keyAt(i);
10266            if (libVersion < pkg.staticSharedLibVersion) {
10267                previousLibVersion = Math.max(previousLibVersion, libVersion);
10268            }
10269        }
10270        if (previousLibVersion >= 0) {
10271            return versionedLib.get(previousLibVersion);
10272        }
10273        return null;
10274    }
10275
10276    public void shutdown() {
10277        mPackageUsage.writeNow(mPackages);
10278        mCompilerStats.writeNow();
10279        mDexManager.writePackageDexUsageNow();
10280    }
10281
10282    @Override
10283    public void dumpProfiles(String packageName) {
10284        PackageParser.Package pkg;
10285        synchronized (mPackages) {
10286            pkg = mPackages.get(packageName);
10287            if (pkg == null) {
10288                throw new IllegalArgumentException("Unknown package: " + packageName);
10289            }
10290        }
10291        /* Only the shell, root, or the app user should be able to dump profiles. */
10292        int callingUid = Binder.getCallingUid();
10293        if (callingUid != Process.SHELL_UID &&
10294            callingUid != Process.ROOT_UID &&
10295            callingUid != pkg.applicationInfo.uid) {
10296            throw new SecurityException("dumpProfiles");
10297        }
10298
10299        synchronized (mInstallLock) {
10300            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10301            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10302            try {
10303                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10304                String codePaths = TextUtils.join(";", allCodePaths);
10305                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10306            } catch (InstallerException e) {
10307                Slog.w(TAG, "Failed to dump profiles", e);
10308            }
10309            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10310        }
10311    }
10312
10313    @Override
10314    public void forceDexOpt(String packageName) {
10315        enforceSystemOrRoot("forceDexOpt");
10316
10317        PackageParser.Package pkg;
10318        synchronized (mPackages) {
10319            pkg = mPackages.get(packageName);
10320            if (pkg == null) {
10321                throw new IllegalArgumentException("Unknown package: " + packageName);
10322            }
10323        }
10324
10325        synchronized (mInstallLock) {
10326            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10327
10328            // Whoever is calling forceDexOpt wants a compiled package.
10329            // Don't use profiles since that may cause compilation to be skipped.
10330            final int res = performDexOptInternalWithDependenciesLI(
10331                    pkg,
10332                    new DexoptOptions(packageName,
10333                            getDefaultCompilerFilter(),
10334                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10335
10336            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10337            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10338                throw new IllegalStateException("Failed to dexopt: " + res);
10339            }
10340        }
10341    }
10342
10343    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10344        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10345            Slog.w(TAG, "Unable to update from " + oldPkg.name
10346                    + " to " + newPkg.packageName
10347                    + ": old package not in system partition");
10348            return false;
10349        } else if (mPackages.get(oldPkg.name) != null) {
10350            Slog.w(TAG, "Unable to update from " + oldPkg.name
10351                    + " to " + newPkg.packageName
10352                    + ": old package still exists");
10353            return false;
10354        }
10355        return true;
10356    }
10357
10358    void removeCodePathLI(File codePath) {
10359        if (codePath.isDirectory()) {
10360            try {
10361                mInstaller.rmPackageDir(codePath.getAbsolutePath());
10362            } catch (InstallerException e) {
10363                Slog.w(TAG, "Failed to remove code path", e);
10364            }
10365        } else {
10366            codePath.delete();
10367        }
10368    }
10369
10370    private int[] resolveUserIds(int userId) {
10371        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10372    }
10373
10374    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10375        if (pkg == null) {
10376            Slog.wtf(TAG, "Package was null!", new Throwable());
10377            return;
10378        }
10379        clearAppDataLeafLIF(pkg, userId, flags);
10380        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10381        for (int i = 0; i < childCount; i++) {
10382            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10383        }
10384    }
10385
10386    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10387        final PackageSetting ps;
10388        synchronized (mPackages) {
10389            ps = mSettings.mPackages.get(pkg.packageName);
10390        }
10391        for (int realUserId : resolveUserIds(userId)) {
10392            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10393            try {
10394                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10395                        ceDataInode);
10396            } catch (InstallerException e) {
10397                Slog.w(TAG, String.valueOf(e));
10398            }
10399        }
10400    }
10401
10402    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10403        if (pkg == null) {
10404            Slog.wtf(TAG, "Package was null!", new Throwable());
10405            return;
10406        }
10407        destroyAppDataLeafLIF(pkg, userId, flags);
10408        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10409        for (int i = 0; i < childCount; i++) {
10410            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10411        }
10412    }
10413
10414    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10415        final PackageSetting ps;
10416        synchronized (mPackages) {
10417            ps = mSettings.mPackages.get(pkg.packageName);
10418        }
10419        for (int realUserId : resolveUserIds(userId)) {
10420            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10421            try {
10422                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10423                        ceDataInode);
10424            } catch (InstallerException e) {
10425                Slog.w(TAG, String.valueOf(e));
10426            }
10427            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10428        }
10429    }
10430
10431    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10432        if (pkg == null) {
10433            Slog.wtf(TAG, "Package was null!", new Throwable());
10434            return;
10435        }
10436        destroyAppProfilesLeafLIF(pkg);
10437        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10438        for (int i = 0; i < childCount; i++) {
10439            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10440        }
10441    }
10442
10443    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10444        try {
10445            mInstaller.destroyAppProfiles(pkg.packageName);
10446        } catch (InstallerException e) {
10447            Slog.w(TAG, String.valueOf(e));
10448        }
10449    }
10450
10451    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10452        if (pkg == null) {
10453            Slog.wtf(TAG, "Package was null!", new Throwable());
10454            return;
10455        }
10456        clearAppProfilesLeafLIF(pkg);
10457        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10458        for (int i = 0; i < childCount; i++) {
10459            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10460        }
10461    }
10462
10463    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10464        try {
10465            mInstaller.clearAppProfiles(pkg.packageName);
10466        } catch (InstallerException e) {
10467            Slog.w(TAG, String.valueOf(e));
10468        }
10469    }
10470
10471    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10472            long lastUpdateTime) {
10473        // Set parent install/update time
10474        PackageSetting ps = (PackageSetting) pkg.mExtras;
10475        if (ps != null) {
10476            ps.firstInstallTime = firstInstallTime;
10477            ps.lastUpdateTime = lastUpdateTime;
10478        }
10479        // Set children install/update time
10480        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10481        for (int i = 0; i < childCount; i++) {
10482            PackageParser.Package childPkg = pkg.childPackages.get(i);
10483            ps = (PackageSetting) childPkg.mExtras;
10484            if (ps != null) {
10485                ps.firstInstallTime = firstInstallTime;
10486                ps.lastUpdateTime = lastUpdateTime;
10487            }
10488        }
10489    }
10490
10491    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10492            PackageParser.Package changingLib) {
10493        if (file.path != null) {
10494            usesLibraryFiles.add(file.path);
10495            return;
10496        }
10497        PackageParser.Package p = mPackages.get(file.apk);
10498        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10499            // If we are doing this while in the middle of updating a library apk,
10500            // then we need to make sure to use that new apk for determining the
10501            // dependencies here.  (We haven't yet finished committing the new apk
10502            // to the package manager state.)
10503            if (p == null || p.packageName.equals(changingLib.packageName)) {
10504                p = changingLib;
10505            }
10506        }
10507        if (p != null) {
10508            usesLibraryFiles.addAll(p.getAllCodePaths());
10509            if (p.usesLibraryFiles != null) {
10510                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10511            }
10512        }
10513    }
10514
10515    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10516            PackageParser.Package changingLib) throws PackageManagerException {
10517        if (pkg == null) {
10518            return;
10519        }
10520        ArraySet<String> usesLibraryFiles = null;
10521        if (pkg.usesLibraries != null) {
10522            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10523                    null, null, pkg.packageName, changingLib, true,
10524                    pkg.applicationInfo.targetSdkVersion, null);
10525        }
10526        if (pkg.usesStaticLibraries != null) {
10527            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10528                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10529                    pkg.packageName, changingLib, true,
10530                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10531        }
10532        if (pkg.usesOptionalLibraries != null) {
10533            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10534                    null, null, pkg.packageName, changingLib, false,
10535                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10536        }
10537        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10538            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10539        } else {
10540            pkg.usesLibraryFiles = null;
10541        }
10542    }
10543
10544    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10545            @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
10546            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10547            boolean required, int targetSdk, @Nullable ArraySet<String> outUsedLibraries)
10548            throws PackageManagerException {
10549        final int libCount = requestedLibraries.size();
10550        for (int i = 0; i < libCount; i++) {
10551            final String libName = requestedLibraries.get(i);
10552            final int libVersion = requiredVersions != null ? requiredVersions[i]
10553                    : SharedLibraryInfo.VERSION_UNDEFINED;
10554            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10555            if (libEntry == null) {
10556                if (required) {
10557                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10558                            "Package " + packageName + " requires unavailable shared library "
10559                                    + libName + "; failing!");
10560                } else if (DEBUG_SHARED_LIBRARIES) {
10561                    Slog.i(TAG, "Package " + packageName
10562                            + " desires unavailable shared library "
10563                            + libName + "; ignoring!");
10564                }
10565            } else {
10566                if (requiredVersions != null && requiredCertDigests != null) {
10567                    if (libEntry.info.getVersion() != requiredVersions[i]) {
10568                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10569                            "Package " + packageName + " requires unavailable static shared"
10570                                    + " library " + libName + " version "
10571                                    + libEntry.info.getVersion() + "; failing!");
10572                    }
10573
10574                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10575                    if (libPkg == null) {
10576                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10577                                "Package " + packageName + " requires unavailable static shared"
10578                                        + " library; failing!");
10579                    }
10580
10581                    final String[] expectedCertDigests = requiredCertDigests[i];
10582                    // For apps targeting O MR1 we require explicit enumeration of all certs.
10583                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
10584                            ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
10585                            : PackageUtils.computeSignaturesSha256Digests(
10586                                    new Signature[]{libPkg.mSignatures[0]});
10587
10588                    // Take a shortcut if sizes don't match. Note that if an app doesn't
10589                    // target O we don't parse the "additional-certificate" tags similarly
10590                    // how we only consider all certs only for apps targeting O (see above).
10591                    // Therefore, the size check is safe to make.
10592                    if (expectedCertDigests.length != libCertDigests.length) {
10593                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10594                                "Package " + packageName + " requires differently signed" +
10595                                        " static sDexLoadReporter.java:45.19hared library; failing!");
10596                    }
10597
10598                    // Use a predictable order as signature order may vary
10599                    Arrays.sort(libCertDigests);
10600                    Arrays.sort(expectedCertDigests);
10601
10602                    final int certCount = libCertDigests.length;
10603                    for (int j = 0; j < certCount; j++) {
10604                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10605                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10606                                    "Package " + packageName + " requires differently signed" +
10607                                            " static shared library; failing!");
10608                        }
10609                    }
10610                }
10611
10612                if (outUsedLibraries == null) {
10613                    outUsedLibraries = new ArraySet<>();
10614                }
10615                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10616            }
10617        }
10618        return outUsedLibraries;
10619    }
10620
10621    private static boolean hasString(List<String> list, List<String> which) {
10622        if (list == null) {
10623            return false;
10624        }
10625        for (int i=list.size()-1; i>=0; i--) {
10626            for (int j=which.size()-1; j>=0; j--) {
10627                if (which.get(j).equals(list.get(i))) {
10628                    return true;
10629                }
10630            }
10631        }
10632        return false;
10633    }
10634
10635    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10636            PackageParser.Package changingPkg) {
10637        ArrayList<PackageParser.Package> res = null;
10638        for (PackageParser.Package pkg : mPackages.values()) {
10639            if (changingPkg != null
10640                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10641                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10642                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10643                            changingPkg.staticSharedLibName)) {
10644                return null;
10645            }
10646            if (res == null) {
10647                res = new ArrayList<>();
10648            }
10649            res.add(pkg);
10650            try {
10651                updateSharedLibrariesLPr(pkg, changingPkg);
10652            } catch (PackageManagerException e) {
10653                // If a system app update or an app and a required lib missing we
10654                // delete the package and for updated system apps keep the data as
10655                // it is better for the user to reinstall than to be in an limbo
10656                // state. Also libs disappearing under an app should never happen
10657                // - just in case.
10658                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10659                    final int flags = pkg.isUpdatedSystemApp()
10660                            ? PackageManager.DELETE_KEEP_DATA : 0;
10661                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10662                            flags , null, true, null);
10663                }
10664                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10665            }
10666        }
10667        return res;
10668    }
10669
10670    /**
10671     * Derive the value of the {@code cpuAbiOverride} based on the provided
10672     * value and an optional stored value from the package settings.
10673     */
10674    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10675        String cpuAbiOverride = null;
10676
10677        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10678            cpuAbiOverride = null;
10679        } else if (abiOverride != null) {
10680            cpuAbiOverride = abiOverride;
10681        } else if (settings != null) {
10682            cpuAbiOverride = settings.cpuAbiOverrideString;
10683        }
10684
10685        return cpuAbiOverride;
10686    }
10687
10688    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10689            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10690                    throws PackageManagerException {
10691        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10692        // If the package has children and this is the first dive in the function
10693        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10694        // whether all packages (parent and children) would be successfully scanned
10695        // before the actual scan since scanning mutates internal state and we want
10696        // to atomically install the package and its children.
10697        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10698            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10699                scanFlags |= SCAN_CHECK_ONLY;
10700            }
10701        } else {
10702            scanFlags &= ~SCAN_CHECK_ONLY;
10703        }
10704
10705        final PackageParser.Package scannedPkg;
10706        try {
10707            // Scan the parent
10708            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10709            // Scan the children
10710            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10711            for (int i = 0; i < childCount; i++) {
10712                PackageParser.Package childPkg = pkg.childPackages.get(i);
10713                scanPackageLI(childPkg, policyFlags,
10714                        scanFlags, currentTime, user);
10715            }
10716        } finally {
10717            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10718        }
10719
10720        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10721            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10722        }
10723
10724        return scannedPkg;
10725    }
10726
10727    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10728            int scanFlags, long currentTime, @Nullable UserHandle user)
10729                    throws PackageManagerException {
10730        boolean success = false;
10731        try {
10732            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10733                    currentTime, user);
10734            success = true;
10735            return res;
10736        } finally {
10737            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10738                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10739                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10740                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10741                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10742            }
10743        }
10744    }
10745
10746    /**
10747     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10748     */
10749    private static boolean apkHasCode(String fileName) {
10750        StrictJarFile jarFile = null;
10751        try {
10752            jarFile = new StrictJarFile(fileName,
10753                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10754            return jarFile.findEntry("classes.dex") != null;
10755        } catch (IOException ignore) {
10756        } finally {
10757            try {
10758                if (jarFile != null) {
10759                    jarFile.close();
10760                }
10761            } catch (IOException ignore) {}
10762        }
10763        return false;
10764    }
10765
10766    /**
10767     * Enforces code policy for the package. This ensures that if an APK has
10768     * declared hasCode="true" in its manifest that the APK actually contains
10769     * code.
10770     *
10771     * @throws PackageManagerException If bytecode could not be found when it should exist
10772     */
10773    private static void assertCodePolicy(PackageParser.Package pkg)
10774            throws PackageManagerException {
10775        final boolean shouldHaveCode =
10776                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10777        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10778            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10779                    "Package " + pkg.baseCodePath + " code is missing");
10780        }
10781
10782        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10783            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10784                final boolean splitShouldHaveCode =
10785                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10786                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10787                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10788                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10789                }
10790            }
10791        }
10792    }
10793
10794    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10795            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10796                    throws PackageManagerException {
10797        if (DEBUG_PACKAGE_SCANNING) {
10798            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10799                Log.d(TAG, "Scanning package " + pkg.packageName);
10800        }
10801
10802        applyPolicy(pkg, policyFlags);
10803
10804        assertPackageIsValid(pkg, policyFlags, scanFlags);
10805
10806        // Initialize package source and resource directories
10807        final File scanFile = new File(pkg.codePath);
10808        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10809        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10810
10811        SharedUserSetting suid = null;
10812        PackageSetting pkgSetting = null;
10813
10814        // Getting the package setting may have a side-effect, so if we
10815        // are only checking if scan would succeed, stash a copy of the
10816        // old setting to restore at the end.
10817        PackageSetting nonMutatedPs = null;
10818
10819        // We keep references to the derived CPU Abis from settings in oder to reuse
10820        // them in the case where we're not upgrading or booting for the first time.
10821        String primaryCpuAbiFromSettings = null;
10822        String secondaryCpuAbiFromSettings = null;
10823
10824        final PackageParser.Package oldPkg;
10825
10826        // writer
10827        synchronized (mPackages) {
10828            if (pkg.mSharedUserId != null) {
10829                // SIDE EFFECTS; may potentially allocate a new shared user
10830                suid = mSettings.getSharedUserLPw(
10831                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10832                if (DEBUG_PACKAGE_SCANNING) {
10833                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10834                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10835                                + "): packages=" + suid.packages);
10836                }
10837            }
10838
10839            // Check if we are renaming from an original package name.
10840            PackageSetting origPackage = null;
10841            String realName = null;
10842            if (pkg.mOriginalPackages != null) {
10843                // This package may need to be renamed to a previously
10844                // installed name.  Let's check on that...
10845                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10846                if (pkg.mOriginalPackages.contains(renamed)) {
10847                    // This package had originally been installed as the
10848                    // original name, and we have already taken care of
10849                    // transitioning to the new one.  Just update the new
10850                    // one to continue using the old name.
10851                    realName = pkg.mRealPackage;
10852                    if (!pkg.packageName.equals(renamed)) {
10853                        // Callers into this function may have already taken
10854                        // care of renaming the package; only do it here if
10855                        // it is not already done.
10856                        pkg.setPackageName(renamed);
10857                    }
10858                } else {
10859                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10860                        if ((origPackage = mSettings.getPackageLPr(
10861                                pkg.mOriginalPackages.get(i))) != null) {
10862                            // We do have the package already installed under its
10863                            // original name...  should we use it?
10864                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10865                                // New package is not compatible with original.
10866                                origPackage = null;
10867                                continue;
10868                            } else if (origPackage.sharedUser != null) {
10869                                // Make sure uid is compatible between packages.
10870                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10871                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10872                                            + " to " + pkg.packageName + ": old uid "
10873                                            + origPackage.sharedUser.name
10874                                            + " differs from " + pkg.mSharedUserId);
10875                                    origPackage = null;
10876                                    continue;
10877                                }
10878                                // TODO: Add case when shared user id is added [b/28144775]
10879                            } else {
10880                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10881                                        + pkg.packageName + " to old name " + origPackage.name);
10882                            }
10883                            break;
10884                        }
10885                    }
10886                }
10887            }
10888
10889            if (mTransferedPackages.contains(pkg.packageName)) {
10890                Slog.w(TAG, "Package " + pkg.packageName
10891                        + " was transferred to another, but its .apk remains");
10892            }
10893
10894            // See comments in nonMutatedPs declaration
10895            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10896                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10897                if (foundPs != null) {
10898                    nonMutatedPs = new PackageSetting(foundPs);
10899                }
10900            }
10901
10902            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10903                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10904                if (foundPs != null) {
10905                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10906                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10907                }
10908            }
10909
10910            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10911            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10912                PackageManagerService.reportSettingsProblem(Log.WARN,
10913                        "Package " + pkg.packageName + " shared user changed from "
10914                                + (pkgSetting.sharedUser != null
10915                                        ? pkgSetting.sharedUser.name : "<nothing>")
10916                                + " to "
10917                                + (suid != null ? suid.name : "<nothing>")
10918                                + "; replacing with new");
10919                pkgSetting = null;
10920            }
10921            final PackageSetting oldPkgSetting =
10922                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10923            final PackageSetting disabledPkgSetting =
10924                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10925
10926            if (oldPkgSetting == null) {
10927                oldPkg = null;
10928            } else {
10929                oldPkg = oldPkgSetting.pkg;
10930            }
10931
10932            String[] usesStaticLibraries = null;
10933            if (pkg.usesStaticLibraries != null) {
10934                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10935                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10936            }
10937
10938            if (pkgSetting == null) {
10939                final String parentPackageName = (pkg.parentPackage != null)
10940                        ? pkg.parentPackage.packageName : null;
10941                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10942                final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10943                // REMOVE SharedUserSetting from method; update in a separate call
10944                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10945                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10946                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10947                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10948                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10949                        true /*allowInstall*/, instantApp, virtualPreload,
10950                        parentPackageName, pkg.getChildPackageNames(),
10951                        UserManagerService.getInstance(), usesStaticLibraries,
10952                        pkg.usesStaticLibrariesVersions);
10953                // SIDE EFFECTS; updates system state; move elsewhere
10954                if (origPackage != null) {
10955                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10956                }
10957                mSettings.addUserToSettingLPw(pkgSetting);
10958            } else {
10959                // REMOVE SharedUserSetting from method; update in a separate call.
10960                //
10961                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10962                // secondaryCpuAbi are not known at this point so we always update them
10963                // to null here, only to reset them at a later point.
10964                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10965                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10966                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10967                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10968                        UserManagerService.getInstance(), usesStaticLibraries,
10969                        pkg.usesStaticLibrariesVersions);
10970            }
10971            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10972            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10973
10974            // SIDE EFFECTS; modifies system state; move elsewhere
10975            if (pkgSetting.origPackage != null) {
10976                // If we are first transitioning from an original package,
10977                // fix up the new package's name now.  We need to do this after
10978                // looking up the package under its new name, so getPackageLP
10979                // can take care of fiddling things correctly.
10980                pkg.setPackageName(origPackage.name);
10981
10982                // File a report about this.
10983                String msg = "New package " + pkgSetting.realName
10984                        + " renamed to replace old package " + pkgSetting.name;
10985                reportSettingsProblem(Log.WARN, msg);
10986
10987                // Make a note of it.
10988                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10989                    mTransferedPackages.add(origPackage.name);
10990                }
10991
10992                // No longer need to retain this.
10993                pkgSetting.origPackage = null;
10994            }
10995
10996            // SIDE EFFECTS; modifies system state; move elsewhere
10997            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10998                // Make a note of it.
10999                mTransferedPackages.add(pkg.packageName);
11000            }
11001
11002            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
11003                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
11004            }
11005
11006            if ((scanFlags & SCAN_BOOTING) == 0
11007                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11008                // Check all shared libraries and map to their actual file path.
11009                // We only do this here for apps not on a system dir, because those
11010                // are the only ones that can fail an install due to this.  We
11011                // will take care of the system apps by updating all of their
11012                // library paths after the scan is done. Also during the initial
11013                // scan don't update any libs as we do this wholesale after all
11014                // apps are scanned to avoid dependency based scanning.
11015                updateSharedLibrariesLPr(pkg, null);
11016            }
11017
11018            if (mFoundPolicyFile) {
11019                SELinuxMMAC.assignSeInfoValue(pkg);
11020            }
11021            pkg.applicationInfo.uid = pkgSetting.appId;
11022            pkg.mExtras = pkgSetting;
11023
11024
11025            // Static shared libs have same package with different versions where
11026            // we internally use a synthetic package name to allow multiple versions
11027            // of the same package, therefore we need to compare signatures against
11028            // the package setting for the latest library version.
11029            PackageSetting signatureCheckPs = pkgSetting;
11030            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11031                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
11032                if (libraryEntry != null) {
11033                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
11034                }
11035            }
11036
11037            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
11038                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
11039                    // We just determined the app is signed correctly, so bring
11040                    // over the latest parsed certs.
11041                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
11042                } else {
11043                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11044                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
11045                                "Package " + pkg.packageName + " upgrade keys do not match the "
11046                                + "previously installed version");
11047                    } else {
11048                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
11049                        String msg = "System package " + pkg.packageName
11050                                + " signature changed; retaining data.";
11051                        reportSettingsProblem(Log.WARN, msg);
11052                    }
11053                }
11054            } else {
11055                try {
11056                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
11057                    verifySignaturesLP(signatureCheckPs, pkg);
11058                    // We just determined the app is signed correctly, so bring
11059                    // over the latest parsed certs.
11060                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
11061                } catch (PackageManagerException e) {
11062                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11063                        throw e;
11064                    }
11065                    // The signature has changed, but this package is in the system
11066                    // image...  let's recover!
11067                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
11068                    // However...  if this package is part of a shared user, but it
11069                    // doesn't match the signature of the shared user, let's fail.
11070                    // What this means is that you can't change the signatures
11071                    // associated with an overall shared user, which doesn't seem all
11072                    // that unreasonable.
11073                    if (signatureCheckPs.sharedUser != null) {
11074                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
11075                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
11076                            throw new PackageManagerException(
11077                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
11078                                    "Signature mismatch for shared user: "
11079                                            + pkgSetting.sharedUser);
11080                        }
11081                    }
11082                    // File a report about this.
11083                    String msg = "System package " + pkg.packageName
11084                            + " signature changed; retaining data.";
11085                    reportSettingsProblem(Log.WARN, msg);
11086                }
11087            }
11088
11089            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
11090                // This package wants to adopt ownership of permissions from
11091                // another package.
11092                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
11093                    final String origName = pkg.mAdoptPermissions.get(i);
11094                    final PackageSetting orig = mSettings.getPackageLPr(origName);
11095                    if (orig != null) {
11096                        if (verifyPackageUpdateLPr(orig, pkg)) {
11097                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
11098                                    + pkg.packageName);
11099                            // SIDE EFFECTS; updates permissions system state; move elsewhere
11100                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
11101                        }
11102                    }
11103                }
11104            }
11105        }
11106
11107        pkg.applicationInfo.processName = fixProcessName(
11108                pkg.applicationInfo.packageName,
11109                pkg.applicationInfo.processName);
11110
11111        if (pkg != mPlatformPackage) {
11112            // Get all of our default paths setup
11113            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
11114        }
11115
11116        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
11117
11118        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
11119            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
11120                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
11121                final boolean extractNativeLibs = !pkg.isLibrary();
11122                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
11123                        mAppLib32InstallDir);
11124                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11125
11126                // Some system apps still use directory structure for native libraries
11127                // in which case we might end up not detecting abi solely based on apk
11128                // structure. Try to detect abi based on directory structure.
11129                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
11130                        pkg.applicationInfo.primaryCpuAbi == null) {
11131                    setBundledAppAbisAndRoots(pkg, pkgSetting);
11132                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11133                }
11134            } else {
11135                // This is not a first boot or an upgrade, don't bother deriving the
11136                // ABI during the scan. Instead, trust the value that was stored in the
11137                // package setting.
11138                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
11139                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
11140
11141                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11142
11143                if (DEBUG_ABI_SELECTION) {
11144                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11145                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
11146                        pkg.applicationInfo.secondaryCpuAbi);
11147                }
11148            }
11149        } else {
11150            if ((scanFlags & SCAN_MOVE) != 0) {
11151                // We haven't run dex-opt for this move (since we've moved the compiled output too)
11152                // but we already have this packages package info in the PackageSetting. We just
11153                // use that and derive the native library path based on the new codepath.
11154                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
11155                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
11156            }
11157
11158            // Set native library paths again. For moves, the path will be updated based on the
11159            // ABIs we've determined above. For non-moves, the path will be updated based on the
11160            // ABIs we determined during compilation, but the path will depend on the final
11161            // package path (after the rename away from the stage path).
11162            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11163        }
11164
11165        // This is a special case for the "system" package, where the ABI is
11166        // dictated by the zygote configuration (and init.rc). We should keep track
11167        // of this ABI so that we can deal with "normal" applications that run under
11168        // the same UID correctly.
11169        if (mPlatformPackage == pkg) {
11170            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
11171                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
11172        }
11173
11174        // If there's a mismatch between the abi-override in the package setting
11175        // and the abiOverride specified for the install. Warn about this because we
11176        // would've already compiled the app without taking the package setting into
11177        // account.
11178        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11179            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
11180                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11181                        " for package " + pkg.packageName);
11182            }
11183        }
11184
11185        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11186        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11187        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11188
11189        // Copy the derived override back to the parsed package, so that we can
11190        // update the package settings accordingly.
11191        pkg.cpuAbiOverride = cpuAbiOverride;
11192
11193        if (DEBUG_ABI_SELECTION) {
11194            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
11195                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
11196                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
11197        }
11198
11199        // Push the derived path down into PackageSettings so we know what to
11200        // clean up at uninstall time.
11201        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
11202
11203        if (DEBUG_ABI_SELECTION) {
11204            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
11205                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
11206                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
11207        }
11208
11209        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
11210        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11211            // We don't do this here during boot because we can do it all
11212            // at once after scanning all existing packages.
11213            //
11214            // We also do this *before* we perform dexopt on this package, so that
11215            // we can avoid redundant dexopts, and also to make sure we've got the
11216            // code and package path correct.
11217            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
11218        }
11219
11220        if (mFactoryTest && pkg.requestedPermissions.contains(
11221                android.Manifest.permission.FACTORY_TEST)) {
11222            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
11223        }
11224
11225        if (isSystemApp(pkg)) {
11226            pkgSetting.isOrphaned = true;
11227        }
11228
11229        // Take care of first install / last update times.
11230        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
11231        if (currentTime != 0) {
11232            if (pkgSetting.firstInstallTime == 0) {
11233                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11234            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11235                pkgSetting.lastUpdateTime = currentTime;
11236            }
11237        } else if (pkgSetting.firstInstallTime == 0) {
11238            // We need *something*.  Take time time stamp of the file.
11239            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11240        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11241            if (scanFileTime != pkgSetting.timeStamp) {
11242                // A package on the system image has changed; consider this
11243                // to be an update.
11244                pkgSetting.lastUpdateTime = scanFileTime;
11245            }
11246        }
11247        pkgSetting.setTimeStamp(scanFileTime);
11248
11249        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11250            if (nonMutatedPs != null) {
11251                synchronized (mPackages) {
11252                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
11253                }
11254            }
11255        } else {
11256            final int userId = user == null ? 0 : user.getIdentifier();
11257            // Modify state for the given package setting
11258            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
11259                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
11260            if (pkgSetting.getInstantApp(userId)) {
11261                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11262            }
11263        }
11264
11265        if (oldPkg != null) {
11266            // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11267            // revokation from this method might need to kill apps which need the
11268            // mPackages lock on a different thread. This would dead lock.
11269            //
11270            // Hence create a copy of all package names and pass it into
11271            // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11272            // revoked. If a new package is added before the async code runs the permission
11273            // won't be granted yet, hence new packages are no problem.
11274            final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11275
11276            AsyncTask.execute(new Runnable() {
11277                public void run() {
11278                    revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
11279                }
11280            });
11281        }
11282
11283        return pkg;
11284    }
11285
11286    /**
11287     * Applies policy to the parsed package based upon the given policy flags.
11288     * Ensures the package is in a good state.
11289     * <p>
11290     * Implementation detail: This method must NOT have any side effect. It would
11291     * ideally be static, but, it requires locks to read system state.
11292     */
11293    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
11294        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
11295            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11296            if (pkg.applicationInfo.isDirectBootAware()) {
11297                // we're direct boot aware; set for all components
11298                for (PackageParser.Service s : pkg.services) {
11299                    s.info.encryptionAware = s.info.directBootAware = true;
11300                }
11301                for (PackageParser.Provider p : pkg.providers) {
11302                    p.info.encryptionAware = p.info.directBootAware = true;
11303                }
11304                for (PackageParser.Activity a : pkg.activities) {
11305                    a.info.encryptionAware = a.info.directBootAware = true;
11306                }
11307                for (PackageParser.Activity r : pkg.receivers) {
11308                    r.info.encryptionAware = r.info.directBootAware = true;
11309                }
11310            }
11311            if (compressedFileExists(pkg.codePath)) {
11312                pkg.isStub = true;
11313            }
11314        } else {
11315            // Only allow system apps to be flagged as core apps.
11316            pkg.coreApp = false;
11317            // clear flags not applicable to regular apps
11318            pkg.applicationInfo.privateFlags &=
11319                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11320            pkg.applicationInfo.privateFlags &=
11321                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11322        }
11323        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
11324
11325        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
11326            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11327        }
11328
11329        if (!isSystemApp(pkg)) {
11330            // Only system apps can use these features.
11331            pkg.mOriginalPackages = null;
11332            pkg.mRealPackage = null;
11333            pkg.mAdoptPermissions = null;
11334        }
11335    }
11336
11337    /**
11338     * Asserts the parsed package is valid according to the given policy. If the
11339     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11340     * <p>
11341     * Implementation detail: This method must NOT have any side effects. It would
11342     * ideally be static, but, it requires locks to read system state.
11343     *
11344     * @throws PackageManagerException If the package fails any of the validation checks
11345     */
11346    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11347            throws PackageManagerException {
11348        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11349            assertCodePolicy(pkg);
11350        }
11351
11352        if (pkg.applicationInfo.getCodePath() == null ||
11353                pkg.applicationInfo.getResourcePath() == null) {
11354            // Bail out. The resource and code paths haven't been set.
11355            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11356                    "Code and resource paths haven't been set correctly");
11357        }
11358
11359        // Make sure we're not adding any bogus keyset info
11360        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11361        ksms.assertScannedPackageValid(pkg);
11362
11363        synchronized (mPackages) {
11364            // The special "android" package can only be defined once
11365            if (pkg.packageName.equals("android")) {
11366                if (mAndroidApplication != null) {
11367                    Slog.w(TAG, "*************************************************");
11368                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
11369                    Slog.w(TAG, " codePath=" + pkg.codePath);
11370                    Slog.w(TAG, "*************************************************");
11371                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11372                            "Core android package being redefined.  Skipping.");
11373                }
11374            }
11375
11376            // A package name must be unique; don't allow duplicates
11377            if (mPackages.containsKey(pkg.packageName)) {
11378                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11379                        "Application package " + pkg.packageName
11380                        + " already installed.  Skipping duplicate.");
11381            }
11382
11383            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11384                // Static libs have a synthetic package name containing the version
11385                // but we still want the base name to be unique.
11386                if (mPackages.containsKey(pkg.manifestPackageName)) {
11387                    throw new PackageManagerException(
11388                            "Duplicate static shared lib provider package");
11389                }
11390
11391                // Static shared libraries should have at least O target SDK
11392                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11393                    throw new PackageManagerException(
11394                            "Packages declaring static-shared libs must target O SDK or higher");
11395                }
11396
11397                // Package declaring static a shared lib cannot be instant apps
11398                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11399                    throw new PackageManagerException(
11400                            "Packages declaring static-shared libs cannot be instant apps");
11401                }
11402
11403                // Package declaring static a shared lib cannot be renamed since the package
11404                // name is synthetic and apps can't code around package manager internals.
11405                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11406                    throw new PackageManagerException(
11407                            "Packages declaring static-shared libs cannot be renamed");
11408                }
11409
11410                // Package declaring static a shared lib cannot declare child packages
11411                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11412                    throw new PackageManagerException(
11413                            "Packages declaring static-shared libs cannot have child packages");
11414                }
11415
11416                // Package declaring static a shared lib cannot declare dynamic libs
11417                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11418                    throw new PackageManagerException(
11419                            "Packages declaring static-shared libs cannot declare dynamic libs");
11420                }
11421
11422                // Package declaring static a shared lib cannot declare shared users
11423                if (pkg.mSharedUserId != null) {
11424                    throw new PackageManagerException(
11425                            "Packages declaring static-shared libs cannot declare shared users");
11426                }
11427
11428                // Static shared libs cannot declare activities
11429                if (!pkg.activities.isEmpty()) {
11430                    throw new PackageManagerException(
11431                            "Static shared libs cannot declare activities");
11432                }
11433
11434                // Static shared libs cannot declare services
11435                if (!pkg.services.isEmpty()) {
11436                    throw new PackageManagerException(
11437                            "Static shared libs cannot declare services");
11438                }
11439
11440                // Static shared libs cannot declare providers
11441                if (!pkg.providers.isEmpty()) {
11442                    throw new PackageManagerException(
11443                            "Static shared libs cannot declare content providers");
11444                }
11445
11446                // Static shared libs cannot declare receivers
11447                if (!pkg.receivers.isEmpty()) {
11448                    throw new PackageManagerException(
11449                            "Static shared libs cannot declare broadcast receivers");
11450                }
11451
11452                // Static shared libs cannot declare permission groups
11453                if (!pkg.permissionGroups.isEmpty()) {
11454                    throw new PackageManagerException(
11455                            "Static shared libs cannot declare permission groups");
11456                }
11457
11458                // Static shared libs cannot declare permissions
11459                if (!pkg.permissions.isEmpty()) {
11460                    throw new PackageManagerException(
11461                            "Static shared libs cannot declare permissions");
11462                }
11463
11464                // Static shared libs cannot declare protected broadcasts
11465                if (pkg.protectedBroadcasts != null) {
11466                    throw new PackageManagerException(
11467                            "Static shared libs cannot declare protected broadcasts");
11468                }
11469
11470                // Static shared libs cannot be overlay targets
11471                if (pkg.mOverlayTarget != null) {
11472                    throw new PackageManagerException(
11473                            "Static shared libs cannot be overlay targets");
11474                }
11475
11476                // The version codes must be ordered as lib versions
11477                int minVersionCode = Integer.MIN_VALUE;
11478                int maxVersionCode = Integer.MAX_VALUE;
11479
11480                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11481                        pkg.staticSharedLibName);
11482                if (versionedLib != null) {
11483                    final int versionCount = versionedLib.size();
11484                    for (int i = 0; i < versionCount; i++) {
11485                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11486                        final int libVersionCode = libInfo.getDeclaringPackage()
11487                                .getVersionCode();
11488                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11489                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11490                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11491                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11492                        } else {
11493                            minVersionCode = maxVersionCode = libVersionCode;
11494                            break;
11495                        }
11496                    }
11497                }
11498                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11499                    throw new PackageManagerException("Static shared"
11500                            + " lib version codes must be ordered as lib versions");
11501                }
11502            }
11503
11504            // Only privileged apps and updated privileged apps can add child packages.
11505            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11506                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11507                    throw new PackageManagerException("Only privileged apps can add child "
11508                            + "packages. Ignoring package " + pkg.packageName);
11509                }
11510                final int childCount = pkg.childPackages.size();
11511                for (int i = 0; i < childCount; i++) {
11512                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11513                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11514                            childPkg.packageName)) {
11515                        throw new PackageManagerException("Can't override child of "
11516                                + "another disabled app. Ignoring package " + pkg.packageName);
11517                    }
11518                }
11519            }
11520
11521            // If we're only installing presumed-existing packages, require that the
11522            // scanned APK is both already known and at the path previously established
11523            // for it.  Previously unknown packages we pick up normally, but if we have an
11524            // a priori expectation about this package's install presence, enforce it.
11525            // With a singular exception for new system packages. When an OTA contains
11526            // a new system package, we allow the codepath to change from a system location
11527            // to the user-installed location. If we don't allow this change, any newer,
11528            // user-installed version of the application will be ignored.
11529            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11530                if (mExpectingBetter.containsKey(pkg.packageName)) {
11531                    logCriticalInfo(Log.WARN,
11532                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11533                } else {
11534                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11535                    if (known != null) {
11536                        if (DEBUG_PACKAGE_SCANNING) {
11537                            Log.d(TAG, "Examining " + pkg.codePath
11538                                    + " and requiring known paths " + known.codePathString
11539                                    + " & " + known.resourcePathString);
11540                        }
11541                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11542                                || !pkg.applicationInfo.getResourcePath().equals(
11543                                        known.resourcePathString)) {
11544                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11545                                    "Application package " + pkg.packageName
11546                                    + " found at " + pkg.applicationInfo.getCodePath()
11547                                    + " but expected at " + known.codePathString
11548                                    + "; ignoring.");
11549                        }
11550                    } else {
11551                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11552                                "Application package " + pkg.packageName
11553                                + " not found; ignoring.");
11554                    }
11555                }
11556            }
11557
11558            // Verify that this new package doesn't have any content providers
11559            // that conflict with existing packages.  Only do this if the
11560            // package isn't already installed, since we don't want to break
11561            // things that are installed.
11562            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11563                final int N = pkg.providers.size();
11564                int i;
11565                for (i=0; i<N; i++) {
11566                    PackageParser.Provider p = pkg.providers.get(i);
11567                    if (p.info.authority != null) {
11568                        String names[] = p.info.authority.split(";");
11569                        for (int j = 0; j < names.length; j++) {
11570                            if (mProvidersByAuthority.containsKey(names[j])) {
11571                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11572                                final String otherPackageName =
11573                                        ((other != null && other.getComponentName() != null) ?
11574                                                other.getComponentName().getPackageName() : "?");
11575                                throw new PackageManagerException(
11576                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11577                                        "Can't install because provider name " + names[j]
11578                                                + " (in package " + pkg.applicationInfo.packageName
11579                                                + ") is already used by " + otherPackageName);
11580                            }
11581                        }
11582                    }
11583                }
11584            }
11585        }
11586    }
11587
11588    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11589            int type, String declaringPackageName, int declaringVersionCode) {
11590        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11591        if (versionedLib == null) {
11592            versionedLib = new SparseArray<>();
11593            mSharedLibraries.put(name, versionedLib);
11594            if (type == SharedLibraryInfo.TYPE_STATIC) {
11595                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11596            }
11597        } else if (versionedLib.indexOfKey(version) >= 0) {
11598            return false;
11599        }
11600        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11601                version, type, declaringPackageName, declaringVersionCode);
11602        versionedLib.put(version, libEntry);
11603        return true;
11604    }
11605
11606    private boolean removeSharedLibraryLPw(String name, int version) {
11607        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11608        if (versionedLib == null) {
11609            return false;
11610        }
11611        final int libIdx = versionedLib.indexOfKey(version);
11612        if (libIdx < 0) {
11613            return false;
11614        }
11615        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11616        versionedLib.remove(version);
11617        if (versionedLib.size() <= 0) {
11618            mSharedLibraries.remove(name);
11619            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11620                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11621                        .getPackageName());
11622            }
11623        }
11624        return true;
11625    }
11626
11627    /**
11628     * Adds a scanned package to the system. When this method is finished, the package will
11629     * be available for query, resolution, etc...
11630     */
11631    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11632            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11633        final String pkgName = pkg.packageName;
11634        if (mCustomResolverComponentName != null &&
11635                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11636            setUpCustomResolverActivity(pkg);
11637        }
11638
11639        if (pkg.packageName.equals("android")) {
11640            synchronized (mPackages) {
11641                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11642                    // Set up information for our fall-back user intent resolution activity.
11643                    mPlatformPackage = pkg;
11644                    pkg.mVersionCode = mSdkVersion;
11645                    mAndroidApplication = pkg.applicationInfo;
11646                    if (!mResolverReplaced) {
11647                        mResolveActivity.applicationInfo = mAndroidApplication;
11648                        mResolveActivity.name = ResolverActivity.class.getName();
11649                        mResolveActivity.packageName = mAndroidApplication.packageName;
11650                        mResolveActivity.processName = "system:ui";
11651                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11652                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11653                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11654                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11655                        mResolveActivity.exported = true;
11656                        mResolveActivity.enabled = true;
11657                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11658                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11659                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11660                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11661                                | ActivityInfo.CONFIG_ORIENTATION
11662                                | ActivityInfo.CONFIG_KEYBOARD
11663                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11664                        mResolveInfo.activityInfo = mResolveActivity;
11665                        mResolveInfo.priority = 0;
11666                        mResolveInfo.preferredOrder = 0;
11667                        mResolveInfo.match = 0;
11668                        mResolveComponentName = new ComponentName(
11669                                mAndroidApplication.packageName, mResolveActivity.name);
11670                    }
11671                }
11672            }
11673        }
11674
11675        ArrayList<PackageParser.Package> clientLibPkgs = null;
11676        // writer
11677        synchronized (mPackages) {
11678            boolean hasStaticSharedLibs = false;
11679
11680            // Any app can add new static shared libraries
11681            if (pkg.staticSharedLibName != null) {
11682                // Static shared libs don't allow renaming as they have synthetic package
11683                // names to allow install of multiple versions, so use name from manifest.
11684                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11685                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11686                        pkg.manifestPackageName, pkg.mVersionCode)) {
11687                    hasStaticSharedLibs = true;
11688                } else {
11689                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11690                                + pkg.staticSharedLibName + " already exists; skipping");
11691                }
11692                // Static shared libs cannot be updated once installed since they
11693                // use synthetic package name which includes the version code, so
11694                // not need to update other packages's shared lib dependencies.
11695            }
11696
11697            if (!hasStaticSharedLibs
11698                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11699                // Only system apps can add new dynamic shared libraries.
11700                if (pkg.libraryNames != null) {
11701                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11702                        String name = pkg.libraryNames.get(i);
11703                        boolean allowed = false;
11704                        if (pkg.isUpdatedSystemApp()) {
11705                            // New library entries can only be added through the
11706                            // system image.  This is important to get rid of a lot
11707                            // of nasty edge cases: for example if we allowed a non-
11708                            // system update of the app to add a library, then uninstalling
11709                            // the update would make the library go away, and assumptions
11710                            // we made such as through app install filtering would now
11711                            // have allowed apps on the device which aren't compatible
11712                            // with it.  Better to just have the restriction here, be
11713                            // conservative, and create many fewer cases that can negatively
11714                            // impact the user experience.
11715                            final PackageSetting sysPs = mSettings
11716                                    .getDisabledSystemPkgLPr(pkg.packageName);
11717                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11718                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11719                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11720                                        allowed = true;
11721                                        break;
11722                                    }
11723                                }
11724                            }
11725                        } else {
11726                            allowed = true;
11727                        }
11728                        if (allowed) {
11729                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11730                                    SharedLibraryInfo.VERSION_UNDEFINED,
11731                                    SharedLibraryInfo.TYPE_DYNAMIC,
11732                                    pkg.packageName, pkg.mVersionCode)) {
11733                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11734                                        + name + " already exists; skipping");
11735                            }
11736                        } else {
11737                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11738                                    + name + " that is not declared on system image; skipping");
11739                        }
11740                    }
11741
11742                    if ((scanFlags & SCAN_BOOTING) == 0) {
11743                        // If we are not booting, we need to update any applications
11744                        // that are clients of our shared library.  If we are booting,
11745                        // this will all be done once the scan is complete.
11746                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11747                    }
11748                }
11749            }
11750        }
11751
11752        if ((scanFlags & SCAN_BOOTING) != 0) {
11753            // No apps can run during boot scan, so they don't need to be frozen
11754        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11755            // Caller asked to not kill app, so it's probably not frozen
11756        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11757            // Caller asked us to ignore frozen check for some reason; they
11758            // probably didn't know the package name
11759        } else {
11760            // We're doing major surgery on this package, so it better be frozen
11761            // right now to keep it from launching
11762            checkPackageFrozen(pkgName);
11763        }
11764
11765        // Also need to kill any apps that are dependent on the library.
11766        if (clientLibPkgs != null) {
11767            for (int i=0; i<clientLibPkgs.size(); i++) {
11768                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11769                killApplication(clientPkg.applicationInfo.packageName,
11770                        clientPkg.applicationInfo.uid, "update lib");
11771            }
11772        }
11773
11774        // writer
11775        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11776
11777        synchronized (mPackages) {
11778            // We don't expect installation to fail beyond this point
11779
11780            // Add the new setting to mSettings
11781            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11782            // Add the new setting to mPackages
11783            mPackages.put(pkg.applicationInfo.packageName, pkg);
11784            // Make sure we don't accidentally delete its data.
11785            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11786            while (iter.hasNext()) {
11787                PackageCleanItem item = iter.next();
11788                if (pkgName.equals(item.packageName)) {
11789                    iter.remove();
11790                }
11791            }
11792
11793            // Add the package's KeySets to the global KeySetManagerService
11794            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11795            ksms.addScannedPackageLPw(pkg);
11796
11797            int N = pkg.providers.size();
11798            StringBuilder r = null;
11799            int i;
11800            for (i=0; i<N; i++) {
11801                PackageParser.Provider p = pkg.providers.get(i);
11802                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11803                        p.info.processName);
11804                mProviders.addProvider(p);
11805                p.syncable = p.info.isSyncable;
11806                if (p.info.authority != null) {
11807                    String names[] = p.info.authority.split(";");
11808                    p.info.authority = null;
11809                    for (int j = 0; j < names.length; j++) {
11810                        if (j == 1 && p.syncable) {
11811                            // We only want the first authority for a provider to possibly be
11812                            // syncable, so if we already added this provider using a different
11813                            // authority clear the syncable flag. We copy the provider before
11814                            // changing it because the mProviders object contains a reference
11815                            // to a provider that we don't want to change.
11816                            // Only do this for the second authority since the resulting provider
11817                            // object can be the same for all future authorities for this provider.
11818                            p = new PackageParser.Provider(p);
11819                            p.syncable = false;
11820                        }
11821                        if (!mProvidersByAuthority.containsKey(names[j])) {
11822                            mProvidersByAuthority.put(names[j], p);
11823                            if (p.info.authority == null) {
11824                                p.info.authority = names[j];
11825                            } else {
11826                                p.info.authority = p.info.authority + ";" + names[j];
11827                            }
11828                            if (DEBUG_PACKAGE_SCANNING) {
11829                                if (chatty)
11830                                    Log.d(TAG, "Registered content provider: " + names[j]
11831                                            + ", className = " + p.info.name + ", isSyncable = "
11832                                            + p.info.isSyncable);
11833                            }
11834                        } else {
11835                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11836                            Slog.w(TAG, "Skipping provider name " + names[j] +
11837                                    " (in package " + pkg.applicationInfo.packageName +
11838                                    "): name already used by "
11839                                    + ((other != null && other.getComponentName() != null)
11840                                            ? other.getComponentName().getPackageName() : "?"));
11841                        }
11842                    }
11843                }
11844                if (chatty) {
11845                    if (r == null) {
11846                        r = new StringBuilder(256);
11847                    } else {
11848                        r.append(' ');
11849                    }
11850                    r.append(p.info.name);
11851                }
11852            }
11853            if (r != null) {
11854                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11855            }
11856
11857            N = pkg.services.size();
11858            r = null;
11859            for (i=0; i<N; i++) {
11860                PackageParser.Service s = pkg.services.get(i);
11861                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11862                        s.info.processName);
11863                mServices.addService(s);
11864                if (chatty) {
11865                    if (r == null) {
11866                        r = new StringBuilder(256);
11867                    } else {
11868                        r.append(' ');
11869                    }
11870                    r.append(s.info.name);
11871                }
11872            }
11873            if (r != null) {
11874                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11875            }
11876
11877            N = pkg.receivers.size();
11878            r = null;
11879            for (i=0; i<N; i++) {
11880                PackageParser.Activity a = pkg.receivers.get(i);
11881                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11882                        a.info.processName);
11883                mReceivers.addActivity(a, "receiver");
11884                if (chatty) {
11885                    if (r == null) {
11886                        r = new StringBuilder(256);
11887                    } else {
11888                        r.append(' ');
11889                    }
11890                    r.append(a.info.name);
11891                }
11892            }
11893            if (r != null) {
11894                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11895            }
11896
11897            N = pkg.activities.size();
11898            r = null;
11899            for (i=0; i<N; i++) {
11900                PackageParser.Activity a = pkg.activities.get(i);
11901                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11902                        a.info.processName);
11903                mActivities.addActivity(a, "activity");
11904                if (chatty) {
11905                    if (r == null) {
11906                        r = new StringBuilder(256);
11907                    } else {
11908                        r.append(' ');
11909                    }
11910                    r.append(a.info.name);
11911                }
11912            }
11913            if (r != null) {
11914                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11915            }
11916
11917            N = pkg.permissionGroups.size();
11918            r = null;
11919            for (i=0; i<N; i++) {
11920                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11921                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11922                final String curPackageName = cur == null ? null : cur.info.packageName;
11923                // Dont allow ephemeral apps to define new permission groups.
11924                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11925                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11926                            + pg.info.packageName
11927                            + " ignored: instant apps cannot define new permission groups.");
11928                    continue;
11929                }
11930                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11931                if (cur == null || isPackageUpdate) {
11932                    mPermissionGroups.put(pg.info.name, pg);
11933                    if (chatty) {
11934                        if (r == null) {
11935                            r = new StringBuilder(256);
11936                        } else {
11937                            r.append(' ');
11938                        }
11939                        if (isPackageUpdate) {
11940                            r.append("UPD:");
11941                        }
11942                        r.append(pg.info.name);
11943                    }
11944                } else {
11945                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11946                            + pg.info.packageName + " ignored: original from "
11947                            + cur.info.packageName);
11948                    if (chatty) {
11949                        if (r == null) {
11950                            r = new StringBuilder(256);
11951                        } else {
11952                            r.append(' ');
11953                        }
11954                        r.append("DUP:");
11955                        r.append(pg.info.name);
11956                    }
11957                }
11958            }
11959            if (r != null) {
11960                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11961            }
11962
11963            N = pkg.permissions.size();
11964            r = null;
11965            for (i=0; i<N; i++) {
11966                PackageParser.Permission p = pkg.permissions.get(i);
11967
11968                // Dont allow ephemeral apps to define new permissions.
11969                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11970                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11971                            + p.info.packageName
11972                            + " ignored: instant apps cannot define new permissions.");
11973                    continue;
11974                }
11975
11976                // Assume by default that we did not install this permission into the system.
11977                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11978
11979                // Now that permission groups have a special meaning, we ignore permission
11980                // groups for legacy apps to prevent unexpected behavior. In particular,
11981                // permissions for one app being granted to someone just because they happen
11982                // to be in a group defined by another app (before this had no implications).
11983                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11984                    p.group = mPermissionGroups.get(p.info.group);
11985                    // Warn for a permission in an unknown group.
11986                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11987                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11988                                + p.info.packageName + " in an unknown group " + p.info.group);
11989                    }
11990                }
11991
11992                ArrayMap<String, BasePermission> permissionMap =
11993                        p.tree ? mSettings.mPermissionTrees
11994                                : mSettings.mPermissions;
11995                BasePermission bp = permissionMap.get(p.info.name);
11996
11997                // Allow system apps to redefine non-system permissions
11998                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11999                    final boolean currentOwnerIsSystem = (bp.perm != null
12000                            && isSystemApp(bp.perm.owner));
12001                    if (isSystemApp(p.owner)) {
12002                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
12003                            // It's a built-in permission and no owner, take ownership now
12004                            bp.packageSetting = pkgSetting;
12005                            bp.perm = p;
12006                            bp.uid = pkg.applicationInfo.uid;
12007                            bp.sourcePackage = p.info.packageName;
12008                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12009                        } else if (!currentOwnerIsSystem) {
12010                            String msg = "New decl " + p.owner + " of permission  "
12011                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
12012                            reportSettingsProblem(Log.WARN, msg);
12013                            bp = null;
12014                        }
12015                    }
12016                }
12017
12018                if (bp == null) {
12019                    bp = new BasePermission(p.info.name, p.info.packageName,
12020                            BasePermission.TYPE_NORMAL);
12021                    permissionMap.put(p.info.name, bp);
12022                }
12023
12024                if (bp.perm == null) {
12025                    if (bp.sourcePackage == null
12026                            || bp.sourcePackage.equals(p.info.packageName)) {
12027                        BasePermission tree = findPermissionTreeLP(p.info.name);
12028                        if (tree == null
12029                                || tree.sourcePackage.equals(p.info.packageName)) {
12030                            bp.packageSetting = pkgSetting;
12031                            bp.perm = p;
12032                            bp.uid = pkg.applicationInfo.uid;
12033                            bp.sourcePackage = p.info.packageName;
12034                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
12035                            if (chatty) {
12036                                if (r == null) {
12037                                    r = new StringBuilder(256);
12038                                } else {
12039                                    r.append(' ');
12040                                }
12041                                r.append(p.info.name);
12042                            }
12043                        } else {
12044                            Slog.w(TAG, "Permission " + p.info.name + " from package "
12045                                    + p.info.packageName + " ignored: base tree "
12046                                    + tree.name + " is from package "
12047                                    + tree.sourcePackage);
12048                        }
12049                    } else {
12050                        Slog.w(TAG, "Permission " + p.info.name + " from package "
12051                                + p.info.packageName + " ignored: original from "
12052                                + bp.sourcePackage);
12053                    }
12054                } else if (chatty) {
12055                    if (r == null) {
12056                        r = new StringBuilder(256);
12057                    } else {
12058                        r.append(' ');
12059                    }
12060                    r.append("DUP:");
12061                    r.append(p.info.name);
12062                }
12063                if (bp.perm == p) {
12064                    bp.protectionLevel = p.info.protectionLevel;
12065                }
12066            }
12067
12068            if (r != null) {
12069                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
12070            }
12071
12072            N = pkg.instrumentation.size();
12073            r = null;
12074            for (i=0; i<N; i++) {
12075                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12076                a.info.packageName = pkg.applicationInfo.packageName;
12077                a.info.sourceDir = pkg.applicationInfo.sourceDir;
12078                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
12079                a.info.splitNames = pkg.splitNames;
12080                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
12081                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
12082                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
12083                a.info.dataDir = pkg.applicationInfo.dataDir;
12084                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
12085                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
12086                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
12087                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
12088                mInstrumentation.put(a.getComponentName(), a);
12089                if (chatty) {
12090                    if (r == null) {
12091                        r = new StringBuilder(256);
12092                    } else {
12093                        r.append(' ');
12094                    }
12095                    r.append(a.info.name);
12096                }
12097            }
12098            if (r != null) {
12099                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
12100            }
12101
12102            if (pkg.protectedBroadcasts != null) {
12103                N = pkg.protectedBroadcasts.size();
12104                synchronized (mProtectedBroadcasts) {
12105                    for (i = 0; i < N; i++) {
12106                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
12107                    }
12108                }
12109            }
12110        }
12111
12112        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12113    }
12114
12115    /**
12116     * Derive the ABI of a non-system package located at {@code scanFile}. This information
12117     * is derived purely on the basis of the contents of {@code scanFile} and
12118     * {@code cpuAbiOverride}.
12119     *
12120     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
12121     */
12122    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
12123                                 String cpuAbiOverride, boolean extractLibs,
12124                                 File appLib32InstallDir)
12125            throws PackageManagerException {
12126        // Give ourselves some initial paths; we'll come back for another
12127        // pass once we've determined ABI below.
12128        setNativeLibraryPaths(pkg, appLib32InstallDir);
12129
12130        // We would never need to extract libs for forward-locked and external packages,
12131        // since the container service will do it for us. We shouldn't attempt to
12132        // extract libs from system app when it was not updated.
12133        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
12134                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
12135            extractLibs = false;
12136        }
12137
12138        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
12139        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
12140
12141        NativeLibraryHelper.Handle handle = null;
12142        try {
12143            handle = NativeLibraryHelper.Handle.create(pkg);
12144            // TODO(multiArch): This can be null for apps that didn't go through the
12145            // usual installation process. We can calculate it again, like we
12146            // do during install time.
12147            //
12148            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
12149            // unnecessary.
12150            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
12151
12152            // Null out the abis so that they can be recalculated.
12153            pkg.applicationInfo.primaryCpuAbi = null;
12154            pkg.applicationInfo.secondaryCpuAbi = null;
12155            if (isMultiArch(pkg.applicationInfo)) {
12156                // Warn if we've set an abiOverride for multi-lib packages..
12157                // By definition, we need to copy both 32 and 64 bit libraries for
12158                // such packages.
12159                if (pkg.cpuAbiOverride != null
12160                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
12161                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
12162                }
12163
12164                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
12165                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
12166                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
12167                    if (extractLibs) {
12168                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12169                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12170                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
12171                                useIsaSpecificSubdirs);
12172                    } else {
12173                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12174                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
12175                    }
12176                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12177                }
12178
12179                // Shared library native code should be in the APK zip aligned
12180                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
12181                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12182                            "Shared library native lib extraction not supported");
12183                }
12184
12185                maybeThrowExceptionForMultiArchCopy(
12186                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
12187
12188                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
12189                    if (extractLibs) {
12190                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12191                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12192                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
12193                                useIsaSpecificSubdirs);
12194                    } else {
12195                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12196                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
12197                    }
12198                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12199                }
12200
12201                maybeThrowExceptionForMultiArchCopy(
12202                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
12203
12204                if (abi64 >= 0) {
12205                    // Shared library native libs should be in the APK zip aligned
12206                    if (extractLibs && pkg.isLibrary()) {
12207                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12208                                "Shared library native lib extraction not supported");
12209                    }
12210                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
12211                }
12212
12213                if (abi32 >= 0) {
12214                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
12215                    if (abi64 >= 0) {
12216                        if (pkg.use32bitAbi) {
12217                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12218                            pkg.applicationInfo.primaryCpuAbi = abi;
12219                        } else {
12220                            pkg.applicationInfo.secondaryCpuAbi = abi;
12221                        }
12222                    } else {
12223                        pkg.applicationInfo.primaryCpuAbi = abi;
12224                    }
12225                }
12226            } else {
12227                String[] abiList = (cpuAbiOverride != null) ?
12228                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
12229
12230                // Enable gross and lame hacks for apps that are built with old
12231                // SDK tools. We must scan their APKs for renderscript bitcode and
12232                // not launch them if it's present. Don't bother checking on devices
12233                // that don't have 64 bit support.
12234                boolean needsRenderScriptOverride = false;
12235                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
12236                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
12237                    abiList = Build.SUPPORTED_32_BIT_ABIS;
12238                    needsRenderScriptOverride = true;
12239                }
12240
12241                final int copyRet;
12242                if (extractLibs) {
12243                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12244                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12245                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
12246                } else {
12247                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12248                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
12249                }
12250                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12251
12252                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
12253                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12254                            "Error unpackaging native libs for app, errorCode=" + copyRet);
12255                }
12256
12257                if (copyRet >= 0) {
12258                    // Shared libraries that have native libs must be multi-architecture
12259                    if (pkg.isLibrary()) {
12260                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12261                                "Shared library with native libs must be multiarch");
12262                    }
12263                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
12264                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
12265                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
12266                } else if (needsRenderScriptOverride) {
12267                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
12268                }
12269            }
12270        } catch (IOException ioe) {
12271            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
12272        } finally {
12273            IoUtils.closeQuietly(handle);
12274        }
12275
12276        // Now that we've calculated the ABIs and determined if it's an internal app,
12277        // we will go ahead and populate the nativeLibraryPath.
12278        setNativeLibraryPaths(pkg, appLib32InstallDir);
12279    }
12280
12281    /**
12282     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
12283     * i.e, so that all packages can be run inside a single process if required.
12284     *
12285     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
12286     * this function will either try and make the ABI for all packages in {@code packagesForUser}
12287     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
12288     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
12289     * updating a package that belongs to a shared user.
12290     *
12291     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
12292     * adds unnecessary complexity.
12293     */
12294    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
12295            PackageParser.Package scannedPackage) {
12296        String requiredInstructionSet = null;
12297        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
12298            requiredInstructionSet = VMRuntime.getInstructionSet(
12299                     scannedPackage.applicationInfo.primaryCpuAbi);
12300        }
12301
12302        PackageSetting requirer = null;
12303        for (PackageSetting ps : packagesForUser) {
12304            // If packagesForUser contains scannedPackage, we skip it. This will happen
12305            // when scannedPackage is an update of an existing package. Without this check,
12306            // we will never be able to change the ABI of any package belonging to a shared
12307            // user, even if it's compatible with other packages.
12308            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12309                if (ps.primaryCpuAbiString == null) {
12310                    continue;
12311                }
12312
12313                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
12314                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12315                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
12316                    // this but there's not much we can do.
12317                    String errorMessage = "Instruction set mismatch, "
12318                            + ((requirer == null) ? "[caller]" : requirer)
12319                            + " requires " + requiredInstructionSet + " whereas " + ps
12320                            + " requires " + instructionSet;
12321                    Slog.w(TAG, errorMessage);
12322                }
12323
12324                if (requiredInstructionSet == null) {
12325                    requiredInstructionSet = instructionSet;
12326                    requirer = ps;
12327                }
12328            }
12329        }
12330
12331        if (requiredInstructionSet != null) {
12332            String adjustedAbi;
12333            if (requirer != null) {
12334                // requirer != null implies that either scannedPackage was null or that scannedPackage
12335                // did not require an ABI, in which case we have to adjust scannedPackage to match
12336                // the ABI of the set (which is the same as requirer's ABI)
12337                adjustedAbi = requirer.primaryCpuAbiString;
12338                if (scannedPackage != null) {
12339                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12340                }
12341            } else {
12342                // requirer == null implies that we're updating all ABIs in the set to
12343                // match scannedPackage.
12344                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
12345            }
12346
12347            for (PackageSetting ps : packagesForUser) {
12348                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12349                    if (ps.primaryCpuAbiString != null) {
12350                        continue;
12351                    }
12352
12353                    ps.primaryCpuAbiString = adjustedAbi;
12354                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12355                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12356                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12357                        if (DEBUG_ABI_SELECTION) {
12358                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12359                                    + " (requirer="
12360                                    + (requirer != null ? requirer.pkg : "null")
12361                                    + ", scannedPackage="
12362                                    + (scannedPackage != null ? scannedPackage : "null")
12363                                    + ")");
12364                        }
12365                        try {
12366                            mInstaller.rmdex(ps.codePathString,
12367                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
12368                        } catch (InstallerException ignored) {
12369                        }
12370                    }
12371                }
12372            }
12373        }
12374    }
12375
12376    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12377        synchronized (mPackages) {
12378            mResolverReplaced = true;
12379            // Set up information for custom user intent resolution activity.
12380            mResolveActivity.applicationInfo = pkg.applicationInfo;
12381            mResolveActivity.name = mCustomResolverComponentName.getClassName();
12382            mResolveActivity.packageName = pkg.applicationInfo.packageName;
12383            mResolveActivity.processName = pkg.applicationInfo.packageName;
12384            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12385            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12386                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12387            mResolveActivity.theme = 0;
12388            mResolveActivity.exported = true;
12389            mResolveActivity.enabled = true;
12390            mResolveInfo.activityInfo = mResolveActivity;
12391            mResolveInfo.priority = 0;
12392            mResolveInfo.preferredOrder = 0;
12393            mResolveInfo.match = 0;
12394            mResolveComponentName = mCustomResolverComponentName;
12395            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12396                    mResolveComponentName);
12397        }
12398    }
12399
12400    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12401        if (installerActivity == null) {
12402            if (DEBUG_EPHEMERAL) {
12403                Slog.d(TAG, "Clear ephemeral installer activity");
12404            }
12405            mInstantAppInstallerActivity = null;
12406            return;
12407        }
12408
12409        if (DEBUG_EPHEMERAL) {
12410            Slog.d(TAG, "Set ephemeral installer activity: "
12411                    + installerActivity.getComponentName());
12412        }
12413        // Set up information for ephemeral installer activity
12414        mInstantAppInstallerActivity = installerActivity;
12415        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12416                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12417        mInstantAppInstallerActivity.exported = true;
12418        mInstantAppInstallerActivity.enabled = true;
12419        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12420        mInstantAppInstallerInfo.priority = 0;
12421        mInstantAppInstallerInfo.preferredOrder = 1;
12422        mInstantAppInstallerInfo.isDefault = true;
12423        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12424                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12425    }
12426
12427    private static String calculateBundledApkRoot(final String codePathString) {
12428        final File codePath = new File(codePathString);
12429        final File codeRoot;
12430        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12431            codeRoot = Environment.getRootDirectory();
12432        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12433            codeRoot = Environment.getOemDirectory();
12434        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12435            codeRoot = Environment.getVendorDirectory();
12436        } else {
12437            // Unrecognized code path; take its top real segment as the apk root:
12438            // e.g. /something/app/blah.apk => /something
12439            try {
12440                File f = codePath.getCanonicalFile();
12441                File parent = f.getParentFile();    // non-null because codePath is a file
12442                File tmp;
12443                while ((tmp = parent.getParentFile()) != null) {
12444                    f = parent;
12445                    parent = tmp;
12446                }
12447                codeRoot = f;
12448                Slog.w(TAG, "Unrecognized code path "
12449                        + codePath + " - using " + codeRoot);
12450            } catch (IOException e) {
12451                // Can't canonicalize the code path -- shenanigans?
12452                Slog.w(TAG, "Can't canonicalize code path " + codePath);
12453                return Environment.getRootDirectory().getPath();
12454            }
12455        }
12456        return codeRoot.getPath();
12457    }
12458
12459    /**
12460     * Derive and set the location of native libraries for the given package,
12461     * which varies depending on where and how the package was installed.
12462     */
12463    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12464        final ApplicationInfo info = pkg.applicationInfo;
12465        final String codePath = pkg.codePath;
12466        final File codeFile = new File(codePath);
12467        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12468        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12469
12470        info.nativeLibraryRootDir = null;
12471        info.nativeLibraryRootRequiresIsa = false;
12472        info.nativeLibraryDir = null;
12473        info.secondaryNativeLibraryDir = null;
12474
12475        if (isApkFile(codeFile)) {
12476            // Monolithic install
12477            if (bundledApp) {
12478                // If "/system/lib64/apkname" exists, assume that is the per-package
12479                // native library directory to use; otherwise use "/system/lib/apkname".
12480                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12481                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12482                        getPrimaryInstructionSet(info));
12483
12484                // This is a bundled system app so choose the path based on the ABI.
12485                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12486                // is just the default path.
12487                final String apkName = deriveCodePathName(codePath);
12488                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12489                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12490                        apkName).getAbsolutePath();
12491
12492                if (info.secondaryCpuAbi != null) {
12493                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12494                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12495                            secondaryLibDir, apkName).getAbsolutePath();
12496                }
12497            } else if (asecApp) {
12498                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12499                        .getAbsolutePath();
12500            } else {
12501                final String apkName = deriveCodePathName(codePath);
12502                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12503                        .getAbsolutePath();
12504            }
12505
12506            info.nativeLibraryRootRequiresIsa = false;
12507            info.nativeLibraryDir = info.nativeLibraryRootDir;
12508        } else {
12509            // Cluster install
12510            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12511            info.nativeLibraryRootRequiresIsa = true;
12512
12513            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12514                    getPrimaryInstructionSet(info)).getAbsolutePath();
12515
12516            if (info.secondaryCpuAbi != null) {
12517                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12518                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12519            }
12520        }
12521    }
12522
12523    /**
12524     * Calculate the abis and roots for a bundled app. These can uniquely
12525     * be determined from the contents of the system partition, i.e whether
12526     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12527     * of this information, and instead assume that the system was built
12528     * sensibly.
12529     */
12530    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12531                                           PackageSetting pkgSetting) {
12532        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12533
12534        // If "/system/lib64/apkname" exists, assume that is the per-package
12535        // native library directory to use; otherwise use "/system/lib/apkname".
12536        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12537        setBundledAppAbi(pkg, apkRoot, apkName);
12538        // pkgSetting might be null during rescan following uninstall of updates
12539        // to a bundled app, so accommodate that possibility.  The settings in
12540        // that case will be established later from the parsed package.
12541        //
12542        // If the settings aren't null, sync them up with what we've just derived.
12543        // note that apkRoot isn't stored in the package settings.
12544        if (pkgSetting != null) {
12545            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12546            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12547        }
12548    }
12549
12550    /**
12551     * Deduces the ABI of a bundled app and sets the relevant fields on the
12552     * parsed pkg object.
12553     *
12554     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12555     *        under which system libraries are installed.
12556     * @param apkName the name of the installed package.
12557     */
12558    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12559        final File codeFile = new File(pkg.codePath);
12560
12561        final boolean has64BitLibs;
12562        final boolean has32BitLibs;
12563        if (isApkFile(codeFile)) {
12564            // Monolithic install
12565            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12566            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12567        } else {
12568            // Cluster install
12569            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12570            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12571                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12572                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12573                has64BitLibs = (new File(rootDir, isa)).exists();
12574            } else {
12575                has64BitLibs = false;
12576            }
12577            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12578                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12579                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12580                has32BitLibs = (new File(rootDir, isa)).exists();
12581            } else {
12582                has32BitLibs = false;
12583            }
12584        }
12585
12586        if (has64BitLibs && !has32BitLibs) {
12587            // The package has 64 bit libs, but not 32 bit libs. Its primary
12588            // ABI should be 64 bit. We can safely assume here that the bundled
12589            // native libraries correspond to the most preferred ABI in the list.
12590
12591            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12592            pkg.applicationInfo.secondaryCpuAbi = null;
12593        } else if (has32BitLibs && !has64BitLibs) {
12594            // The package has 32 bit libs but not 64 bit libs. Its primary
12595            // ABI should be 32 bit.
12596
12597            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12598            pkg.applicationInfo.secondaryCpuAbi = null;
12599        } else if (has32BitLibs && has64BitLibs) {
12600            // The application has both 64 and 32 bit bundled libraries. We check
12601            // here that the app declares multiArch support, and warn if it doesn't.
12602            //
12603            // We will be lenient here and record both ABIs. The primary will be the
12604            // ABI that's higher on the list, i.e, a device that's configured to prefer
12605            // 64 bit apps will see a 64 bit primary ABI,
12606
12607            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12608                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12609            }
12610
12611            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12612                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12613                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12614            } else {
12615                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12616                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12617            }
12618        } else {
12619            pkg.applicationInfo.primaryCpuAbi = null;
12620            pkg.applicationInfo.secondaryCpuAbi = null;
12621        }
12622    }
12623
12624    private void killApplication(String pkgName, int appId, String reason) {
12625        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12626    }
12627
12628    private void killApplication(String pkgName, int appId, int userId, String reason) {
12629        // Request the ActivityManager to kill the process(only for existing packages)
12630        // so that we do not end up in a confused state while the user is still using the older
12631        // version of the application while the new one gets installed.
12632        final long token = Binder.clearCallingIdentity();
12633        try {
12634            IActivityManager am = ActivityManager.getService();
12635            if (am != null) {
12636                try {
12637                    am.killApplication(pkgName, appId, userId, reason);
12638                } catch (RemoteException e) {
12639                }
12640            }
12641        } finally {
12642            Binder.restoreCallingIdentity(token);
12643        }
12644    }
12645
12646    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12647        // Remove the parent package setting
12648        PackageSetting ps = (PackageSetting) pkg.mExtras;
12649        if (ps != null) {
12650            removePackageLI(ps, chatty);
12651        }
12652        // Remove the child package setting
12653        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12654        for (int i = 0; i < childCount; i++) {
12655            PackageParser.Package childPkg = pkg.childPackages.get(i);
12656            ps = (PackageSetting) childPkg.mExtras;
12657            if (ps != null) {
12658                removePackageLI(ps, chatty);
12659            }
12660        }
12661    }
12662
12663    void removePackageLI(PackageSetting ps, boolean chatty) {
12664        if (DEBUG_INSTALL) {
12665            if (chatty)
12666                Log.d(TAG, "Removing package " + ps.name);
12667        }
12668
12669        // writer
12670        synchronized (mPackages) {
12671            mPackages.remove(ps.name);
12672            final PackageParser.Package pkg = ps.pkg;
12673            if (pkg != null) {
12674                cleanPackageDataStructuresLILPw(pkg, chatty);
12675            }
12676        }
12677    }
12678
12679    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12680        if (DEBUG_INSTALL) {
12681            if (chatty)
12682                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12683        }
12684
12685        // writer
12686        synchronized (mPackages) {
12687            // Remove the parent package
12688            mPackages.remove(pkg.applicationInfo.packageName);
12689            cleanPackageDataStructuresLILPw(pkg, chatty);
12690
12691            // Remove the child packages
12692            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12693            for (int i = 0; i < childCount; i++) {
12694                PackageParser.Package childPkg = pkg.childPackages.get(i);
12695                mPackages.remove(childPkg.applicationInfo.packageName);
12696                cleanPackageDataStructuresLILPw(childPkg, chatty);
12697            }
12698        }
12699    }
12700
12701    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12702        int N = pkg.providers.size();
12703        StringBuilder r = null;
12704        int i;
12705        for (i=0; i<N; i++) {
12706            PackageParser.Provider p = pkg.providers.get(i);
12707            mProviders.removeProvider(p);
12708            if (p.info.authority == null) {
12709
12710                /* There was another ContentProvider with this authority when
12711                 * this app was installed so this authority is null,
12712                 * Ignore it as we don't have to unregister the provider.
12713                 */
12714                continue;
12715            }
12716            String names[] = p.info.authority.split(";");
12717            for (int j = 0; j < names.length; j++) {
12718                if (mProvidersByAuthority.get(names[j]) == p) {
12719                    mProvidersByAuthority.remove(names[j]);
12720                    if (DEBUG_REMOVE) {
12721                        if (chatty)
12722                            Log.d(TAG, "Unregistered content provider: " + names[j]
12723                                    + ", className = " + p.info.name + ", isSyncable = "
12724                                    + p.info.isSyncable);
12725                    }
12726                }
12727            }
12728            if (DEBUG_REMOVE && chatty) {
12729                if (r == null) {
12730                    r = new StringBuilder(256);
12731                } else {
12732                    r.append(' ');
12733                }
12734                r.append(p.info.name);
12735            }
12736        }
12737        if (r != null) {
12738            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12739        }
12740
12741        N = pkg.services.size();
12742        r = null;
12743        for (i=0; i<N; i++) {
12744            PackageParser.Service s = pkg.services.get(i);
12745            mServices.removeService(s);
12746            if (chatty) {
12747                if (r == null) {
12748                    r = new StringBuilder(256);
12749                } else {
12750                    r.append(' ');
12751                }
12752                r.append(s.info.name);
12753            }
12754        }
12755        if (r != null) {
12756            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12757        }
12758
12759        N = pkg.receivers.size();
12760        r = null;
12761        for (i=0; i<N; i++) {
12762            PackageParser.Activity a = pkg.receivers.get(i);
12763            mReceivers.removeActivity(a, "receiver");
12764            if (DEBUG_REMOVE && chatty) {
12765                if (r == null) {
12766                    r = new StringBuilder(256);
12767                } else {
12768                    r.append(' ');
12769                }
12770                r.append(a.info.name);
12771            }
12772        }
12773        if (r != null) {
12774            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12775        }
12776
12777        N = pkg.activities.size();
12778        r = null;
12779        for (i=0; i<N; i++) {
12780            PackageParser.Activity a = pkg.activities.get(i);
12781            mActivities.removeActivity(a, "activity");
12782            if (DEBUG_REMOVE && chatty) {
12783                if (r == null) {
12784                    r = new StringBuilder(256);
12785                } else {
12786                    r.append(' ');
12787                }
12788                r.append(a.info.name);
12789            }
12790        }
12791        if (r != null) {
12792            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12793        }
12794
12795        N = pkg.permissions.size();
12796        r = null;
12797        for (i=0; i<N; i++) {
12798            PackageParser.Permission p = pkg.permissions.get(i);
12799            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12800            if (bp == null) {
12801                bp = mSettings.mPermissionTrees.get(p.info.name);
12802            }
12803            if (bp != null && bp.perm == p) {
12804                bp.perm = null;
12805                if (DEBUG_REMOVE && chatty) {
12806                    if (r == null) {
12807                        r = new StringBuilder(256);
12808                    } else {
12809                        r.append(' ');
12810                    }
12811                    r.append(p.info.name);
12812                }
12813            }
12814            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12815                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12816                if (appOpPkgs != null) {
12817                    appOpPkgs.remove(pkg.packageName);
12818                }
12819            }
12820        }
12821        if (r != null) {
12822            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12823        }
12824
12825        N = pkg.requestedPermissions.size();
12826        r = null;
12827        for (i=0; i<N; i++) {
12828            String perm = pkg.requestedPermissions.get(i);
12829            BasePermission bp = mSettings.mPermissions.get(perm);
12830            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12831                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12832                if (appOpPkgs != null) {
12833                    appOpPkgs.remove(pkg.packageName);
12834                    if (appOpPkgs.isEmpty()) {
12835                        mAppOpPermissionPackages.remove(perm);
12836                    }
12837                }
12838            }
12839        }
12840        if (r != null) {
12841            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12842        }
12843
12844        N = pkg.instrumentation.size();
12845        r = null;
12846        for (i=0; i<N; i++) {
12847            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12848            mInstrumentation.remove(a.getComponentName());
12849            if (DEBUG_REMOVE && chatty) {
12850                if (r == null) {
12851                    r = new StringBuilder(256);
12852                } else {
12853                    r.append(' ');
12854                }
12855                r.append(a.info.name);
12856            }
12857        }
12858        if (r != null) {
12859            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12860        }
12861
12862        r = null;
12863        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12864            // Only system apps can hold shared libraries.
12865            if (pkg.libraryNames != null) {
12866                for (i = 0; i < pkg.libraryNames.size(); i++) {
12867                    String name = pkg.libraryNames.get(i);
12868                    if (removeSharedLibraryLPw(name, 0)) {
12869                        if (DEBUG_REMOVE && chatty) {
12870                            if (r == null) {
12871                                r = new StringBuilder(256);
12872                            } else {
12873                                r.append(' ');
12874                            }
12875                            r.append(name);
12876                        }
12877                    }
12878                }
12879            }
12880        }
12881
12882        r = null;
12883
12884        // Any package can hold static shared libraries.
12885        if (pkg.staticSharedLibName != null) {
12886            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12887                if (DEBUG_REMOVE && chatty) {
12888                    if (r == null) {
12889                        r = new StringBuilder(256);
12890                    } else {
12891                        r.append(' ');
12892                    }
12893                    r.append(pkg.staticSharedLibName);
12894                }
12895            }
12896        }
12897
12898        if (r != null) {
12899            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12900        }
12901    }
12902
12903    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12904        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12905            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12906                return true;
12907            }
12908        }
12909        return false;
12910    }
12911
12912    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12913    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12914    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12915
12916    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12917        // Update the parent permissions
12918        updatePermissionsLPw(pkg.packageName, pkg, flags);
12919        // Update the child permissions
12920        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12921        for (int i = 0; i < childCount; i++) {
12922            PackageParser.Package childPkg = pkg.childPackages.get(i);
12923            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12924        }
12925    }
12926
12927    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12928            int flags) {
12929        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12930        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12931    }
12932
12933    private void updatePermissionsLPw(String changingPkg,
12934            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12935        // Make sure there are no dangling permission trees.
12936        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12937        while (it.hasNext()) {
12938            final BasePermission bp = it.next();
12939            if (bp.packageSetting == null) {
12940                // We may not yet have parsed the package, so just see if
12941                // we still know about its settings.
12942                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12943            }
12944            if (bp.packageSetting == null) {
12945                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12946                        + " from package " + bp.sourcePackage);
12947                it.remove();
12948            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12949                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12950                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12951                            + " from package " + bp.sourcePackage);
12952                    flags |= UPDATE_PERMISSIONS_ALL;
12953                    it.remove();
12954                }
12955            }
12956        }
12957
12958        // Make sure all dynamic permissions have been assigned to a package,
12959        // and make sure there are no dangling permissions.
12960        it = mSettings.mPermissions.values().iterator();
12961        while (it.hasNext()) {
12962            final BasePermission bp = it.next();
12963            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12964                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12965                        + bp.name + " pkg=" + bp.sourcePackage
12966                        + " info=" + bp.pendingInfo);
12967                if (bp.packageSetting == null && bp.pendingInfo != null) {
12968                    final BasePermission tree = findPermissionTreeLP(bp.name);
12969                    if (tree != null && tree.perm != null) {
12970                        bp.packageSetting = tree.packageSetting;
12971                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12972                                new PermissionInfo(bp.pendingInfo));
12973                        bp.perm.info.packageName = tree.perm.info.packageName;
12974                        bp.perm.info.name = bp.name;
12975                        bp.uid = tree.uid;
12976                    }
12977                }
12978            }
12979            if (bp.packageSetting == null) {
12980                // We may not yet have parsed the package, so just see if
12981                // we still know about its settings.
12982                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12983            }
12984            if (bp.packageSetting == null) {
12985                Slog.w(TAG, "Removing dangling permission: " + bp.name
12986                        + " from package " + bp.sourcePackage);
12987                it.remove();
12988            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12989                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12990                    Slog.i(TAG, "Removing old permission: " + bp.name
12991                            + " from package " + bp.sourcePackage);
12992                    flags |= UPDATE_PERMISSIONS_ALL;
12993                    it.remove();
12994                }
12995            }
12996        }
12997
12998        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12999        // Now update the permissions for all packages, in particular
13000        // replace the granted permissions of the system packages.
13001        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
13002            for (PackageParser.Package pkg : mPackages.values()) {
13003                if (pkg != pkgInfo) {
13004                    // Only replace for packages on requested volume
13005                    final String volumeUuid = getVolumeUuidForPackage(pkg);
13006                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
13007                            && Objects.equals(replaceVolumeUuid, volumeUuid);
13008                    grantPermissionsLPw(pkg, replace, changingPkg);
13009                }
13010            }
13011        }
13012
13013        if (pkgInfo != null) {
13014            // Only replace for packages on requested volume
13015            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
13016            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
13017                    && Objects.equals(replaceVolumeUuid, volumeUuid);
13018            grantPermissionsLPw(pkgInfo, replace, changingPkg);
13019        }
13020        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
13021    }
13022
13023    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
13024            String packageOfInterest) {
13025        // IMPORTANT: There are two types of permissions: install and runtime.
13026        // Install time permissions are granted when the app is installed to
13027        // all device users and users added in the future. Runtime permissions
13028        // are granted at runtime explicitly to specific users. Normal and signature
13029        // protected permissions are install time permissions. Dangerous permissions
13030        // are install permissions if the app's target SDK is Lollipop MR1 or older,
13031        // otherwise they are runtime permissions. This function does not manage
13032        // runtime permissions except for the case an app targeting Lollipop MR1
13033        // being upgraded to target a newer SDK, in which case dangerous permissions
13034        // are transformed from install time to runtime ones.
13035
13036        final PackageSetting ps = (PackageSetting) pkg.mExtras;
13037        if (ps == null) {
13038            return;
13039        }
13040
13041        PermissionsState permissionsState = ps.getPermissionsState();
13042        PermissionsState origPermissions = permissionsState;
13043
13044        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
13045
13046        boolean runtimePermissionsRevoked = false;
13047        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
13048
13049        boolean changedInstallPermission = false;
13050
13051        if (replace) {
13052            ps.installPermissionsFixed = false;
13053            if (!ps.isSharedUser()) {
13054                origPermissions = new PermissionsState(permissionsState);
13055                permissionsState.reset();
13056            } else {
13057                // We need to know only about runtime permission changes since the
13058                // calling code always writes the install permissions state but
13059                // the runtime ones are written only if changed. The only cases of
13060                // changed runtime permissions here are promotion of an install to
13061                // runtime and revocation of a runtime from a shared user.
13062                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
13063                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
13064                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
13065                    runtimePermissionsRevoked = true;
13066                }
13067            }
13068        }
13069
13070        permissionsState.setGlobalGids(mGlobalGids);
13071
13072        final int N = pkg.requestedPermissions.size();
13073        for (int i=0; i<N; i++) {
13074            final String name = pkg.requestedPermissions.get(i);
13075            final BasePermission bp = mSettings.mPermissions.get(name);
13076            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
13077                    >= Build.VERSION_CODES.M;
13078
13079            if (DEBUG_INSTALL) {
13080                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
13081            }
13082
13083            if (bp == null || bp.packageSetting == null) {
13084                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
13085                    if (DEBUG_PERMISSIONS) {
13086                        Slog.i(TAG, "Unknown permission " + name
13087                                + " in package " + pkg.packageName);
13088                    }
13089                }
13090                continue;
13091            }
13092
13093
13094            // Limit ephemeral apps to ephemeral allowed permissions.
13095            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
13096                if (DEBUG_PERMISSIONS) {
13097                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
13098                            + pkg.packageName);
13099                }
13100                continue;
13101            }
13102
13103            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
13104                if (DEBUG_PERMISSIONS) {
13105                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
13106                            + pkg.packageName);
13107                }
13108                continue;
13109            }
13110
13111            final String perm = bp.name;
13112            boolean allowedSig = false;
13113            int grant = GRANT_DENIED;
13114
13115            // Keep track of app op permissions.
13116            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
13117                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
13118                if (pkgs == null) {
13119                    pkgs = new ArraySet<>();
13120                    mAppOpPermissionPackages.put(bp.name, pkgs);
13121                }
13122                pkgs.add(pkg.packageName);
13123            }
13124
13125            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
13126            switch (level) {
13127                case PermissionInfo.PROTECTION_NORMAL: {
13128                    // For all apps normal permissions are install time ones.
13129                    grant = GRANT_INSTALL;
13130                } break;
13131
13132                case PermissionInfo.PROTECTION_DANGEROUS: {
13133                    // If a permission review is required for legacy apps we represent
13134                    // their permissions as always granted runtime ones since we need
13135                    // to keep the review required permission flag per user while an
13136                    // install permission's state is shared across all users.
13137                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
13138                        // For legacy apps dangerous permissions are install time ones.
13139                        grant = GRANT_INSTALL;
13140                    } else if (origPermissions.hasInstallPermission(bp.name)) {
13141                        // For legacy apps that became modern, install becomes runtime.
13142                        grant = GRANT_UPGRADE;
13143                    } else if (mPromoteSystemApps
13144                            && isSystemApp(ps)
13145                            && mExistingSystemPackages.contains(ps.name)) {
13146                        // For legacy system apps, install becomes runtime.
13147                        // We cannot check hasInstallPermission() for system apps since those
13148                        // permissions were granted implicitly and not persisted pre-M.
13149                        grant = GRANT_UPGRADE;
13150                    } else {
13151                        // For modern apps keep runtime permissions unchanged.
13152                        grant = GRANT_RUNTIME;
13153                    }
13154                } break;
13155
13156                case PermissionInfo.PROTECTION_SIGNATURE: {
13157                    // For all apps signature permissions are install time ones.
13158                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
13159                    if (allowedSig) {
13160                        grant = GRANT_INSTALL;
13161                    }
13162                } break;
13163            }
13164
13165            if (DEBUG_PERMISSIONS) {
13166                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
13167            }
13168
13169            if (grant != GRANT_DENIED) {
13170                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
13171                    // If this is an existing, non-system package, then
13172                    // we can't add any new permissions to it.
13173                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
13174                        // Except...  if this is a permission that was added
13175                        // to the platform (note: need to only do this when
13176                        // updating the platform).
13177                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
13178                            grant = GRANT_DENIED;
13179                        }
13180                    }
13181                }
13182
13183                switch (grant) {
13184                    case GRANT_INSTALL: {
13185                        // Revoke this as runtime permission to handle the case of
13186                        // a runtime permission being downgraded to an install one.
13187                        // Also in permission review mode we keep dangerous permissions
13188                        // for legacy apps
13189                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13190                            if (origPermissions.getRuntimePermissionState(
13191                                    bp.name, userId) != null) {
13192                                // Revoke the runtime permission and clear the flags.
13193                                origPermissions.revokeRuntimePermission(bp, userId);
13194                                origPermissions.updatePermissionFlags(bp, userId,
13195                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
13196                                // If we revoked a permission permission, we have to write.
13197                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13198                                        changedRuntimePermissionUserIds, userId);
13199                            }
13200                        }
13201                        // Grant an install permission.
13202                        if (permissionsState.grantInstallPermission(bp) !=
13203                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
13204                            changedInstallPermission = true;
13205                        }
13206                    } break;
13207
13208                    case GRANT_RUNTIME: {
13209                        // Grant previously granted runtime permissions.
13210                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13211                            PermissionState permissionState = origPermissions
13212                                    .getRuntimePermissionState(bp.name, userId);
13213                            int flags = permissionState != null
13214                                    ? permissionState.getFlags() : 0;
13215                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
13216                                // Don't propagate the permission in a permission review mode if
13217                                // the former was revoked, i.e. marked to not propagate on upgrade.
13218                                // Note that in a permission review mode install permissions are
13219                                // represented as constantly granted runtime ones since we need to
13220                                // keep a per user state associated with the permission. Also the
13221                                // revoke on upgrade flag is no longer applicable and is reset.
13222                                final boolean revokeOnUpgrade = (flags & PackageManager
13223                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
13224                                if (revokeOnUpgrade) {
13225                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13226                                    // Since we changed the flags, we have to write.
13227                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13228                                            changedRuntimePermissionUserIds, userId);
13229                                }
13230                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
13231                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
13232                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
13233                                        // If we cannot put the permission as it was,
13234                                        // we have to write.
13235                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13236                                                changedRuntimePermissionUserIds, userId);
13237                                    }
13238                                }
13239
13240                                // If the app supports runtime permissions no need for a review.
13241                                if (mPermissionReviewRequired
13242                                        && appSupportsRuntimePermissions
13243                                        && (flags & PackageManager
13244                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
13245                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
13246                                    // Since we changed the flags, we have to write.
13247                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13248                                            changedRuntimePermissionUserIds, userId);
13249                                }
13250                            } else if (mPermissionReviewRequired
13251                                    && !appSupportsRuntimePermissions) {
13252                                // For legacy apps that need a permission review, every new
13253                                // runtime permission is granted but it is pending a review.
13254                                // We also need to review only platform defined runtime
13255                                // permissions as these are the only ones the platform knows
13256                                // how to disable the API to simulate revocation as legacy
13257                                // apps don't expect to run with revoked permissions.
13258                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
13259                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
13260                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
13261                                        // We changed the flags, hence have to write.
13262                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13263                                                changedRuntimePermissionUserIds, userId);
13264                                    }
13265                                }
13266                                if (permissionsState.grantRuntimePermission(bp, userId)
13267                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13268                                    // We changed the permission, hence have to write.
13269                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13270                                            changedRuntimePermissionUserIds, userId);
13271                                }
13272                            }
13273                            // Propagate the permission flags.
13274                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
13275                        }
13276                    } break;
13277
13278                    case GRANT_UPGRADE: {
13279                        // Grant runtime permissions for a previously held install permission.
13280                        PermissionState permissionState = origPermissions
13281                                .getInstallPermissionState(bp.name);
13282                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
13283
13284                        if (origPermissions.revokeInstallPermission(bp)
13285                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13286                            // We will be transferring the permission flags, so clear them.
13287                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
13288                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
13289                            changedInstallPermission = true;
13290                        }
13291
13292                        // If the permission is not to be promoted to runtime we ignore it and
13293                        // also its other flags as they are not applicable to install permissions.
13294                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
13295                            for (int userId : currentUserIds) {
13296                                if (permissionsState.grantRuntimePermission(bp, userId) !=
13297                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
13298                                    // Transfer the permission flags.
13299                                    permissionsState.updatePermissionFlags(bp, userId,
13300                                            flags, flags);
13301                                    // If we granted the permission, we have to write.
13302                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13303                                            changedRuntimePermissionUserIds, userId);
13304                                }
13305                            }
13306                        }
13307                    } break;
13308
13309                    default: {
13310                        if (packageOfInterest == null
13311                                || packageOfInterest.equals(pkg.packageName)) {
13312                            if (DEBUG_PERMISSIONS) {
13313                                Slog.i(TAG, "Not granting permission " + perm
13314                                        + " to package " + pkg.packageName
13315                                        + " because it was previously installed without");
13316                            }
13317                        }
13318                    } break;
13319                }
13320            } else {
13321                if (permissionsState.revokeInstallPermission(bp) !=
13322                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
13323                    // Also drop the permission flags.
13324                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
13325                            PackageManager.MASK_PERMISSION_FLAGS, 0);
13326                    changedInstallPermission = true;
13327                    Slog.i(TAG, "Un-granting permission " + perm
13328                            + " from package " + pkg.packageName
13329                            + " (protectionLevel=" + bp.protectionLevel
13330                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13331                            + ")");
13332                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
13333                    // Don't print warning for app op permissions, since it is fine for them
13334                    // not to be granted, there is a UI for the user to decide.
13335                    if (DEBUG_PERMISSIONS
13336                            && (packageOfInterest == null
13337                                    || packageOfInterest.equals(pkg.packageName))) {
13338                        Slog.i(TAG, "Not granting permission " + perm
13339                                + " to package " + pkg.packageName
13340                                + " (protectionLevel=" + bp.protectionLevel
13341                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13342                                + ")");
13343                    }
13344                }
13345            }
13346        }
13347
13348        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13349                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13350            // This is the first that we have heard about this package, so the
13351            // permissions we have now selected are fixed until explicitly
13352            // changed.
13353            ps.installPermissionsFixed = true;
13354        }
13355
13356        // Persist the runtime permissions state for users with changes. If permissions
13357        // were revoked because no app in the shared user declares them we have to
13358        // write synchronously to avoid losing runtime permissions state.
13359        for (int userId : changedRuntimePermissionUserIds) {
13360            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13361        }
13362    }
13363
13364    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13365        boolean allowed = false;
13366        final int NP = PackageParser.NEW_PERMISSIONS.length;
13367        for (int ip=0; ip<NP; ip++) {
13368            final PackageParser.NewPermissionInfo npi
13369                    = PackageParser.NEW_PERMISSIONS[ip];
13370            if (npi.name.equals(perm)
13371                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13372                allowed = true;
13373                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13374                        + pkg.packageName);
13375                break;
13376            }
13377        }
13378        return allowed;
13379    }
13380
13381    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13382            BasePermission bp, PermissionsState origPermissions) {
13383        boolean privilegedPermission = (bp.protectionLevel
13384                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13385        boolean privappPermissionsDisable =
13386                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13387        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13388        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13389        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13390                && !platformPackage && platformPermission) {
13391            final ArraySet<String> allowedPermissions = SystemConfig.getInstance()
13392                    .getPrivAppPermissions(pkg.packageName);
13393            final boolean whitelisted =
13394                    allowedPermissions != null && allowedPermissions.contains(perm);
13395            if (!whitelisted) {
13396                Slog.w(TAG, "Privileged permission " + perm + " for package "
13397                        + pkg.packageName + " - not in privapp-permissions whitelist");
13398                // Only report violations for apps on system image
13399                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13400                    // it's only a reportable violation if the permission isn't explicitly denied
13401                    final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
13402                            .getPrivAppDenyPermissions(pkg.packageName);
13403                    final boolean permissionViolation =
13404                            deniedPermissions == null || !deniedPermissions.contains(perm);
13405                    if (permissionViolation) {
13406                        if (mPrivappPermissionsViolations == null) {
13407                            mPrivappPermissionsViolations = new ArraySet<>();
13408                        }
13409                        mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13410                    } else {
13411                        return false;
13412                    }
13413                }
13414                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13415                    return false;
13416                }
13417            }
13418        }
13419        boolean allowed = (compareSignatures(
13420                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13421                        == PackageManager.SIGNATURE_MATCH)
13422                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13423                        == PackageManager.SIGNATURE_MATCH);
13424        if (!allowed && privilegedPermission) {
13425            if (isSystemApp(pkg)) {
13426                // For updated system applications, a system permission
13427                // is granted only if it had been defined by the original application.
13428                if (pkg.isUpdatedSystemApp()) {
13429                    final PackageSetting sysPs = mSettings
13430                            .getDisabledSystemPkgLPr(pkg.packageName);
13431                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13432                        // If the original was granted this permission, we take
13433                        // that grant decision as read and propagate it to the
13434                        // update.
13435                        if (sysPs.isPrivileged()) {
13436                            allowed = true;
13437                        }
13438                    } else {
13439                        // The system apk may have been updated with an older
13440                        // version of the one on the data partition, but which
13441                        // granted a new system permission that it didn't have
13442                        // before.  In this case we do want to allow the app to
13443                        // now get the new permission if the ancestral apk is
13444                        // privileged to get it.
13445                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13446                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13447                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13448                                    allowed = true;
13449                                    break;
13450                                }
13451                            }
13452                        }
13453                        // Also if a privileged parent package on the system image or any of
13454                        // its children requested a privileged permission, the updated child
13455                        // packages can also get the permission.
13456                        if (pkg.parentPackage != null) {
13457                            final PackageSetting disabledSysParentPs = mSettings
13458                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13459                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13460                                    && disabledSysParentPs.isPrivileged()) {
13461                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13462                                    allowed = true;
13463                                } else if (disabledSysParentPs.pkg.childPackages != null) {
13464                                    final int count = disabledSysParentPs.pkg.childPackages.size();
13465                                    for (int i = 0; i < count; i++) {
13466                                        PackageParser.Package disabledSysChildPkg =
13467                                                disabledSysParentPs.pkg.childPackages.get(i);
13468                                        if (isPackageRequestingPermission(disabledSysChildPkg,
13469                                                perm)) {
13470                                            allowed = true;
13471                                            break;
13472                                        }
13473                                    }
13474                                }
13475                            }
13476                        }
13477                    }
13478                } else {
13479                    allowed = isPrivilegedApp(pkg);
13480                }
13481            }
13482        }
13483        if (!allowed) {
13484            if (!allowed && (bp.protectionLevel
13485                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13486                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13487                // If this was a previously normal/dangerous permission that got moved
13488                // to a system permission as part of the runtime permission redesign, then
13489                // we still want to blindly grant it to old apps.
13490                allowed = true;
13491            }
13492            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13493                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
13494                // If this permission is to be granted to the system installer and
13495                // this app is an installer, then it gets the permission.
13496                allowed = true;
13497            }
13498            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13499                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
13500                // If this permission is to be granted to the system verifier and
13501                // this app is a verifier, then it gets the permission.
13502                allowed = true;
13503            }
13504            if (!allowed && (bp.protectionLevel
13505                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13506                    && isSystemApp(pkg)) {
13507                // Any pre-installed system app is allowed to get this permission.
13508                allowed = true;
13509            }
13510            if (!allowed && (bp.protectionLevel
13511                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13512                // For development permissions, a development permission
13513                // is granted only if it was already granted.
13514                allowed = origPermissions.hasInstallPermission(perm);
13515            }
13516            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13517                    && pkg.packageName.equals(mSetupWizardPackage)) {
13518                // If this permission is to be granted to the system setup wizard and
13519                // this app is a setup wizard, then it gets the permission.
13520                allowed = true;
13521            }
13522        }
13523        return allowed;
13524    }
13525
13526    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13527        final int permCount = pkg.requestedPermissions.size();
13528        for (int j = 0; j < permCount; j++) {
13529            String requestedPermission = pkg.requestedPermissions.get(j);
13530            if (permission.equals(requestedPermission)) {
13531                return true;
13532            }
13533        }
13534        return false;
13535    }
13536
13537    final class ActivityIntentResolver
13538            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13539        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13540                boolean defaultOnly, int userId) {
13541            if (!sUserManager.exists(userId)) return null;
13542            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13543            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13544        }
13545
13546        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13547                int userId) {
13548            if (!sUserManager.exists(userId)) return null;
13549            mFlags = flags;
13550            return super.queryIntent(intent, resolvedType,
13551                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13552                    userId);
13553        }
13554
13555        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13556                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13557            if (!sUserManager.exists(userId)) return null;
13558            if (packageActivities == null) {
13559                return null;
13560            }
13561            mFlags = flags;
13562            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13563            final int N = packageActivities.size();
13564            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13565                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13566
13567            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13568            for (int i = 0; i < N; ++i) {
13569                intentFilters = packageActivities.get(i).intents;
13570                if (intentFilters != null && intentFilters.size() > 0) {
13571                    PackageParser.ActivityIntentInfo[] array =
13572                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
13573                    intentFilters.toArray(array);
13574                    listCut.add(array);
13575                }
13576            }
13577            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13578        }
13579
13580        /**
13581         * Finds a privileged activity that matches the specified activity names.
13582         */
13583        private PackageParser.Activity findMatchingActivity(
13584                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13585            for (PackageParser.Activity sysActivity : activityList) {
13586                if (sysActivity.info.name.equals(activityInfo.name)) {
13587                    return sysActivity;
13588                }
13589                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13590                    return sysActivity;
13591                }
13592                if (sysActivity.info.targetActivity != null) {
13593                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13594                        return sysActivity;
13595                    }
13596                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13597                        return sysActivity;
13598                    }
13599                }
13600            }
13601            return null;
13602        }
13603
13604        public class IterGenerator<E> {
13605            public Iterator<E> generate(ActivityIntentInfo info) {
13606                return null;
13607            }
13608        }
13609
13610        public class ActionIterGenerator extends IterGenerator<String> {
13611            @Override
13612            public Iterator<String> generate(ActivityIntentInfo info) {
13613                return info.actionsIterator();
13614            }
13615        }
13616
13617        public class CategoriesIterGenerator extends IterGenerator<String> {
13618            @Override
13619            public Iterator<String> generate(ActivityIntentInfo info) {
13620                return info.categoriesIterator();
13621            }
13622        }
13623
13624        public class SchemesIterGenerator extends IterGenerator<String> {
13625            @Override
13626            public Iterator<String> generate(ActivityIntentInfo info) {
13627                return info.schemesIterator();
13628            }
13629        }
13630
13631        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13632            @Override
13633            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13634                return info.authoritiesIterator();
13635            }
13636        }
13637
13638        /**
13639         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13640         * MODIFIED. Do not pass in a list that should not be changed.
13641         */
13642        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13643                IterGenerator<T> generator, Iterator<T> searchIterator) {
13644            // loop through the set of actions; every one must be found in the intent filter
13645            while (searchIterator.hasNext()) {
13646                // we must have at least one filter in the list to consider a match
13647                if (intentList.size() == 0) {
13648                    break;
13649                }
13650
13651                final T searchAction = searchIterator.next();
13652
13653                // loop through the set of intent filters
13654                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13655                while (intentIter.hasNext()) {
13656                    final ActivityIntentInfo intentInfo = intentIter.next();
13657                    boolean selectionFound = false;
13658
13659                    // loop through the intent filter's selection criteria; at least one
13660                    // of them must match the searched criteria
13661                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13662                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13663                        final T intentSelection = intentSelectionIter.next();
13664                        if (intentSelection != null && intentSelection.equals(searchAction)) {
13665                            selectionFound = true;
13666                            break;
13667                        }
13668                    }
13669
13670                    // the selection criteria wasn't found in this filter's set; this filter
13671                    // is not a potential match
13672                    if (!selectionFound) {
13673                        intentIter.remove();
13674                    }
13675                }
13676            }
13677        }
13678
13679        private boolean isProtectedAction(ActivityIntentInfo filter) {
13680            final Iterator<String> actionsIter = filter.actionsIterator();
13681            while (actionsIter != null && actionsIter.hasNext()) {
13682                final String filterAction = actionsIter.next();
13683                if (PROTECTED_ACTIONS.contains(filterAction)) {
13684                    return true;
13685                }
13686            }
13687            return false;
13688        }
13689
13690        /**
13691         * Adjusts the priority of the given intent filter according to policy.
13692         * <p>
13693         * <ul>
13694         * <li>The priority for non privileged applications is capped to '0'</li>
13695         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13696         * <li>The priority for unbundled updates to privileged applications is capped to the
13697         *      priority defined on the system partition</li>
13698         * </ul>
13699         * <p>
13700         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13701         * allowed to obtain any priority on any action.
13702         */
13703        private void adjustPriority(
13704                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13705            // nothing to do; priority is fine as-is
13706            if (intent.getPriority() <= 0) {
13707                return;
13708            }
13709
13710            final ActivityInfo activityInfo = intent.activity.info;
13711            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13712
13713            final boolean privilegedApp =
13714                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13715            if (!privilegedApp) {
13716                // non-privileged applications can never define a priority >0
13717                if (DEBUG_FILTERS) {
13718                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13719                            + " package: " + applicationInfo.packageName
13720                            + " activity: " + intent.activity.className
13721                            + " origPrio: " + intent.getPriority());
13722                }
13723                intent.setPriority(0);
13724                return;
13725            }
13726
13727            if (systemActivities == null) {
13728                // the system package is not disabled; we're parsing the system partition
13729                if (isProtectedAction(intent)) {
13730                    if (mDeferProtectedFilters) {
13731                        // We can't deal with these just yet. No component should ever obtain a
13732                        // >0 priority for a protected actions, with ONE exception -- the setup
13733                        // wizard. The setup wizard, however, cannot be known until we're able to
13734                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13735                        // until all intent filters have been processed. Chicken, meet egg.
13736                        // Let the filter temporarily have a high priority and rectify the
13737                        // priorities after all system packages have been scanned.
13738                        mProtectedFilters.add(intent);
13739                        if (DEBUG_FILTERS) {
13740                            Slog.i(TAG, "Protected action; save for later;"
13741                                    + " package: " + applicationInfo.packageName
13742                                    + " activity: " + intent.activity.className
13743                                    + " origPrio: " + intent.getPriority());
13744                        }
13745                        return;
13746                    } else {
13747                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13748                            Slog.i(TAG, "No setup wizard;"
13749                                + " All protected intents capped to priority 0");
13750                        }
13751                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13752                            if (DEBUG_FILTERS) {
13753                                Slog.i(TAG, "Found setup wizard;"
13754                                    + " allow priority " + intent.getPriority() + ";"
13755                                    + " package: " + intent.activity.info.packageName
13756                                    + " activity: " + intent.activity.className
13757                                    + " priority: " + intent.getPriority());
13758                            }
13759                            // setup wizard gets whatever it wants
13760                            return;
13761                        }
13762                        if (DEBUG_FILTERS) {
13763                            Slog.i(TAG, "Protected action; cap priority to 0;"
13764                                    + " package: " + intent.activity.info.packageName
13765                                    + " activity: " + intent.activity.className
13766                                    + " origPrio: " + intent.getPriority());
13767                        }
13768                        intent.setPriority(0);
13769                        return;
13770                    }
13771                }
13772                // privileged apps on the system image get whatever priority they request
13773                return;
13774            }
13775
13776            // privileged app unbundled update ... try to find the same activity
13777            final PackageParser.Activity foundActivity =
13778                    findMatchingActivity(systemActivities, activityInfo);
13779            if (foundActivity == null) {
13780                // this is a new activity; it cannot obtain >0 priority
13781                if (DEBUG_FILTERS) {
13782                    Slog.i(TAG, "New activity; cap priority to 0;"
13783                            + " package: " + applicationInfo.packageName
13784                            + " activity: " + intent.activity.className
13785                            + " origPrio: " + intent.getPriority());
13786                }
13787                intent.setPriority(0);
13788                return;
13789            }
13790
13791            // found activity, now check for filter equivalence
13792
13793            // a shallow copy is enough; we modify the list, not its contents
13794            final List<ActivityIntentInfo> intentListCopy =
13795                    new ArrayList<>(foundActivity.intents);
13796            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13797
13798            // find matching action subsets
13799            final Iterator<String> actionsIterator = intent.actionsIterator();
13800            if (actionsIterator != null) {
13801                getIntentListSubset(
13802                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13803                if (intentListCopy.size() == 0) {
13804                    // no more intents to match; we're not equivalent
13805                    if (DEBUG_FILTERS) {
13806                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13807                                + " package: " + applicationInfo.packageName
13808                                + " activity: " + intent.activity.className
13809                                + " origPrio: " + intent.getPriority());
13810                    }
13811                    intent.setPriority(0);
13812                    return;
13813                }
13814            }
13815
13816            // find matching category subsets
13817            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13818            if (categoriesIterator != null) {
13819                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13820                        categoriesIterator);
13821                if (intentListCopy.size() == 0) {
13822                    // no more intents to match; we're not equivalent
13823                    if (DEBUG_FILTERS) {
13824                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13825                                + " package: " + applicationInfo.packageName
13826                                + " activity: " + intent.activity.className
13827                                + " origPrio: " + intent.getPriority());
13828                    }
13829                    intent.setPriority(0);
13830                    return;
13831                }
13832            }
13833
13834            // find matching schemes subsets
13835            final Iterator<String> schemesIterator = intent.schemesIterator();
13836            if (schemesIterator != null) {
13837                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13838                        schemesIterator);
13839                if (intentListCopy.size() == 0) {
13840                    // no more intents to match; we're not equivalent
13841                    if (DEBUG_FILTERS) {
13842                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13843                                + " package: " + applicationInfo.packageName
13844                                + " activity: " + intent.activity.className
13845                                + " origPrio: " + intent.getPriority());
13846                    }
13847                    intent.setPriority(0);
13848                    return;
13849                }
13850            }
13851
13852            // find matching authorities subsets
13853            final Iterator<IntentFilter.AuthorityEntry>
13854                    authoritiesIterator = intent.authoritiesIterator();
13855            if (authoritiesIterator != null) {
13856                getIntentListSubset(intentListCopy,
13857                        new AuthoritiesIterGenerator(),
13858                        authoritiesIterator);
13859                if (intentListCopy.size() == 0) {
13860                    // no more intents to match; we're not equivalent
13861                    if (DEBUG_FILTERS) {
13862                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13863                                + " package: " + applicationInfo.packageName
13864                                + " activity: " + intent.activity.className
13865                                + " origPrio: " + intent.getPriority());
13866                    }
13867                    intent.setPriority(0);
13868                    return;
13869                }
13870            }
13871
13872            // we found matching filter(s); app gets the max priority of all intents
13873            int cappedPriority = 0;
13874            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13875                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13876            }
13877            if (intent.getPriority() > cappedPriority) {
13878                if (DEBUG_FILTERS) {
13879                    Slog.i(TAG, "Found matching filter(s);"
13880                            + " cap priority to " + cappedPriority + ";"
13881                            + " package: " + applicationInfo.packageName
13882                            + " activity: " + intent.activity.className
13883                            + " origPrio: " + intent.getPriority());
13884                }
13885                intent.setPriority(cappedPriority);
13886                return;
13887            }
13888            // all this for nothing; the requested priority was <= what was on the system
13889        }
13890
13891        public final void addActivity(PackageParser.Activity a, String type) {
13892            mActivities.put(a.getComponentName(), a);
13893            if (DEBUG_SHOW_INFO)
13894                Log.v(
13895                TAG, "  " + type + " " +
13896                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13897            if (DEBUG_SHOW_INFO)
13898                Log.v(TAG, "    Class=" + a.info.name);
13899            final int NI = a.intents.size();
13900            for (int j=0; j<NI; j++) {
13901                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13902                if ("activity".equals(type)) {
13903                    final PackageSetting ps =
13904                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13905                    final List<PackageParser.Activity> systemActivities =
13906                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13907                    adjustPriority(systemActivities, intent);
13908                }
13909                if (DEBUG_SHOW_INFO) {
13910                    Log.v(TAG, "    IntentFilter:");
13911                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13912                }
13913                if (!intent.debugCheck()) {
13914                    Log.w(TAG, "==> For Activity " + a.info.name);
13915                }
13916                addFilter(intent);
13917            }
13918        }
13919
13920        public final void removeActivity(PackageParser.Activity a, String type) {
13921            mActivities.remove(a.getComponentName());
13922            if (DEBUG_SHOW_INFO) {
13923                Log.v(TAG, "  " + type + " "
13924                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13925                                : a.info.name) + ":");
13926                Log.v(TAG, "    Class=" + a.info.name);
13927            }
13928            final int NI = a.intents.size();
13929            for (int j=0; j<NI; j++) {
13930                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13931                if (DEBUG_SHOW_INFO) {
13932                    Log.v(TAG, "    IntentFilter:");
13933                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13934                }
13935                removeFilter(intent);
13936            }
13937        }
13938
13939        @Override
13940        protected boolean allowFilterResult(
13941                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13942            ActivityInfo filterAi = filter.activity.info;
13943            for (int i=dest.size()-1; i>=0; i--) {
13944                ActivityInfo destAi = dest.get(i).activityInfo;
13945                if (destAi.name == filterAi.name
13946                        && destAi.packageName == filterAi.packageName) {
13947                    return false;
13948                }
13949            }
13950            return true;
13951        }
13952
13953        @Override
13954        protected ActivityIntentInfo[] newArray(int size) {
13955            return new ActivityIntentInfo[size];
13956        }
13957
13958        @Override
13959        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13960            if (!sUserManager.exists(userId)) return true;
13961            PackageParser.Package p = filter.activity.owner;
13962            if (p != null) {
13963                PackageSetting ps = (PackageSetting)p.mExtras;
13964                if (ps != null) {
13965                    // System apps are never considered stopped for purposes of
13966                    // filtering, because there may be no way for the user to
13967                    // actually re-launch them.
13968                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13969                            && ps.getStopped(userId);
13970                }
13971            }
13972            return false;
13973        }
13974
13975        @Override
13976        protected boolean isPackageForFilter(String packageName,
13977                PackageParser.ActivityIntentInfo info) {
13978            return packageName.equals(info.activity.owner.packageName);
13979        }
13980
13981        @Override
13982        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13983                int match, int userId) {
13984            if (!sUserManager.exists(userId)) return null;
13985            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13986                return null;
13987            }
13988            final PackageParser.Activity activity = info.activity;
13989            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13990            if (ps == null) {
13991                return null;
13992            }
13993            final PackageUserState userState = ps.readUserState(userId);
13994            ActivityInfo ai =
13995                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13996            if (ai == null) {
13997                return null;
13998            }
13999            final boolean matchExplicitlyVisibleOnly =
14000                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
14001            final boolean matchVisibleToInstantApp =
14002                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14003            final boolean componentVisible =
14004                    matchVisibleToInstantApp
14005                    && info.isVisibleToInstantApp()
14006                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
14007            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14008            // throw out filters that aren't visible to ephemeral apps
14009            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
14010                return null;
14011            }
14012            // throw out instant app filters if we're not explicitly requesting them
14013            if (!matchInstantApp && userState.instantApp) {
14014                return null;
14015            }
14016            // throw out instant app filters if updates are available; will trigger
14017            // instant app resolution
14018            if (userState.instantApp && ps.isUpdateAvailable()) {
14019                return null;
14020            }
14021            final ResolveInfo res = new ResolveInfo();
14022            res.activityInfo = ai;
14023            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14024                res.filter = info;
14025            }
14026            if (info != null) {
14027                res.handleAllWebDataURI = info.handleAllWebDataURI();
14028            }
14029            res.priority = info.getPriority();
14030            res.preferredOrder = activity.owner.mPreferredOrder;
14031            //System.out.println("Result: " + res.activityInfo.className +
14032            //                   " = " + res.priority);
14033            res.match = match;
14034            res.isDefault = info.hasDefault;
14035            res.labelRes = info.labelRes;
14036            res.nonLocalizedLabel = info.nonLocalizedLabel;
14037            if (userNeedsBadging(userId)) {
14038                res.noResourceId = true;
14039            } else {
14040                res.icon = info.icon;
14041            }
14042            res.iconResourceId = info.icon;
14043            res.system = res.activityInfo.applicationInfo.isSystemApp();
14044            res.isInstantAppAvailable = userState.instantApp;
14045            return res;
14046        }
14047
14048        @Override
14049        protected void sortResults(List<ResolveInfo> results) {
14050            Collections.sort(results, mResolvePrioritySorter);
14051        }
14052
14053        @Override
14054        protected void dumpFilter(PrintWriter out, String prefix,
14055                PackageParser.ActivityIntentInfo filter) {
14056            out.print(prefix); out.print(
14057                    Integer.toHexString(System.identityHashCode(filter.activity)));
14058                    out.print(' ');
14059                    filter.activity.printComponentShortName(out);
14060                    out.print(" filter ");
14061                    out.println(Integer.toHexString(System.identityHashCode(filter)));
14062        }
14063
14064        @Override
14065        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
14066            return filter.activity;
14067        }
14068
14069        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14070            PackageParser.Activity activity = (PackageParser.Activity)label;
14071            out.print(prefix); out.print(
14072                    Integer.toHexString(System.identityHashCode(activity)));
14073                    out.print(' ');
14074                    activity.printComponentShortName(out);
14075            if (count > 1) {
14076                out.print(" ("); out.print(count); out.print(" filters)");
14077            }
14078            out.println();
14079        }
14080
14081        // Keys are String (activity class name), values are Activity.
14082        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
14083                = new ArrayMap<ComponentName, PackageParser.Activity>();
14084        private int mFlags;
14085    }
14086
14087    private final class ServiceIntentResolver
14088            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
14089        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14090                boolean defaultOnly, int userId) {
14091            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14092            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14093        }
14094
14095        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14096                int userId) {
14097            if (!sUserManager.exists(userId)) return null;
14098            mFlags = flags;
14099            return super.queryIntent(intent, resolvedType,
14100                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14101                    userId);
14102        }
14103
14104        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14105                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
14106            if (!sUserManager.exists(userId)) return null;
14107            if (packageServices == null) {
14108                return null;
14109            }
14110            mFlags = flags;
14111            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
14112            final int N = packageServices.size();
14113            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
14114                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
14115
14116            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
14117            for (int i = 0; i < N; ++i) {
14118                intentFilters = packageServices.get(i).intents;
14119                if (intentFilters != null && intentFilters.size() > 0) {
14120                    PackageParser.ServiceIntentInfo[] array =
14121                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
14122                    intentFilters.toArray(array);
14123                    listCut.add(array);
14124                }
14125            }
14126            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14127        }
14128
14129        public final void addService(PackageParser.Service s) {
14130            mServices.put(s.getComponentName(), s);
14131            if (DEBUG_SHOW_INFO) {
14132                Log.v(TAG, "  "
14133                        + (s.info.nonLocalizedLabel != null
14134                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
14135                Log.v(TAG, "    Class=" + s.info.name);
14136            }
14137            final int NI = s.intents.size();
14138            int j;
14139            for (j=0; j<NI; j++) {
14140                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14141                if (DEBUG_SHOW_INFO) {
14142                    Log.v(TAG, "    IntentFilter:");
14143                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14144                }
14145                if (!intent.debugCheck()) {
14146                    Log.w(TAG, "==> For Service " + s.info.name);
14147                }
14148                addFilter(intent);
14149            }
14150        }
14151
14152        public final void removeService(PackageParser.Service s) {
14153            mServices.remove(s.getComponentName());
14154            if (DEBUG_SHOW_INFO) {
14155                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
14156                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
14157                Log.v(TAG, "    Class=" + s.info.name);
14158            }
14159            final int NI = s.intents.size();
14160            int j;
14161            for (j=0; j<NI; j++) {
14162                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14163                if (DEBUG_SHOW_INFO) {
14164                    Log.v(TAG, "    IntentFilter:");
14165                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14166                }
14167                removeFilter(intent);
14168            }
14169        }
14170
14171        @Override
14172        protected boolean allowFilterResult(
14173                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
14174            ServiceInfo filterSi = filter.service.info;
14175            for (int i=dest.size()-1; i>=0; i--) {
14176                ServiceInfo destAi = dest.get(i).serviceInfo;
14177                if (destAi.name == filterSi.name
14178                        && destAi.packageName == filterSi.packageName) {
14179                    return false;
14180                }
14181            }
14182            return true;
14183        }
14184
14185        @Override
14186        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
14187            return new PackageParser.ServiceIntentInfo[size];
14188        }
14189
14190        @Override
14191        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
14192            if (!sUserManager.exists(userId)) return true;
14193            PackageParser.Package p = filter.service.owner;
14194            if (p != null) {
14195                PackageSetting ps = (PackageSetting)p.mExtras;
14196                if (ps != null) {
14197                    // System apps are never considered stopped for purposes of
14198                    // filtering, because there may be no way for the user to
14199                    // actually re-launch them.
14200                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14201                            && ps.getStopped(userId);
14202                }
14203            }
14204            return false;
14205        }
14206
14207        @Override
14208        protected boolean isPackageForFilter(String packageName,
14209                PackageParser.ServiceIntentInfo info) {
14210            return packageName.equals(info.service.owner.packageName);
14211        }
14212
14213        @Override
14214        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
14215                int match, int userId) {
14216            if (!sUserManager.exists(userId)) return null;
14217            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
14218            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
14219                return null;
14220            }
14221            final PackageParser.Service service = info.service;
14222            PackageSetting ps = (PackageSetting) service.owner.mExtras;
14223            if (ps == null) {
14224                return null;
14225            }
14226            final PackageUserState userState = ps.readUserState(userId);
14227            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
14228                    userState, userId);
14229            if (si == null) {
14230                return null;
14231            }
14232            final boolean matchVisibleToInstantApp =
14233                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14234            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14235            // throw out filters that aren't visible to ephemeral apps
14236            if (matchVisibleToInstantApp
14237                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14238                return null;
14239            }
14240            // throw out ephemeral filters if we're not explicitly requesting them
14241            if (!isInstantApp && userState.instantApp) {
14242                return null;
14243            }
14244            // throw out instant app filters if updates are available; will trigger
14245            // instant app resolution
14246            if (userState.instantApp && ps.isUpdateAvailable()) {
14247                return null;
14248            }
14249            final ResolveInfo res = new ResolveInfo();
14250            res.serviceInfo = si;
14251            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14252                res.filter = filter;
14253            }
14254            res.priority = info.getPriority();
14255            res.preferredOrder = service.owner.mPreferredOrder;
14256            res.match = match;
14257            res.isDefault = info.hasDefault;
14258            res.labelRes = info.labelRes;
14259            res.nonLocalizedLabel = info.nonLocalizedLabel;
14260            res.icon = info.icon;
14261            res.system = res.serviceInfo.applicationInfo.isSystemApp();
14262            return res;
14263        }
14264
14265        @Override
14266        protected void sortResults(List<ResolveInfo> results) {
14267            Collections.sort(results, mResolvePrioritySorter);
14268        }
14269
14270        @Override
14271        protected void dumpFilter(PrintWriter out, String prefix,
14272                PackageParser.ServiceIntentInfo filter) {
14273            out.print(prefix); out.print(
14274                    Integer.toHexString(System.identityHashCode(filter.service)));
14275                    out.print(' ');
14276                    filter.service.printComponentShortName(out);
14277                    out.print(" filter ");
14278                    out.println(Integer.toHexString(System.identityHashCode(filter)));
14279        }
14280
14281        @Override
14282        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
14283            return filter.service;
14284        }
14285
14286        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14287            PackageParser.Service service = (PackageParser.Service)label;
14288            out.print(prefix); out.print(
14289                    Integer.toHexString(System.identityHashCode(service)));
14290                    out.print(' ');
14291                    service.printComponentShortName(out);
14292            if (count > 1) {
14293                out.print(" ("); out.print(count); out.print(" filters)");
14294            }
14295            out.println();
14296        }
14297
14298//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
14299//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
14300//            final List<ResolveInfo> retList = Lists.newArrayList();
14301//            while (i.hasNext()) {
14302//                final ResolveInfo resolveInfo = (ResolveInfo) i;
14303//                if (isEnabledLP(resolveInfo.serviceInfo)) {
14304//                    retList.add(resolveInfo);
14305//                }
14306//            }
14307//            return retList;
14308//        }
14309
14310        // Keys are String (activity class name), values are Activity.
14311        private final ArrayMap<ComponentName, PackageParser.Service> mServices
14312                = new ArrayMap<ComponentName, PackageParser.Service>();
14313        private int mFlags;
14314    }
14315
14316    private final class ProviderIntentResolver
14317            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
14318        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14319                boolean defaultOnly, int userId) {
14320            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14321            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14322        }
14323
14324        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14325                int userId) {
14326            if (!sUserManager.exists(userId))
14327                return null;
14328            mFlags = flags;
14329            return super.queryIntent(intent, resolvedType,
14330                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14331                    userId);
14332        }
14333
14334        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14335                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
14336            if (!sUserManager.exists(userId))
14337                return null;
14338            if (packageProviders == null) {
14339                return null;
14340            }
14341            mFlags = flags;
14342            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14343            final int N = packageProviders.size();
14344            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14345                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14346
14347            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14348            for (int i = 0; i < N; ++i) {
14349                intentFilters = packageProviders.get(i).intents;
14350                if (intentFilters != null && intentFilters.size() > 0) {
14351                    PackageParser.ProviderIntentInfo[] array =
14352                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
14353                    intentFilters.toArray(array);
14354                    listCut.add(array);
14355                }
14356            }
14357            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14358        }
14359
14360        public final void addProvider(PackageParser.Provider p) {
14361            if (mProviders.containsKey(p.getComponentName())) {
14362                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14363                return;
14364            }
14365
14366            mProviders.put(p.getComponentName(), p);
14367            if (DEBUG_SHOW_INFO) {
14368                Log.v(TAG, "  "
14369                        + (p.info.nonLocalizedLabel != null
14370                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
14371                Log.v(TAG, "    Class=" + p.info.name);
14372            }
14373            final int NI = p.intents.size();
14374            int j;
14375            for (j = 0; j < NI; j++) {
14376                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14377                if (DEBUG_SHOW_INFO) {
14378                    Log.v(TAG, "    IntentFilter:");
14379                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14380                }
14381                if (!intent.debugCheck()) {
14382                    Log.w(TAG, "==> For Provider " + p.info.name);
14383                }
14384                addFilter(intent);
14385            }
14386        }
14387
14388        public final void removeProvider(PackageParser.Provider p) {
14389            mProviders.remove(p.getComponentName());
14390            if (DEBUG_SHOW_INFO) {
14391                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14392                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
14393                Log.v(TAG, "    Class=" + p.info.name);
14394            }
14395            final int NI = p.intents.size();
14396            int j;
14397            for (j = 0; j < NI; j++) {
14398                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14399                if (DEBUG_SHOW_INFO) {
14400                    Log.v(TAG, "    IntentFilter:");
14401                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14402                }
14403                removeFilter(intent);
14404            }
14405        }
14406
14407        @Override
14408        protected boolean allowFilterResult(
14409                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14410            ProviderInfo filterPi = filter.provider.info;
14411            for (int i = dest.size() - 1; i >= 0; i--) {
14412                ProviderInfo destPi = dest.get(i).providerInfo;
14413                if (destPi.name == filterPi.name
14414                        && destPi.packageName == filterPi.packageName) {
14415                    return false;
14416                }
14417            }
14418            return true;
14419        }
14420
14421        @Override
14422        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14423            return new PackageParser.ProviderIntentInfo[size];
14424        }
14425
14426        @Override
14427        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14428            if (!sUserManager.exists(userId))
14429                return true;
14430            PackageParser.Package p = filter.provider.owner;
14431            if (p != null) {
14432                PackageSetting ps = (PackageSetting) p.mExtras;
14433                if (ps != null) {
14434                    // System apps are never considered stopped for purposes of
14435                    // filtering, because there may be no way for the user to
14436                    // actually re-launch them.
14437                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14438                            && ps.getStopped(userId);
14439                }
14440            }
14441            return false;
14442        }
14443
14444        @Override
14445        protected boolean isPackageForFilter(String packageName,
14446                PackageParser.ProviderIntentInfo info) {
14447            return packageName.equals(info.provider.owner.packageName);
14448        }
14449
14450        @Override
14451        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14452                int match, int userId) {
14453            if (!sUserManager.exists(userId))
14454                return null;
14455            final PackageParser.ProviderIntentInfo info = filter;
14456            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14457                return null;
14458            }
14459            final PackageParser.Provider provider = info.provider;
14460            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14461            if (ps == null) {
14462                return null;
14463            }
14464            final PackageUserState userState = ps.readUserState(userId);
14465            final boolean matchVisibleToInstantApp =
14466                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14467            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14468            // throw out filters that aren't visible to instant applications
14469            if (matchVisibleToInstantApp
14470                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14471                return null;
14472            }
14473            // throw out instant application filters if we're not explicitly requesting them
14474            if (!isInstantApp && userState.instantApp) {
14475                return null;
14476            }
14477            // throw out instant application filters if updates are available; will trigger
14478            // instant application resolution
14479            if (userState.instantApp && ps.isUpdateAvailable()) {
14480                return null;
14481            }
14482            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14483                    userState, userId);
14484            if (pi == null) {
14485                return null;
14486            }
14487            final ResolveInfo res = new ResolveInfo();
14488            res.providerInfo = pi;
14489            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14490                res.filter = filter;
14491            }
14492            res.priority = info.getPriority();
14493            res.preferredOrder = provider.owner.mPreferredOrder;
14494            res.match = match;
14495            res.isDefault = info.hasDefault;
14496            res.labelRes = info.labelRes;
14497            res.nonLocalizedLabel = info.nonLocalizedLabel;
14498            res.icon = info.icon;
14499            res.system = res.providerInfo.applicationInfo.isSystemApp();
14500            return res;
14501        }
14502
14503        @Override
14504        protected void sortResults(List<ResolveInfo> results) {
14505            Collections.sort(results, mResolvePrioritySorter);
14506        }
14507
14508        @Override
14509        protected void dumpFilter(PrintWriter out, String prefix,
14510                PackageParser.ProviderIntentInfo filter) {
14511            out.print(prefix);
14512            out.print(
14513                    Integer.toHexString(System.identityHashCode(filter.provider)));
14514            out.print(' ');
14515            filter.provider.printComponentShortName(out);
14516            out.print(" filter ");
14517            out.println(Integer.toHexString(System.identityHashCode(filter)));
14518        }
14519
14520        @Override
14521        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14522            return filter.provider;
14523        }
14524
14525        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14526            PackageParser.Provider provider = (PackageParser.Provider)label;
14527            out.print(prefix); out.print(
14528                    Integer.toHexString(System.identityHashCode(provider)));
14529                    out.print(' ');
14530                    provider.printComponentShortName(out);
14531            if (count > 1) {
14532                out.print(" ("); out.print(count); out.print(" filters)");
14533            }
14534            out.println();
14535        }
14536
14537        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14538                = new ArrayMap<ComponentName, PackageParser.Provider>();
14539        private int mFlags;
14540    }
14541
14542    static final class EphemeralIntentResolver
14543            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14544        /**
14545         * The result that has the highest defined order. Ordering applies on a
14546         * per-package basis. Mapping is from package name to Pair of order and
14547         * EphemeralResolveInfo.
14548         * <p>
14549         * NOTE: This is implemented as a field variable for convenience and efficiency.
14550         * By having a field variable, we're able to track filter ordering as soon as
14551         * a non-zero order is defined. Otherwise, multiple loops across the result set
14552         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14553         * this needs to be contained entirely within {@link #filterResults}.
14554         */
14555        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14556
14557        @Override
14558        protected AuxiliaryResolveInfo[] newArray(int size) {
14559            return new AuxiliaryResolveInfo[size];
14560        }
14561
14562        @Override
14563        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14564            return true;
14565        }
14566
14567        @Override
14568        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14569                int userId) {
14570            if (!sUserManager.exists(userId)) {
14571                return null;
14572            }
14573            final String packageName = responseObj.resolveInfo.getPackageName();
14574            final Integer order = responseObj.getOrder();
14575            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14576                    mOrderResult.get(packageName);
14577            // ordering is enabled and this item's order isn't high enough
14578            if (lastOrderResult != null && lastOrderResult.first >= order) {
14579                return null;
14580            }
14581            final InstantAppResolveInfo res = responseObj.resolveInfo;
14582            if (order > 0) {
14583                // non-zero order, enable ordering
14584                mOrderResult.put(packageName, new Pair<>(order, res));
14585            }
14586            return responseObj;
14587        }
14588
14589        @Override
14590        protected void filterResults(List<AuxiliaryResolveInfo> results) {
14591            // only do work if ordering is enabled [most of the time it won't be]
14592            if (mOrderResult.size() == 0) {
14593                return;
14594            }
14595            int resultSize = results.size();
14596            for (int i = 0; i < resultSize; i++) {
14597                final InstantAppResolveInfo info = results.get(i).resolveInfo;
14598                final String packageName = info.getPackageName();
14599                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14600                if (savedInfo == null) {
14601                    // package doesn't having ordering
14602                    continue;
14603                }
14604                if (savedInfo.second == info) {
14605                    // circled back to the highest ordered item; remove from order list
14606                    mOrderResult.remove(packageName);
14607                    if (mOrderResult.size() == 0) {
14608                        // no more ordered items
14609                        break;
14610                    }
14611                    continue;
14612                }
14613                // item has a worse order, remove it from the result list
14614                results.remove(i);
14615                resultSize--;
14616                i--;
14617            }
14618        }
14619    }
14620
14621    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14622            new Comparator<ResolveInfo>() {
14623        public int compare(ResolveInfo r1, ResolveInfo r2) {
14624            int v1 = r1.priority;
14625            int v2 = r2.priority;
14626            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14627            if (v1 != v2) {
14628                return (v1 > v2) ? -1 : 1;
14629            }
14630            v1 = r1.preferredOrder;
14631            v2 = r2.preferredOrder;
14632            if (v1 != v2) {
14633                return (v1 > v2) ? -1 : 1;
14634            }
14635            if (r1.isDefault != r2.isDefault) {
14636                return r1.isDefault ? -1 : 1;
14637            }
14638            v1 = r1.match;
14639            v2 = r2.match;
14640            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14641            if (v1 != v2) {
14642                return (v1 > v2) ? -1 : 1;
14643            }
14644            if (r1.system != r2.system) {
14645                return r1.system ? -1 : 1;
14646            }
14647            if (r1.activityInfo != null) {
14648                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14649            }
14650            if (r1.serviceInfo != null) {
14651                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14652            }
14653            if (r1.providerInfo != null) {
14654                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14655            }
14656            return 0;
14657        }
14658    };
14659
14660    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14661            new Comparator<ProviderInfo>() {
14662        public int compare(ProviderInfo p1, ProviderInfo p2) {
14663            final int v1 = p1.initOrder;
14664            final int v2 = p2.initOrder;
14665            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14666        }
14667    };
14668
14669    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14670            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14671            final int[] userIds) {
14672        mHandler.post(new Runnable() {
14673            @Override
14674            public void run() {
14675                try {
14676                    final IActivityManager am = ActivityManager.getService();
14677                    if (am == null) return;
14678                    final int[] resolvedUserIds;
14679                    if (userIds == null) {
14680                        resolvedUserIds = am.getRunningUserIds();
14681                    } else {
14682                        resolvedUserIds = userIds;
14683                    }
14684                    for (int id : resolvedUserIds) {
14685                        final Intent intent = new Intent(action,
14686                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14687                        if (extras != null) {
14688                            intent.putExtras(extras);
14689                        }
14690                        if (targetPkg != null) {
14691                            intent.setPackage(targetPkg);
14692                        }
14693                        // Modify the UID when posting to other users
14694                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14695                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14696                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14697                            intent.putExtra(Intent.EXTRA_UID, uid);
14698                        }
14699                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14700                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14701                        if (DEBUG_BROADCASTS) {
14702                            RuntimeException here = new RuntimeException("here");
14703                            here.fillInStackTrace();
14704                            Slog.d(TAG, "Sending to user " + id + ": "
14705                                    + intent.toShortString(false, true, false, false)
14706                                    + " " + intent.getExtras(), here);
14707                        }
14708                        am.broadcastIntent(null, intent, null, finishedReceiver,
14709                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14710                                null, finishedReceiver != null, false, id);
14711                    }
14712                } catch (RemoteException ex) {
14713                }
14714            }
14715        });
14716    }
14717
14718    /**
14719     * Check if the external storage media is available. This is true if there
14720     * is a mounted external storage medium or if the external storage is
14721     * emulated.
14722     */
14723    private boolean isExternalMediaAvailable() {
14724        return mMediaMounted || Environment.isExternalStorageEmulated();
14725    }
14726
14727    @Override
14728    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14729        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14730            return null;
14731        }
14732        // writer
14733        synchronized (mPackages) {
14734            if (!isExternalMediaAvailable()) {
14735                // If the external storage is no longer mounted at this point,
14736                // the caller may not have been able to delete all of this
14737                // packages files and can not delete any more.  Bail.
14738                return null;
14739            }
14740            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14741            if (lastPackage != null) {
14742                pkgs.remove(lastPackage);
14743            }
14744            if (pkgs.size() > 0) {
14745                return pkgs.get(0);
14746            }
14747        }
14748        return null;
14749    }
14750
14751    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14752        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14753                userId, andCode ? 1 : 0, packageName);
14754        if (mSystemReady) {
14755            msg.sendToTarget();
14756        } else {
14757            if (mPostSystemReadyMessages == null) {
14758                mPostSystemReadyMessages = new ArrayList<>();
14759            }
14760            mPostSystemReadyMessages.add(msg);
14761        }
14762    }
14763
14764    void startCleaningPackages() {
14765        // reader
14766        if (!isExternalMediaAvailable()) {
14767            return;
14768        }
14769        synchronized (mPackages) {
14770            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14771                return;
14772            }
14773        }
14774        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14775        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14776        IActivityManager am = ActivityManager.getService();
14777        if (am != null) {
14778            int dcsUid = -1;
14779            synchronized (mPackages) {
14780                if (!mDefaultContainerWhitelisted) {
14781                    mDefaultContainerWhitelisted = true;
14782                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14783                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14784                }
14785            }
14786            try {
14787                if (dcsUid > 0) {
14788                    am.backgroundWhitelistUid(dcsUid);
14789                }
14790                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14791                        UserHandle.USER_SYSTEM);
14792            } catch (RemoteException e) {
14793            }
14794        }
14795    }
14796
14797    @Override
14798    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14799            int installFlags, String installerPackageName, int userId) {
14800        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14801
14802        final int callingUid = Binder.getCallingUid();
14803        enforceCrossUserPermission(callingUid, userId,
14804                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14805
14806        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14807            try {
14808                if (observer != null) {
14809                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14810                }
14811            } catch (RemoteException re) {
14812            }
14813            return;
14814        }
14815
14816        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14817            installFlags |= PackageManager.INSTALL_FROM_ADB;
14818
14819        } else {
14820            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14821            // about installerPackageName.
14822
14823            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14824            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14825        }
14826
14827        UserHandle user;
14828        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14829            user = UserHandle.ALL;
14830        } else {
14831            user = new UserHandle(userId);
14832        }
14833
14834        // Only system components can circumvent runtime permissions when installing.
14835        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14836                && mContext.checkCallingOrSelfPermission(Manifest.permission
14837                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14838            throw new SecurityException("You need the "
14839                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14840                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14841        }
14842
14843        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14844                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14845            throw new IllegalArgumentException(
14846                    "New installs into ASEC containers no longer supported");
14847        }
14848
14849        final File originFile = new File(originPath);
14850        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14851
14852        final Message msg = mHandler.obtainMessage(INIT_COPY);
14853        final VerificationInfo verificationInfo = new VerificationInfo(
14854                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14855        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14856                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14857                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14858                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14859        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14860        msg.obj = params;
14861
14862        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14863                System.identityHashCode(msg.obj));
14864        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14865                System.identityHashCode(msg.obj));
14866
14867        mHandler.sendMessage(msg);
14868    }
14869
14870
14871    /**
14872     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14873     * it is acting on behalf on an enterprise or the user).
14874     *
14875     * Note that the ordering of the conditionals in this method is important. The checks we perform
14876     * are as follows, in this order:
14877     *
14878     * 1) If the install is being performed by a system app, we can trust the app to have set the
14879     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14880     *    what it is.
14881     * 2) If the install is being performed by a device or profile owner app, the install reason
14882     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14883     *    set the install reason correctly. If the app targets an older SDK version where install
14884     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14885     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14886     * 3) In all other cases, the install is being performed by a regular app that is neither part
14887     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14888     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14889     *    set to enterprise policy and if so, change it to unknown instead.
14890     */
14891    private int fixUpInstallReason(String installerPackageName, int installerUid,
14892            int installReason) {
14893        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14894                == PERMISSION_GRANTED) {
14895            // If the install is being performed by a system app, we trust that app to have set the
14896            // install reason correctly.
14897            return installReason;
14898        }
14899
14900        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14901            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14902        if (dpm != null) {
14903            ComponentName owner = null;
14904            try {
14905                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14906                if (owner == null) {
14907                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14908                }
14909            } catch (RemoteException e) {
14910            }
14911            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14912                // If the install is being performed by a device or profile owner, the install
14913                // reason should be enterprise policy.
14914                return PackageManager.INSTALL_REASON_POLICY;
14915            }
14916        }
14917
14918        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14919            // If the install is being performed by a regular app (i.e. neither system app nor
14920            // device or profile owner), we have no reason to believe that the app is acting on
14921            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14922            // change it to unknown instead.
14923            return PackageManager.INSTALL_REASON_UNKNOWN;
14924        }
14925
14926        // If the install is being performed by a regular app and the install reason was set to any
14927        // value but enterprise policy, leave the install reason unchanged.
14928        return installReason;
14929    }
14930
14931    void installStage(String packageName, File stagedDir, String stagedCid,
14932            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14933            String installerPackageName, int installerUid, UserHandle user,
14934            Certificate[][] certificates) {
14935        if (DEBUG_EPHEMERAL) {
14936            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14937                Slog.d(TAG, "Ephemeral install of " + packageName);
14938            }
14939        }
14940        final VerificationInfo verificationInfo = new VerificationInfo(
14941                sessionParams.originatingUri, sessionParams.referrerUri,
14942                sessionParams.originatingUid, installerUid);
14943
14944        final OriginInfo origin;
14945        if (stagedDir != null) {
14946            origin = OriginInfo.fromStagedFile(stagedDir);
14947        } else {
14948            origin = OriginInfo.fromStagedContainer(stagedCid);
14949        }
14950
14951        final Message msg = mHandler.obtainMessage(INIT_COPY);
14952        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14953                sessionParams.installReason);
14954        final InstallParams params = new InstallParams(origin, null, observer,
14955                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14956                verificationInfo, user, sessionParams.abiOverride,
14957                sessionParams.grantedRuntimePermissions, certificates, installReason);
14958        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14959        msg.obj = params;
14960
14961        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14962                System.identityHashCode(msg.obj));
14963        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14964                System.identityHashCode(msg.obj));
14965
14966        mHandler.sendMessage(msg);
14967    }
14968
14969    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14970            int userId) {
14971        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14972        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14973                false /*startReceiver*/, pkgSetting.appId, userId);
14974
14975        // Send a session commit broadcast
14976        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14977        info.installReason = pkgSetting.getInstallReason(userId);
14978        info.appPackageName = packageName;
14979        sendSessionCommitBroadcast(info, userId);
14980    }
14981
14982    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14983            boolean includeStopped, int appId, int... userIds) {
14984        if (ArrayUtils.isEmpty(userIds)) {
14985            return;
14986        }
14987        Bundle extras = new Bundle(1);
14988        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14989        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14990
14991        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14992                packageName, extras, 0, null, null, userIds);
14993        if (sendBootCompleted) {
14994            mHandler.post(() -> {
14995                        for (int userId : userIds) {
14996                            sendBootCompletedBroadcastToSystemApp(
14997                                    packageName, includeStopped, userId);
14998                        }
14999                    }
15000            );
15001        }
15002    }
15003
15004    /**
15005     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
15006     * automatically without needing an explicit launch.
15007     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
15008     */
15009    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
15010            int userId) {
15011        // If user is not running, the app didn't miss any broadcast
15012        if (!mUserManagerInternal.isUserRunning(userId)) {
15013            return;
15014        }
15015        final IActivityManager am = ActivityManager.getService();
15016        try {
15017            // Deliver LOCKED_BOOT_COMPLETED first
15018            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
15019                    .setPackage(packageName);
15020            if (includeStopped) {
15021                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15022            }
15023            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
15024            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
15025                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15026
15027            // Deliver BOOT_COMPLETED only if user is unlocked
15028            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
15029                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
15030                if (includeStopped) {
15031                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
15032                }
15033                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
15034                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
15035            }
15036        } catch (RemoteException e) {
15037            throw e.rethrowFromSystemServer();
15038        }
15039    }
15040
15041    @Override
15042    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
15043            int userId) {
15044        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15045        PackageSetting pkgSetting;
15046        final int callingUid = Binder.getCallingUid();
15047        enforceCrossUserPermission(callingUid, userId,
15048                true /* requireFullPermission */, true /* checkShell */,
15049                "setApplicationHiddenSetting for user " + userId);
15050
15051        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
15052            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
15053            return false;
15054        }
15055
15056        long callingId = Binder.clearCallingIdentity();
15057        try {
15058            boolean sendAdded = false;
15059            boolean sendRemoved = false;
15060            // writer
15061            synchronized (mPackages) {
15062                pkgSetting = mSettings.mPackages.get(packageName);
15063                if (pkgSetting == null) {
15064                    return false;
15065                }
15066                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15067                    return false;
15068                }
15069                // Do not allow "android" is being disabled
15070                if ("android".equals(packageName)) {
15071                    Slog.w(TAG, "Cannot hide package: android");
15072                    return false;
15073                }
15074                // Cannot hide static shared libs as they are considered
15075                // a part of the using app (emulating static linking). Also
15076                // static libs are installed always on internal storage.
15077                PackageParser.Package pkg = mPackages.get(packageName);
15078                if (pkg != null && pkg.staticSharedLibName != null) {
15079                    Slog.w(TAG, "Cannot hide package: " + packageName
15080                            + " providing static shared library: "
15081                            + pkg.staticSharedLibName);
15082                    return false;
15083                }
15084                // Only allow protected packages to hide themselves.
15085                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
15086                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15087                    Slog.w(TAG, "Not hiding protected package: " + packageName);
15088                    return false;
15089                }
15090
15091                if (pkgSetting.getHidden(userId) != hidden) {
15092                    pkgSetting.setHidden(hidden, userId);
15093                    mSettings.writePackageRestrictionsLPr(userId);
15094                    if (hidden) {
15095                        sendRemoved = true;
15096                    } else {
15097                        sendAdded = true;
15098                    }
15099                }
15100            }
15101            if (sendAdded) {
15102                sendPackageAddedForUser(packageName, pkgSetting, userId);
15103                return true;
15104            }
15105            if (sendRemoved) {
15106                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
15107                        "hiding pkg");
15108                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
15109                return true;
15110            }
15111        } finally {
15112            Binder.restoreCallingIdentity(callingId);
15113        }
15114        return false;
15115    }
15116
15117    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
15118            int userId) {
15119        final PackageRemovedInfo info = new PackageRemovedInfo(this);
15120        info.removedPackage = packageName;
15121        info.installerPackageName = pkgSetting.installerPackageName;
15122        info.removedUsers = new int[] {userId};
15123        info.broadcastUsers = new int[] {userId};
15124        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
15125        info.sendPackageRemovedBroadcasts(true /*killApp*/);
15126    }
15127
15128    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
15129        if (pkgList.length > 0) {
15130            Bundle extras = new Bundle(1);
15131            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
15132
15133            sendPackageBroadcast(
15134                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
15135                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
15136                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
15137                    new int[] {userId});
15138        }
15139    }
15140
15141    /**
15142     * Returns true if application is not found or there was an error. Otherwise it returns
15143     * the hidden state of the package for the given user.
15144     */
15145    @Override
15146    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
15147        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15148        final int callingUid = Binder.getCallingUid();
15149        enforceCrossUserPermission(callingUid, userId,
15150                true /* requireFullPermission */, false /* checkShell */,
15151                "getApplicationHidden for user " + userId);
15152        PackageSetting ps;
15153        long callingId = Binder.clearCallingIdentity();
15154        try {
15155            // writer
15156            synchronized (mPackages) {
15157                ps = mSettings.mPackages.get(packageName);
15158                if (ps == null) {
15159                    return true;
15160                }
15161                if (filterAppAccessLPr(ps, callingUid, userId)) {
15162                    return true;
15163                }
15164                return ps.getHidden(userId);
15165            }
15166        } finally {
15167            Binder.restoreCallingIdentity(callingId);
15168        }
15169    }
15170
15171    /**
15172     * @hide
15173     */
15174    @Override
15175    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
15176            int installReason) {
15177        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
15178                null);
15179        PackageSetting pkgSetting;
15180        final int callingUid = Binder.getCallingUid();
15181        enforceCrossUserPermission(callingUid, userId,
15182                true /* requireFullPermission */, true /* checkShell */,
15183                "installExistingPackage for user " + userId);
15184        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
15185            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
15186        }
15187
15188        long callingId = Binder.clearCallingIdentity();
15189        try {
15190            boolean installed = false;
15191            final boolean instantApp =
15192                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15193            final boolean fullApp =
15194                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
15195
15196            // writer
15197            synchronized (mPackages) {
15198                pkgSetting = mSettings.mPackages.get(packageName);
15199                if (pkgSetting == null) {
15200                    return PackageManager.INSTALL_FAILED_INVALID_URI;
15201                }
15202                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
15203                    // only allow the existing package to be used if it's installed as a full
15204                    // application for at least one user
15205                    boolean installAllowed = false;
15206                    for (int checkUserId : sUserManager.getUserIds()) {
15207                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
15208                        if (installAllowed) {
15209                            break;
15210                        }
15211                    }
15212                    if (!installAllowed) {
15213                        return PackageManager.INSTALL_FAILED_INVALID_URI;
15214                    }
15215                }
15216                if (!pkgSetting.getInstalled(userId)) {
15217                    pkgSetting.setInstalled(true, userId);
15218                    pkgSetting.setHidden(false, userId);
15219                    pkgSetting.setInstallReason(installReason, userId);
15220                    mSettings.writePackageRestrictionsLPr(userId);
15221                    mSettings.writeKernelMappingLPr(pkgSetting);
15222                    installed = true;
15223                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15224                    // upgrade app from instant to full; we don't allow app downgrade
15225                    installed = true;
15226                }
15227                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
15228            }
15229
15230            if (installed) {
15231                if (pkgSetting.pkg != null) {
15232                    synchronized (mInstallLock) {
15233                        // We don't need to freeze for a brand new install
15234                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
15235                    }
15236                }
15237                sendPackageAddedForUser(packageName, pkgSetting, userId);
15238                synchronized (mPackages) {
15239                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
15240                }
15241            }
15242        } finally {
15243            Binder.restoreCallingIdentity(callingId);
15244        }
15245
15246        return PackageManager.INSTALL_SUCCEEDED;
15247    }
15248
15249    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
15250            boolean instantApp, boolean fullApp) {
15251        // no state specified; do nothing
15252        if (!instantApp && !fullApp) {
15253            return;
15254        }
15255        if (userId != UserHandle.USER_ALL) {
15256            if (instantApp && !pkgSetting.getInstantApp(userId)) {
15257                pkgSetting.setInstantApp(true /*instantApp*/, userId);
15258            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15259                pkgSetting.setInstantApp(false /*instantApp*/, userId);
15260            }
15261        } else {
15262            for (int currentUserId : sUserManager.getUserIds()) {
15263                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
15264                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
15265                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
15266                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
15267                }
15268            }
15269        }
15270    }
15271
15272    boolean isUserRestricted(int userId, String restrictionKey) {
15273        Bundle restrictions = sUserManager.getUserRestrictions(userId);
15274        if (restrictions.getBoolean(restrictionKey, false)) {
15275            Log.w(TAG, "User is restricted: " + restrictionKey);
15276            return true;
15277        }
15278        return false;
15279    }
15280
15281    @Override
15282    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
15283            int userId) {
15284        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15285        final int callingUid = Binder.getCallingUid();
15286        enforceCrossUserPermission(callingUid, userId,
15287                true /* requireFullPermission */, true /* checkShell */,
15288                "setPackagesSuspended for user " + userId);
15289
15290        if (ArrayUtils.isEmpty(packageNames)) {
15291            return packageNames;
15292        }
15293
15294        // List of package names for whom the suspended state has changed.
15295        List<String> changedPackages = new ArrayList<>(packageNames.length);
15296        // List of package names for whom the suspended state is not set as requested in this
15297        // method.
15298        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
15299        long callingId = Binder.clearCallingIdentity();
15300        try {
15301            for (int i = 0; i < packageNames.length; i++) {
15302                String packageName = packageNames[i];
15303                boolean changed = false;
15304                final int appId;
15305                synchronized (mPackages) {
15306                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
15307                    if (pkgSetting == null
15308                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15309                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
15310                                + "\". Skipping suspending/un-suspending.");
15311                        unactionedPackages.add(packageName);
15312                        continue;
15313                    }
15314                    appId = pkgSetting.appId;
15315                    if (pkgSetting.getSuspended(userId) != suspended) {
15316                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
15317                            unactionedPackages.add(packageName);
15318                            continue;
15319                        }
15320                        pkgSetting.setSuspended(suspended, userId);
15321                        mSettings.writePackageRestrictionsLPr(userId);
15322                        changed = true;
15323                        changedPackages.add(packageName);
15324                    }
15325                }
15326
15327                if (changed && suspended) {
15328                    killApplication(packageName, UserHandle.getUid(userId, appId),
15329                            "suspending package");
15330                }
15331            }
15332        } finally {
15333            Binder.restoreCallingIdentity(callingId);
15334        }
15335
15336        if (!changedPackages.isEmpty()) {
15337            sendPackagesSuspendedForUser(changedPackages.toArray(
15338                    new String[changedPackages.size()]), userId, suspended);
15339        }
15340
15341        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15342    }
15343
15344    @Override
15345    public boolean isPackageSuspendedForUser(String packageName, int userId) {
15346        final int callingUid = Binder.getCallingUid();
15347        enforceCrossUserPermission(callingUid, userId,
15348                true /* requireFullPermission */, false /* checkShell */,
15349                "isPackageSuspendedForUser for user " + userId);
15350        synchronized (mPackages) {
15351            final PackageSetting ps = mSettings.mPackages.get(packageName);
15352            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15353                throw new IllegalArgumentException("Unknown target package: " + packageName);
15354            }
15355            return ps.getSuspended(userId);
15356        }
15357    }
15358
15359    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15360        if (isPackageDeviceAdmin(packageName, userId)) {
15361            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15362                    + "\": has an active device admin");
15363            return false;
15364        }
15365
15366        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15367        if (packageName.equals(activeLauncherPackageName)) {
15368            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15369                    + "\": contains the active launcher");
15370            return false;
15371        }
15372
15373        if (packageName.equals(mRequiredInstallerPackage)) {
15374            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15375                    + "\": required for package installation");
15376            return false;
15377        }
15378
15379        if (packageName.equals(mRequiredUninstallerPackage)) {
15380            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15381                    + "\": required for package uninstallation");
15382            return false;
15383        }
15384
15385        if (packageName.equals(mRequiredVerifierPackage)) {
15386            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15387                    + "\": required for package verification");
15388            return false;
15389        }
15390
15391        if (packageName.equals(getDefaultDialerPackageName(userId))) {
15392            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15393                    + "\": is the default dialer");
15394            return false;
15395        }
15396
15397        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15398            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15399                    + "\": protected package");
15400            return false;
15401        }
15402
15403        // Cannot suspend static shared libs as they are considered
15404        // a part of the using app (emulating static linking). Also
15405        // static libs are installed always on internal storage.
15406        PackageParser.Package pkg = mPackages.get(packageName);
15407        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15408            Slog.w(TAG, "Cannot suspend package: " + packageName
15409                    + " providing static shared library: "
15410                    + pkg.staticSharedLibName);
15411            return false;
15412        }
15413
15414        return true;
15415    }
15416
15417    private String getActiveLauncherPackageName(int userId) {
15418        Intent intent = new Intent(Intent.ACTION_MAIN);
15419        intent.addCategory(Intent.CATEGORY_HOME);
15420        ResolveInfo resolveInfo = resolveIntent(
15421                intent,
15422                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15423                PackageManager.MATCH_DEFAULT_ONLY,
15424                userId);
15425
15426        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15427    }
15428
15429    private String getDefaultDialerPackageName(int userId) {
15430        synchronized (mPackages) {
15431            return mSettings.getDefaultDialerPackageNameLPw(userId);
15432        }
15433    }
15434
15435    @Override
15436    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15437        mContext.enforceCallingOrSelfPermission(
15438                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15439                "Only package verification agents can verify applications");
15440
15441        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15442        final PackageVerificationResponse response = new PackageVerificationResponse(
15443                verificationCode, Binder.getCallingUid());
15444        msg.arg1 = id;
15445        msg.obj = response;
15446        mHandler.sendMessage(msg);
15447    }
15448
15449    @Override
15450    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15451            long millisecondsToDelay) {
15452        mContext.enforceCallingOrSelfPermission(
15453                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15454                "Only package verification agents can extend verification timeouts");
15455
15456        final PackageVerificationState state = mPendingVerification.get(id);
15457        final PackageVerificationResponse response = new PackageVerificationResponse(
15458                verificationCodeAtTimeout, Binder.getCallingUid());
15459
15460        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15461            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15462        }
15463        if (millisecondsToDelay < 0) {
15464            millisecondsToDelay = 0;
15465        }
15466        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15467                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15468            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15469        }
15470
15471        if ((state != null) && !state.timeoutExtended()) {
15472            state.extendTimeout();
15473
15474            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15475            msg.arg1 = id;
15476            msg.obj = response;
15477            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15478        }
15479    }
15480
15481    private void broadcastPackageVerified(int verificationId, Uri packageUri,
15482            int verificationCode, UserHandle user) {
15483        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15484        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15485        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15486        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15487        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15488
15489        mContext.sendBroadcastAsUser(intent, user,
15490                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15491    }
15492
15493    private ComponentName matchComponentForVerifier(String packageName,
15494            List<ResolveInfo> receivers) {
15495        ActivityInfo targetReceiver = null;
15496
15497        final int NR = receivers.size();
15498        for (int i = 0; i < NR; i++) {
15499            final ResolveInfo info = receivers.get(i);
15500            if (info.activityInfo == null) {
15501                continue;
15502            }
15503
15504            if (packageName.equals(info.activityInfo.packageName)) {
15505                targetReceiver = info.activityInfo;
15506                break;
15507            }
15508        }
15509
15510        if (targetReceiver == null) {
15511            return null;
15512        }
15513
15514        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15515    }
15516
15517    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15518            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15519        if (pkgInfo.verifiers.length == 0) {
15520            return null;
15521        }
15522
15523        final int N = pkgInfo.verifiers.length;
15524        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15525        for (int i = 0; i < N; i++) {
15526            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15527
15528            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15529                    receivers);
15530            if (comp == null) {
15531                continue;
15532            }
15533
15534            final int verifierUid = getUidForVerifier(verifierInfo);
15535            if (verifierUid == -1) {
15536                continue;
15537            }
15538
15539            if (DEBUG_VERIFY) {
15540                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15541                        + " with the correct signature");
15542            }
15543            sufficientVerifiers.add(comp);
15544            verificationState.addSufficientVerifier(verifierUid);
15545        }
15546
15547        return sufficientVerifiers;
15548    }
15549
15550    private int getUidForVerifier(VerifierInfo verifierInfo) {
15551        synchronized (mPackages) {
15552            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15553            if (pkg == null) {
15554                return -1;
15555            } else if (pkg.mSignatures.length != 1) {
15556                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15557                        + " has more than one signature; ignoring");
15558                return -1;
15559            }
15560
15561            /*
15562             * If the public key of the package's signature does not match
15563             * our expected public key, then this is a different package and
15564             * we should skip.
15565             */
15566
15567            final byte[] expectedPublicKey;
15568            try {
15569                final Signature verifierSig = pkg.mSignatures[0];
15570                final PublicKey publicKey = verifierSig.getPublicKey();
15571                expectedPublicKey = publicKey.getEncoded();
15572            } catch (CertificateException e) {
15573                return -1;
15574            }
15575
15576            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15577
15578            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15579                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15580                        + " does not have the expected public key; ignoring");
15581                return -1;
15582            }
15583
15584            return pkg.applicationInfo.uid;
15585        }
15586    }
15587
15588    @Override
15589    public void finishPackageInstall(int token, boolean didLaunch) {
15590        enforceSystemOrRoot("Only the system is allowed to finish installs");
15591
15592        if (DEBUG_INSTALL) {
15593            Slog.v(TAG, "BM finishing package install for " + token);
15594        }
15595        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15596
15597        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15598        mHandler.sendMessage(msg);
15599    }
15600
15601    /**
15602     * Get the verification agent timeout.  Used for both the APK verifier and the
15603     * intent filter verifier.
15604     *
15605     * @return verification timeout in milliseconds
15606     */
15607    private long getVerificationTimeout() {
15608        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15609                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15610                DEFAULT_VERIFICATION_TIMEOUT);
15611    }
15612
15613    /**
15614     * Get the default verification agent response code.
15615     *
15616     * @return default verification response code
15617     */
15618    private int getDefaultVerificationResponse(UserHandle user) {
15619        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15620            return PackageManager.VERIFICATION_REJECT;
15621        }
15622        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15623                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15624                DEFAULT_VERIFICATION_RESPONSE);
15625    }
15626
15627    /**
15628     * Check whether or not package verification has been enabled.
15629     *
15630     * @return true if verification should be performed
15631     */
15632    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15633        if (!DEFAULT_VERIFY_ENABLE) {
15634            return false;
15635        }
15636
15637        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15638
15639        // Check if installing from ADB
15640        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15641            // Do not run verification in a test harness environment
15642            if (ActivityManager.isRunningInTestHarness()) {
15643                return false;
15644            }
15645            if (ensureVerifyAppsEnabled) {
15646                return true;
15647            }
15648            // Check if the developer does not want package verification for ADB installs
15649            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15650                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15651                return false;
15652            }
15653        } else {
15654            // only when not installed from ADB, skip verification for instant apps when
15655            // the installer and verifier are the same.
15656            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15657                if (mInstantAppInstallerActivity != null
15658                        && mInstantAppInstallerActivity.packageName.equals(
15659                                mRequiredVerifierPackage)) {
15660                    try {
15661                        mContext.getSystemService(AppOpsManager.class)
15662                                .checkPackage(installerUid, mRequiredVerifierPackage);
15663                        if (DEBUG_VERIFY) {
15664                            Slog.i(TAG, "disable verification for instant app");
15665                        }
15666                        return false;
15667                    } catch (SecurityException ignore) { }
15668                }
15669            }
15670        }
15671
15672        if (ensureVerifyAppsEnabled) {
15673            return true;
15674        }
15675
15676        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15677                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15678    }
15679
15680    @Override
15681    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15682            throws RemoteException {
15683        mContext.enforceCallingOrSelfPermission(
15684                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15685                "Only intentfilter verification agents can verify applications");
15686
15687        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15688        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15689                Binder.getCallingUid(), verificationCode, failedDomains);
15690        msg.arg1 = id;
15691        msg.obj = response;
15692        mHandler.sendMessage(msg);
15693    }
15694
15695    @Override
15696    public int getIntentVerificationStatus(String packageName, int userId) {
15697        final int callingUid = Binder.getCallingUid();
15698        if (UserHandle.getUserId(callingUid) != userId) {
15699            mContext.enforceCallingOrSelfPermission(
15700                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15701                    "getIntentVerificationStatus" + userId);
15702        }
15703        if (getInstantAppPackageName(callingUid) != null) {
15704            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15705        }
15706        synchronized (mPackages) {
15707            final PackageSetting ps = mSettings.mPackages.get(packageName);
15708            if (ps == null
15709                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15710                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15711            }
15712            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15713        }
15714    }
15715
15716    @Override
15717    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15718        mContext.enforceCallingOrSelfPermission(
15719                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15720
15721        boolean result = false;
15722        synchronized (mPackages) {
15723            final PackageSetting ps = mSettings.mPackages.get(packageName);
15724            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15725                return false;
15726            }
15727            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15728        }
15729        if (result) {
15730            scheduleWritePackageRestrictionsLocked(userId);
15731        }
15732        return result;
15733    }
15734
15735    @Override
15736    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15737            String packageName) {
15738        final int callingUid = Binder.getCallingUid();
15739        if (getInstantAppPackageName(callingUid) != null) {
15740            return ParceledListSlice.emptyList();
15741        }
15742        synchronized (mPackages) {
15743            final PackageSetting ps = mSettings.mPackages.get(packageName);
15744            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15745                return ParceledListSlice.emptyList();
15746            }
15747            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15748        }
15749    }
15750
15751    @Override
15752    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15753        if (TextUtils.isEmpty(packageName)) {
15754            return ParceledListSlice.emptyList();
15755        }
15756        final int callingUid = Binder.getCallingUid();
15757        final int callingUserId = UserHandle.getUserId(callingUid);
15758        synchronized (mPackages) {
15759            PackageParser.Package pkg = mPackages.get(packageName);
15760            if (pkg == null || pkg.activities == null) {
15761                return ParceledListSlice.emptyList();
15762            }
15763            if (pkg.mExtras == null) {
15764                return ParceledListSlice.emptyList();
15765            }
15766            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15767            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15768                return ParceledListSlice.emptyList();
15769            }
15770            final int count = pkg.activities.size();
15771            ArrayList<IntentFilter> result = new ArrayList<>();
15772            for (int n=0; n<count; n++) {
15773                PackageParser.Activity activity = pkg.activities.get(n);
15774                if (activity.intents != null && activity.intents.size() > 0) {
15775                    result.addAll(activity.intents);
15776                }
15777            }
15778            return new ParceledListSlice<>(result);
15779        }
15780    }
15781
15782    @Override
15783    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15784        mContext.enforceCallingOrSelfPermission(
15785                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15786        if (UserHandle.getCallingUserId() != userId) {
15787            mContext.enforceCallingOrSelfPermission(
15788                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15789        }
15790
15791        synchronized (mPackages) {
15792            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15793            if (packageName != null) {
15794                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15795                        packageName, userId);
15796            }
15797            return result;
15798        }
15799    }
15800
15801    @Override
15802    public String getDefaultBrowserPackageName(int userId) {
15803        if (UserHandle.getCallingUserId() != userId) {
15804            mContext.enforceCallingOrSelfPermission(
15805                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15806        }
15807        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15808            return null;
15809        }
15810        synchronized (mPackages) {
15811            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15812        }
15813    }
15814
15815    /**
15816     * Get the "allow unknown sources" setting.
15817     *
15818     * @return the current "allow unknown sources" setting
15819     */
15820    private int getUnknownSourcesSettings() {
15821        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15822                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15823                -1);
15824    }
15825
15826    @Override
15827    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15828        final int callingUid = Binder.getCallingUid();
15829        if (getInstantAppPackageName(callingUid) != null) {
15830            return;
15831        }
15832        // writer
15833        synchronized (mPackages) {
15834            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15835            if (targetPackageSetting == null
15836                    || filterAppAccessLPr(
15837                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15838                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15839            }
15840
15841            PackageSetting installerPackageSetting;
15842            if (installerPackageName != null) {
15843                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15844                if (installerPackageSetting == null) {
15845                    throw new IllegalArgumentException("Unknown installer package: "
15846                            + installerPackageName);
15847                }
15848            } else {
15849                installerPackageSetting = null;
15850            }
15851
15852            Signature[] callerSignature;
15853            Object obj = mSettings.getUserIdLPr(callingUid);
15854            if (obj != null) {
15855                if (obj instanceof SharedUserSetting) {
15856                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15857                } else if (obj instanceof PackageSetting) {
15858                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15859                } else {
15860                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15861                }
15862            } else {
15863                throw new SecurityException("Unknown calling UID: " + callingUid);
15864            }
15865
15866            // Verify: can't set installerPackageName to a package that is
15867            // not signed with the same cert as the caller.
15868            if (installerPackageSetting != null) {
15869                if (compareSignatures(callerSignature,
15870                        installerPackageSetting.signatures.mSignatures)
15871                        != PackageManager.SIGNATURE_MATCH) {
15872                    throw new SecurityException(
15873                            "Caller does not have same cert as new installer package "
15874                            + installerPackageName);
15875                }
15876            }
15877
15878            // Verify: if target already has an installer package, it must
15879            // be signed with the same cert as the caller.
15880            if (targetPackageSetting.installerPackageName != null) {
15881                PackageSetting setting = mSettings.mPackages.get(
15882                        targetPackageSetting.installerPackageName);
15883                // If the currently set package isn't valid, then it's always
15884                // okay to change it.
15885                if (setting != null) {
15886                    if (compareSignatures(callerSignature,
15887                            setting.signatures.mSignatures)
15888                            != PackageManager.SIGNATURE_MATCH) {
15889                        throw new SecurityException(
15890                                "Caller does not have same cert as old installer package "
15891                                + targetPackageSetting.installerPackageName);
15892                    }
15893                }
15894            }
15895
15896            // Okay!
15897            targetPackageSetting.installerPackageName = installerPackageName;
15898            if (installerPackageName != null) {
15899                mSettings.mInstallerPackages.add(installerPackageName);
15900            }
15901            scheduleWriteSettingsLocked();
15902        }
15903    }
15904
15905    @Override
15906    public void setApplicationCategoryHint(String packageName, int categoryHint,
15907            String callerPackageName) {
15908        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15909            throw new SecurityException("Instant applications don't have access to this method");
15910        }
15911        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15912                callerPackageName);
15913        synchronized (mPackages) {
15914            PackageSetting ps = mSettings.mPackages.get(packageName);
15915            if (ps == null) {
15916                throw new IllegalArgumentException("Unknown target package " + packageName);
15917            }
15918            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15919                throw new IllegalArgumentException("Unknown target package " + packageName);
15920            }
15921            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15922                throw new IllegalArgumentException("Calling package " + callerPackageName
15923                        + " is not installer for " + packageName);
15924            }
15925
15926            if (ps.categoryHint != categoryHint) {
15927                ps.categoryHint = categoryHint;
15928                scheduleWriteSettingsLocked();
15929            }
15930        }
15931    }
15932
15933    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15934        // Queue up an async operation since the package installation may take a little while.
15935        mHandler.post(new Runnable() {
15936            public void run() {
15937                mHandler.removeCallbacks(this);
15938                 // Result object to be returned
15939                PackageInstalledInfo res = new PackageInstalledInfo();
15940                res.setReturnCode(currentStatus);
15941                res.uid = -1;
15942                res.pkg = null;
15943                res.removedInfo = null;
15944                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15945                    args.doPreInstall(res.returnCode);
15946                    synchronized (mInstallLock) {
15947                        installPackageTracedLI(args, res);
15948                    }
15949                    args.doPostInstall(res.returnCode, res.uid);
15950                }
15951
15952                // A restore should be performed at this point if (a) the install
15953                // succeeded, (b) the operation is not an update, and (c) the new
15954                // package has not opted out of backup participation.
15955                final boolean update = res.removedInfo != null
15956                        && res.removedInfo.removedPackage != null;
15957                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15958                boolean doRestore = !update
15959                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15960
15961                // Set up the post-install work request bookkeeping.  This will be used
15962                // and cleaned up by the post-install event handling regardless of whether
15963                // there's a restore pass performed.  Token values are >= 1.
15964                int token;
15965                if (mNextInstallToken < 0) mNextInstallToken = 1;
15966                token = mNextInstallToken++;
15967
15968                PostInstallData data = new PostInstallData(args, res);
15969                mRunningInstalls.put(token, data);
15970                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15971
15972                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15973                    // Pass responsibility to the Backup Manager.  It will perform a
15974                    // restore if appropriate, then pass responsibility back to the
15975                    // Package Manager to run the post-install observer callbacks
15976                    // and broadcasts.
15977                    IBackupManager bm = IBackupManager.Stub.asInterface(
15978                            ServiceManager.getService(Context.BACKUP_SERVICE));
15979                    if (bm != null) {
15980                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15981                                + " to BM for possible restore");
15982                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15983                        try {
15984                            // TODO: http://b/22388012
15985                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15986                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15987                            } else {
15988                                doRestore = false;
15989                            }
15990                        } catch (RemoteException e) {
15991                            // can't happen; the backup manager is local
15992                        } catch (Exception e) {
15993                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15994                            doRestore = false;
15995                        }
15996                    } else {
15997                        Slog.e(TAG, "Backup Manager not found!");
15998                        doRestore = false;
15999                    }
16000                }
16001
16002                if (!doRestore) {
16003                    // No restore possible, or the Backup Manager was mysteriously not
16004                    // available -- just fire the post-install work request directly.
16005                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
16006
16007                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
16008
16009                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
16010                    mHandler.sendMessage(msg);
16011                }
16012            }
16013        });
16014    }
16015
16016    /**
16017     * Callback from PackageSettings whenever an app is first transitioned out of the
16018     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
16019     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
16020     * here whether the app is the target of an ongoing install, and only send the
16021     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
16022     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
16023     * handling.
16024     */
16025    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
16026        // Serialize this with the rest of the install-process message chain.  In the
16027        // restore-at-install case, this Runnable will necessarily run before the
16028        // POST_INSTALL message is processed, so the contents of mRunningInstalls
16029        // are coherent.  In the non-restore case, the app has already completed install
16030        // and been launched through some other means, so it is not in a problematic
16031        // state for observers to see the FIRST_LAUNCH signal.
16032        mHandler.post(new Runnable() {
16033            @Override
16034            public void run() {
16035                for (int i = 0; i < mRunningInstalls.size(); i++) {
16036                    final PostInstallData data = mRunningInstalls.valueAt(i);
16037                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16038                        continue;
16039                    }
16040                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
16041                        // right package; but is it for the right user?
16042                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
16043                            if (userId == data.res.newUsers[uIndex]) {
16044                                if (DEBUG_BACKUP) {
16045                                    Slog.i(TAG, "Package " + pkgName
16046                                            + " being restored so deferring FIRST_LAUNCH");
16047                                }
16048                                return;
16049                            }
16050                        }
16051                    }
16052                }
16053                // didn't find it, so not being restored
16054                if (DEBUG_BACKUP) {
16055                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
16056                }
16057                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
16058            }
16059        });
16060    }
16061
16062    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
16063        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
16064                installerPkg, null, userIds);
16065    }
16066
16067    private abstract class HandlerParams {
16068        private static final int MAX_RETRIES = 4;
16069
16070        /**
16071         * Number of times startCopy() has been attempted and had a non-fatal
16072         * error.
16073         */
16074        private int mRetries = 0;
16075
16076        /** User handle for the user requesting the information or installation. */
16077        private final UserHandle mUser;
16078        String traceMethod;
16079        int traceCookie;
16080
16081        HandlerParams(UserHandle user) {
16082            mUser = user;
16083        }
16084
16085        UserHandle getUser() {
16086            return mUser;
16087        }
16088
16089        HandlerParams setTraceMethod(String traceMethod) {
16090            this.traceMethod = traceMethod;
16091            return this;
16092        }
16093
16094        HandlerParams setTraceCookie(int traceCookie) {
16095            this.traceCookie = traceCookie;
16096            return this;
16097        }
16098
16099        final boolean startCopy() {
16100            boolean res;
16101            try {
16102                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
16103
16104                if (++mRetries > MAX_RETRIES) {
16105                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
16106                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
16107                    handleServiceError();
16108                    return false;
16109                } else {
16110                    handleStartCopy();
16111                    res = true;
16112                }
16113            } catch (RemoteException e) {
16114                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
16115                mHandler.sendEmptyMessage(MCS_RECONNECT);
16116                res = false;
16117            }
16118            handleReturnCode();
16119            return res;
16120        }
16121
16122        final void serviceError() {
16123            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
16124            handleServiceError();
16125            handleReturnCode();
16126        }
16127
16128        abstract void handleStartCopy() throws RemoteException;
16129        abstract void handleServiceError();
16130        abstract void handleReturnCode();
16131    }
16132
16133    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
16134        for (File path : paths) {
16135            try {
16136                mcs.clearDirectory(path.getAbsolutePath());
16137            } catch (RemoteException e) {
16138            }
16139        }
16140    }
16141
16142    static class OriginInfo {
16143        /**
16144         * Location where install is coming from, before it has been
16145         * copied/renamed into place. This could be a single monolithic APK
16146         * file, or a cluster directory. This location may be untrusted.
16147         */
16148        final File file;
16149        final String cid;
16150
16151        /**
16152         * Flag indicating that {@link #file} or {@link #cid} has already been
16153         * staged, meaning downstream users don't need to defensively copy the
16154         * contents.
16155         */
16156        final boolean staged;
16157
16158        /**
16159         * Flag indicating that {@link #file} or {@link #cid} is an already
16160         * installed app that is being moved.
16161         */
16162        final boolean existing;
16163
16164        final String resolvedPath;
16165        final File resolvedFile;
16166
16167        static OriginInfo fromNothing() {
16168            return new OriginInfo(null, null, false, false);
16169        }
16170
16171        static OriginInfo fromUntrustedFile(File file) {
16172            return new OriginInfo(file, null, false, false);
16173        }
16174
16175        static OriginInfo fromExistingFile(File file) {
16176            return new OriginInfo(file, null, false, true);
16177        }
16178
16179        static OriginInfo fromStagedFile(File file) {
16180            return new OriginInfo(file, null, true, false);
16181        }
16182
16183        static OriginInfo fromStagedContainer(String cid) {
16184            return new OriginInfo(null, cid, true, false);
16185        }
16186
16187        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
16188            this.file = file;
16189            this.cid = cid;
16190            this.staged = staged;
16191            this.existing = existing;
16192
16193            if (cid != null) {
16194                resolvedPath = PackageHelper.getSdDir(cid);
16195                resolvedFile = new File(resolvedPath);
16196            } else if (file != null) {
16197                resolvedPath = file.getAbsolutePath();
16198                resolvedFile = file;
16199            } else {
16200                resolvedPath = null;
16201                resolvedFile = null;
16202            }
16203        }
16204    }
16205
16206    static class MoveInfo {
16207        final int moveId;
16208        final String fromUuid;
16209        final String toUuid;
16210        final String packageName;
16211        final String dataAppName;
16212        final int appId;
16213        final String seinfo;
16214        final int targetSdkVersion;
16215
16216        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
16217                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
16218            this.moveId = moveId;
16219            this.fromUuid = fromUuid;
16220            this.toUuid = toUuid;
16221            this.packageName = packageName;
16222            this.dataAppName = dataAppName;
16223            this.appId = appId;
16224            this.seinfo = seinfo;
16225            this.targetSdkVersion = targetSdkVersion;
16226        }
16227    }
16228
16229    static class VerificationInfo {
16230        /** A constant used to indicate that a uid value is not present. */
16231        public static final int NO_UID = -1;
16232
16233        /** URI referencing where the package was downloaded from. */
16234        final Uri originatingUri;
16235
16236        /** HTTP referrer URI associated with the originatingURI. */
16237        final Uri referrer;
16238
16239        /** UID of the application that the install request originated from. */
16240        final int originatingUid;
16241
16242        /** UID of application requesting the install */
16243        final int installerUid;
16244
16245        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
16246            this.originatingUri = originatingUri;
16247            this.referrer = referrer;
16248            this.originatingUid = originatingUid;
16249            this.installerUid = installerUid;
16250        }
16251    }
16252
16253    class InstallParams extends HandlerParams {
16254        final OriginInfo origin;
16255        final MoveInfo move;
16256        final IPackageInstallObserver2 observer;
16257        int installFlags;
16258        final String installerPackageName;
16259        final String volumeUuid;
16260        private InstallArgs mArgs;
16261        private int mRet;
16262        final String packageAbiOverride;
16263        final String[] grantedRuntimePermissions;
16264        final VerificationInfo verificationInfo;
16265        final Certificate[][] certificates;
16266        final int installReason;
16267
16268        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16269                int installFlags, String installerPackageName, String volumeUuid,
16270                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
16271                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
16272            super(user);
16273            this.origin = origin;
16274            this.move = move;
16275            this.observer = observer;
16276            this.installFlags = installFlags;
16277            this.installerPackageName = installerPackageName;
16278            this.volumeUuid = volumeUuid;
16279            this.verificationInfo = verificationInfo;
16280            this.packageAbiOverride = packageAbiOverride;
16281            this.grantedRuntimePermissions = grantedPermissions;
16282            this.certificates = certificates;
16283            this.installReason = installReason;
16284        }
16285
16286        @Override
16287        public String toString() {
16288            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
16289                    + " file=" + origin.file + " cid=" + origin.cid + "}";
16290        }
16291
16292        private int installLocationPolicy(PackageInfoLite pkgLite) {
16293            String packageName = pkgLite.packageName;
16294            int installLocation = pkgLite.installLocation;
16295            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16296            // reader
16297            synchronized (mPackages) {
16298                // Currently installed package which the new package is attempting to replace or
16299                // null if no such package is installed.
16300                PackageParser.Package installedPkg = mPackages.get(packageName);
16301                // Package which currently owns the data which the new package will own if installed.
16302                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
16303                // will be null whereas dataOwnerPkg will contain information about the package
16304                // which was uninstalled while keeping its data.
16305                PackageParser.Package dataOwnerPkg = installedPkg;
16306                if (dataOwnerPkg  == null) {
16307                    PackageSetting ps = mSettings.mPackages.get(packageName);
16308                    if (ps != null) {
16309                        dataOwnerPkg = ps.pkg;
16310                    }
16311                }
16312
16313                if (dataOwnerPkg != null) {
16314                    // If installed, the package will get access to data left on the device by its
16315                    // predecessor. As a security measure, this is permited only if this is not a
16316                    // version downgrade or if the predecessor package is marked as debuggable and
16317                    // a downgrade is explicitly requested.
16318                    //
16319                    // On debuggable platform builds, downgrades are permitted even for
16320                    // non-debuggable packages to make testing easier. Debuggable platform builds do
16321                    // not offer security guarantees and thus it's OK to disable some security
16322                    // mechanisms to make debugging/testing easier on those builds. However, even on
16323                    // debuggable builds downgrades of packages are permitted only if requested via
16324                    // installFlags. This is because we aim to keep the behavior of debuggable
16325                    // platform builds as close as possible to the behavior of non-debuggable
16326                    // platform builds.
16327                    final boolean downgradeRequested =
16328                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
16329                    final boolean packageDebuggable =
16330                                (dataOwnerPkg.applicationInfo.flags
16331                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
16332                    final boolean downgradePermitted =
16333                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
16334                    if (!downgradePermitted) {
16335                        try {
16336                            checkDowngrade(dataOwnerPkg, pkgLite);
16337                        } catch (PackageManagerException e) {
16338                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
16339                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
16340                        }
16341                    }
16342                }
16343
16344                if (installedPkg != null) {
16345                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16346                        // Check for updated system application.
16347                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16348                            if (onSd) {
16349                                Slog.w(TAG, "Cannot install update to system app on sdcard");
16350                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16351                            }
16352                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16353                        } else {
16354                            if (onSd) {
16355                                // Install flag overrides everything.
16356                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16357                            }
16358                            // If current upgrade specifies particular preference
16359                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16360                                // Application explicitly specified internal.
16361                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16362                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16363                                // App explictly prefers external. Let policy decide
16364                            } else {
16365                                // Prefer previous location
16366                                if (isExternal(installedPkg)) {
16367                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16368                                }
16369                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16370                            }
16371                        }
16372                    } else {
16373                        // Invalid install. Return error code
16374                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16375                    }
16376                }
16377            }
16378            // All the special cases have been taken care of.
16379            // Return result based on recommended install location.
16380            if (onSd) {
16381                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16382            }
16383            return pkgLite.recommendedInstallLocation;
16384        }
16385
16386        /*
16387         * Invoke remote method to get package information and install
16388         * location values. Override install location based on default
16389         * policy if needed and then create install arguments based
16390         * on the install location.
16391         */
16392        public void handleStartCopy() throws RemoteException {
16393            int ret = PackageManager.INSTALL_SUCCEEDED;
16394
16395            // If we're already staged, we've firmly committed to an install location
16396            if (origin.staged) {
16397                if (origin.file != null) {
16398                    installFlags |= PackageManager.INSTALL_INTERNAL;
16399                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16400                } else if (origin.cid != null) {
16401                    installFlags |= PackageManager.INSTALL_EXTERNAL;
16402                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
16403                } else {
16404                    throw new IllegalStateException("Invalid stage location");
16405                }
16406            }
16407
16408            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16409            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16410            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16411            PackageInfoLite pkgLite = null;
16412
16413            if (onInt && onSd) {
16414                // Check if both bits are set.
16415                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16416                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16417            } else if (onSd && ephemeral) {
16418                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16419                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16420            } else {
16421                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16422                        packageAbiOverride);
16423
16424                if (DEBUG_EPHEMERAL && ephemeral) {
16425                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
16426                }
16427
16428                /*
16429                 * If we have too little free space, try to free cache
16430                 * before giving up.
16431                 */
16432                if (!origin.staged && pkgLite.recommendedInstallLocation
16433                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16434                    // TODO: focus freeing disk space on the target device
16435                    final StorageManager storage = StorageManager.from(mContext);
16436                    final long lowThreshold = storage.getStorageLowBytes(
16437                            Environment.getDataDirectory());
16438
16439                    final long sizeBytes = mContainerService.calculateInstalledSize(
16440                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16441
16442                    try {
16443                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16444                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16445                                installFlags, packageAbiOverride);
16446                    } catch (InstallerException e) {
16447                        Slog.w(TAG, "Failed to free cache", e);
16448                    }
16449
16450                    /*
16451                     * The cache free must have deleted the file we
16452                     * downloaded to install.
16453                     *
16454                     * TODO: fix the "freeCache" call to not delete
16455                     *       the file we care about.
16456                     */
16457                    if (pkgLite.recommendedInstallLocation
16458                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16459                        pkgLite.recommendedInstallLocation
16460                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16461                    }
16462                }
16463            }
16464
16465            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16466                int loc = pkgLite.recommendedInstallLocation;
16467                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16468                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16469                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16470                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16471                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16472                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16473                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16474                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16475                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16476                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16477                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16478                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16479                } else {
16480                    // Override with defaults if needed.
16481                    loc = installLocationPolicy(pkgLite);
16482                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16483                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16484                    } else if (!onSd && !onInt) {
16485                        // Override install location with flags
16486                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16487                            // Set the flag to install on external media.
16488                            installFlags |= PackageManager.INSTALL_EXTERNAL;
16489                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
16490                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16491                            if (DEBUG_EPHEMERAL) {
16492                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16493                            }
16494                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
16495                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16496                                    |PackageManager.INSTALL_INTERNAL);
16497                        } else {
16498                            // Make sure the flag for installing on external
16499                            // media is unset
16500                            installFlags |= PackageManager.INSTALL_INTERNAL;
16501                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16502                        }
16503                    }
16504                }
16505            }
16506
16507            final InstallArgs args = createInstallArgs(this);
16508            mArgs = args;
16509
16510            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16511                // TODO: http://b/22976637
16512                // Apps installed for "all" users use the device owner to verify the app
16513                UserHandle verifierUser = getUser();
16514                if (verifierUser == UserHandle.ALL) {
16515                    verifierUser = UserHandle.SYSTEM;
16516                }
16517
16518                /*
16519                 * Determine if we have any installed package verifiers. If we
16520                 * do, then we'll defer to them to verify the packages.
16521                 */
16522                final int requiredUid = mRequiredVerifierPackage == null ? -1
16523                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16524                                verifierUser.getIdentifier());
16525                final int installerUid =
16526                        verificationInfo == null ? -1 : verificationInfo.installerUid;
16527                if (!origin.existing && requiredUid != -1
16528                        && isVerificationEnabled(
16529                                verifierUser.getIdentifier(), installFlags, installerUid)) {
16530                    final Intent verification = new Intent(
16531                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16532                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16533                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16534                            PACKAGE_MIME_TYPE);
16535                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16536
16537                    // Query all live verifiers based on current user state
16538                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16539                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
16540                            false /*allowDynamicSplits*/);
16541
16542                    if (DEBUG_VERIFY) {
16543                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16544                                + verification.toString() + " with " + pkgLite.verifiers.length
16545                                + " optional verifiers");
16546                    }
16547
16548                    final int verificationId = mPendingVerificationToken++;
16549
16550                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16551
16552                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16553                            installerPackageName);
16554
16555                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16556                            installFlags);
16557
16558                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16559                            pkgLite.packageName);
16560
16561                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16562                            pkgLite.versionCode);
16563
16564                    if (verificationInfo != null) {
16565                        if (verificationInfo.originatingUri != null) {
16566                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16567                                    verificationInfo.originatingUri);
16568                        }
16569                        if (verificationInfo.referrer != null) {
16570                            verification.putExtra(Intent.EXTRA_REFERRER,
16571                                    verificationInfo.referrer);
16572                        }
16573                        if (verificationInfo.originatingUid >= 0) {
16574                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16575                                    verificationInfo.originatingUid);
16576                        }
16577                        if (verificationInfo.installerUid >= 0) {
16578                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16579                                    verificationInfo.installerUid);
16580                        }
16581                    }
16582
16583                    final PackageVerificationState verificationState = new PackageVerificationState(
16584                            requiredUid, args);
16585
16586                    mPendingVerification.append(verificationId, verificationState);
16587
16588                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16589                            receivers, verificationState);
16590
16591                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
16592                    final long idleDuration = getVerificationTimeout();
16593
16594                    /*
16595                     * If any sufficient verifiers were listed in the package
16596                     * manifest, attempt to ask them.
16597                     */
16598                    if (sufficientVerifiers != null) {
16599                        final int N = sufficientVerifiers.size();
16600                        if (N == 0) {
16601                            Slog.i(TAG, "Additional verifiers required, but none installed.");
16602                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16603                        } else {
16604                            for (int i = 0; i < N; i++) {
16605                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
16606                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16607                                        verifierComponent.getPackageName(), idleDuration,
16608                                        verifierUser.getIdentifier(), false, "package verifier");
16609
16610                                final Intent sufficientIntent = new Intent(verification);
16611                                sufficientIntent.setComponent(verifierComponent);
16612                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16613                            }
16614                        }
16615                    }
16616
16617                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16618                            mRequiredVerifierPackage, receivers);
16619                    if (ret == PackageManager.INSTALL_SUCCEEDED
16620                            && mRequiredVerifierPackage != null) {
16621                        Trace.asyncTraceBegin(
16622                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16623                        /*
16624                         * Send the intent to the required verification agent,
16625                         * but only start the verification timeout after the
16626                         * target BroadcastReceivers have run.
16627                         */
16628                        verification.setComponent(requiredVerifierComponent);
16629                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16630                                mRequiredVerifierPackage, idleDuration,
16631                                verifierUser.getIdentifier(), false, "package verifier");
16632                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16633                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16634                                new BroadcastReceiver() {
16635                                    @Override
16636                                    public void onReceive(Context context, Intent intent) {
16637                                        final Message msg = mHandler
16638                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
16639                                        msg.arg1 = verificationId;
16640                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16641                                    }
16642                                }, null, 0, null, null);
16643
16644                        /*
16645                         * We don't want the copy to proceed until verification
16646                         * succeeds, so null out this field.
16647                         */
16648                        mArgs = null;
16649                    }
16650                } else {
16651                    /*
16652                     * No package verification is enabled, so immediately start
16653                     * the remote call to initiate copy using temporary file.
16654                     */
16655                    ret = args.copyApk(mContainerService, true);
16656                }
16657            }
16658
16659            mRet = ret;
16660        }
16661
16662        @Override
16663        void handleReturnCode() {
16664            // If mArgs is null, then MCS couldn't be reached. When it
16665            // reconnects, it will try again to install. At that point, this
16666            // will succeed.
16667            if (mArgs != null) {
16668                processPendingInstall(mArgs, mRet);
16669            }
16670        }
16671
16672        @Override
16673        void handleServiceError() {
16674            mArgs = createInstallArgs(this);
16675            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16676        }
16677
16678        public boolean isForwardLocked() {
16679            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16680        }
16681    }
16682
16683    /**
16684     * Used during creation of InstallArgs
16685     *
16686     * @param installFlags package installation flags
16687     * @return true if should be installed on external storage
16688     */
16689    private static boolean installOnExternalAsec(int installFlags) {
16690        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16691            return false;
16692        }
16693        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16694            return true;
16695        }
16696        return false;
16697    }
16698
16699    /**
16700     * Used during creation of InstallArgs
16701     *
16702     * @param installFlags package installation flags
16703     * @return true if should be installed as forward locked
16704     */
16705    private static boolean installForwardLocked(int installFlags) {
16706        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16707    }
16708
16709    private InstallArgs createInstallArgs(InstallParams params) {
16710        if (params.move != null) {
16711            return new MoveInstallArgs(params);
16712        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16713            return new AsecInstallArgs(params);
16714        } else {
16715            return new FileInstallArgs(params);
16716        }
16717    }
16718
16719    /**
16720     * Create args that describe an existing installed package. Typically used
16721     * when cleaning up old installs, or used as a move source.
16722     */
16723    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16724            String resourcePath, String[] instructionSets) {
16725        final boolean isInAsec;
16726        if (installOnExternalAsec(installFlags)) {
16727            /* Apps on SD card are always in ASEC containers. */
16728            isInAsec = true;
16729        } else if (installForwardLocked(installFlags)
16730                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16731            /*
16732             * Forward-locked apps are only in ASEC containers if they're the
16733             * new style
16734             */
16735            isInAsec = true;
16736        } else {
16737            isInAsec = false;
16738        }
16739
16740        if (isInAsec) {
16741            return new AsecInstallArgs(codePath, instructionSets,
16742                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16743        } else {
16744            return new FileInstallArgs(codePath, resourcePath, instructionSets);
16745        }
16746    }
16747
16748    static abstract class InstallArgs {
16749        /** @see InstallParams#origin */
16750        final OriginInfo origin;
16751        /** @see InstallParams#move */
16752        final MoveInfo move;
16753
16754        final IPackageInstallObserver2 observer;
16755        // Always refers to PackageManager flags only
16756        final int installFlags;
16757        final String installerPackageName;
16758        final String volumeUuid;
16759        final UserHandle user;
16760        final String abiOverride;
16761        final String[] installGrantPermissions;
16762        /** If non-null, drop an async trace when the install completes */
16763        final String traceMethod;
16764        final int traceCookie;
16765        final Certificate[][] certificates;
16766        final int installReason;
16767
16768        // The list of instruction sets supported by this app. This is currently
16769        // only used during the rmdex() phase to clean up resources. We can get rid of this
16770        // if we move dex files under the common app path.
16771        /* nullable */ String[] instructionSets;
16772
16773        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16774                int installFlags, String installerPackageName, String volumeUuid,
16775                UserHandle user, String[] instructionSets,
16776                String abiOverride, String[] installGrantPermissions,
16777                String traceMethod, int traceCookie, Certificate[][] certificates,
16778                int installReason) {
16779            this.origin = origin;
16780            this.move = move;
16781            this.installFlags = installFlags;
16782            this.observer = observer;
16783            this.installerPackageName = installerPackageName;
16784            this.volumeUuid = volumeUuid;
16785            this.user = user;
16786            this.instructionSets = instructionSets;
16787            this.abiOverride = abiOverride;
16788            this.installGrantPermissions = installGrantPermissions;
16789            this.traceMethod = traceMethod;
16790            this.traceCookie = traceCookie;
16791            this.certificates = certificates;
16792            this.installReason = installReason;
16793        }
16794
16795        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16796        abstract int doPreInstall(int status);
16797
16798        /**
16799         * Rename package into final resting place. All paths on the given
16800         * scanned package should be updated to reflect the rename.
16801         */
16802        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16803        abstract int doPostInstall(int status, int uid);
16804
16805        /** @see PackageSettingBase#codePathString */
16806        abstract String getCodePath();
16807        /** @see PackageSettingBase#resourcePathString */
16808        abstract String getResourcePath();
16809
16810        // Need installer lock especially for dex file removal.
16811        abstract void cleanUpResourcesLI();
16812        abstract boolean doPostDeleteLI(boolean delete);
16813
16814        /**
16815         * Called before the source arguments are copied. This is used mostly
16816         * for MoveParams when it needs to read the source file to put it in the
16817         * destination.
16818         */
16819        int doPreCopy() {
16820            return PackageManager.INSTALL_SUCCEEDED;
16821        }
16822
16823        /**
16824         * Called after the source arguments are copied. This is used mostly for
16825         * MoveParams when it needs to read the source file to put it in the
16826         * destination.
16827         */
16828        int doPostCopy(int uid) {
16829            return PackageManager.INSTALL_SUCCEEDED;
16830        }
16831
16832        protected boolean isFwdLocked() {
16833            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16834        }
16835
16836        protected boolean isExternalAsec() {
16837            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16838        }
16839
16840        protected boolean isEphemeral() {
16841            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16842        }
16843
16844        UserHandle getUser() {
16845            return user;
16846        }
16847    }
16848
16849    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16850        if (!allCodePaths.isEmpty()) {
16851            if (instructionSets == null) {
16852                throw new IllegalStateException("instructionSet == null");
16853            }
16854            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16855            for (String codePath : allCodePaths) {
16856                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16857                    try {
16858                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16859                    } catch (InstallerException ignored) {
16860                    }
16861                }
16862            }
16863        }
16864    }
16865
16866    /**
16867     * Logic to handle installation of non-ASEC applications, including copying
16868     * and renaming logic.
16869     */
16870    class FileInstallArgs extends InstallArgs {
16871        private File codeFile;
16872        private File resourceFile;
16873
16874        // Example topology:
16875        // /data/app/com.example/base.apk
16876        // /data/app/com.example/split_foo.apk
16877        // /data/app/com.example/lib/arm/libfoo.so
16878        // /data/app/com.example/lib/arm64/libfoo.so
16879        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16880
16881        /** New install */
16882        FileInstallArgs(InstallParams params) {
16883            super(params.origin, params.move, params.observer, params.installFlags,
16884                    params.installerPackageName, params.volumeUuid,
16885                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16886                    params.grantedRuntimePermissions,
16887                    params.traceMethod, params.traceCookie, params.certificates,
16888                    params.installReason);
16889            if (isFwdLocked()) {
16890                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16891            }
16892        }
16893
16894        /** Existing install */
16895        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16896            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16897                    null, null, null, 0, null /*certificates*/,
16898                    PackageManager.INSTALL_REASON_UNKNOWN);
16899            this.codeFile = (codePath != null) ? new File(codePath) : null;
16900            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16901        }
16902
16903        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16904            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16905            try {
16906                return doCopyApk(imcs, temp);
16907            } finally {
16908                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16909            }
16910        }
16911
16912        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16913            if (origin.staged) {
16914                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16915                codeFile = origin.file;
16916                resourceFile = origin.file;
16917                return PackageManager.INSTALL_SUCCEEDED;
16918            }
16919
16920            try {
16921                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16922                final File tempDir =
16923                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16924                codeFile = tempDir;
16925                resourceFile = tempDir;
16926            } catch (IOException e) {
16927                Slog.w(TAG, "Failed to create copy file: " + e);
16928                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16929            }
16930
16931            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16932                @Override
16933                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16934                    if (!FileUtils.isValidExtFilename(name)) {
16935                        throw new IllegalArgumentException("Invalid filename: " + name);
16936                    }
16937                    try {
16938                        final File file = new File(codeFile, name);
16939                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16940                                O_RDWR | O_CREAT, 0644);
16941                        Os.chmod(file.getAbsolutePath(), 0644);
16942                        return new ParcelFileDescriptor(fd);
16943                    } catch (ErrnoException e) {
16944                        throw new RemoteException("Failed to open: " + e.getMessage());
16945                    }
16946                }
16947            };
16948
16949            int ret = PackageManager.INSTALL_SUCCEEDED;
16950            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16951            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16952                Slog.e(TAG, "Failed to copy package");
16953                return ret;
16954            }
16955
16956            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16957            NativeLibraryHelper.Handle handle = null;
16958            try {
16959                handle = NativeLibraryHelper.Handle.create(codeFile);
16960                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16961                        abiOverride);
16962            } catch (IOException e) {
16963                Slog.e(TAG, "Copying native libraries failed", e);
16964                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16965            } finally {
16966                IoUtils.closeQuietly(handle);
16967            }
16968
16969            return ret;
16970        }
16971
16972        int doPreInstall(int status) {
16973            if (status != PackageManager.INSTALL_SUCCEEDED) {
16974                cleanUp();
16975            }
16976            return status;
16977        }
16978
16979        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16980            if (status != PackageManager.INSTALL_SUCCEEDED) {
16981                cleanUp();
16982                return false;
16983            }
16984
16985            final File targetDir = codeFile.getParentFile();
16986            final File beforeCodeFile = codeFile;
16987            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16988
16989            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16990            try {
16991                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16992            } catch (ErrnoException e) {
16993                Slog.w(TAG, "Failed to rename", e);
16994                return false;
16995            }
16996
16997            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16998                Slog.w(TAG, "Failed to restorecon");
16999                return false;
17000            }
17001
17002            // Reflect the rename internally
17003            codeFile = afterCodeFile;
17004            resourceFile = afterCodeFile;
17005
17006            // Reflect the rename in scanned details
17007            pkg.setCodePath(afterCodeFile.getAbsolutePath());
17008            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17009                    afterCodeFile, pkg.baseCodePath));
17010            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17011                    afterCodeFile, pkg.splitCodePaths));
17012
17013            // Reflect the rename in app info
17014            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17015            pkg.setApplicationInfoCodePath(pkg.codePath);
17016            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17017            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17018            pkg.setApplicationInfoResourcePath(pkg.codePath);
17019            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17020            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17021
17022            return true;
17023        }
17024
17025        int doPostInstall(int status, int uid) {
17026            if (status != PackageManager.INSTALL_SUCCEEDED) {
17027                cleanUp();
17028            }
17029            return status;
17030        }
17031
17032        @Override
17033        String getCodePath() {
17034            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17035        }
17036
17037        @Override
17038        String getResourcePath() {
17039            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17040        }
17041
17042        private boolean cleanUp() {
17043            if (codeFile == null || !codeFile.exists()) {
17044                return false;
17045            }
17046
17047            removeCodePathLI(codeFile);
17048
17049            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
17050                resourceFile.delete();
17051            }
17052
17053            return true;
17054        }
17055
17056        void cleanUpResourcesLI() {
17057            // Try enumerating all code paths before deleting
17058            List<String> allCodePaths = Collections.EMPTY_LIST;
17059            if (codeFile != null && codeFile.exists()) {
17060                try {
17061                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17062                    allCodePaths = pkg.getAllCodePaths();
17063                } catch (PackageParserException e) {
17064                    // Ignored; we tried our best
17065                }
17066            }
17067
17068            cleanUp();
17069            removeDexFiles(allCodePaths, instructionSets);
17070        }
17071
17072        boolean doPostDeleteLI(boolean delete) {
17073            // XXX err, shouldn't we respect the delete flag?
17074            cleanUpResourcesLI();
17075            return true;
17076        }
17077    }
17078
17079    private boolean isAsecExternal(String cid) {
17080        final String asecPath = PackageHelper.getSdFilesystem(cid);
17081        return !asecPath.startsWith(mAsecInternalPath);
17082    }
17083
17084    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
17085            PackageManagerException {
17086        if (copyRet < 0) {
17087            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
17088                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
17089                throw new PackageManagerException(copyRet, message);
17090            }
17091        }
17092    }
17093
17094    /**
17095     * Extract the StorageManagerService "container ID" from the full code path of an
17096     * .apk.
17097     */
17098    static String cidFromCodePath(String fullCodePath) {
17099        int eidx = fullCodePath.lastIndexOf("/");
17100        String subStr1 = fullCodePath.substring(0, eidx);
17101        int sidx = subStr1.lastIndexOf("/");
17102        return subStr1.substring(sidx+1, eidx);
17103    }
17104
17105    /**
17106     * Logic to handle installation of ASEC applications, including copying and
17107     * renaming logic.
17108     */
17109    class AsecInstallArgs extends InstallArgs {
17110        static final String RES_FILE_NAME = "pkg.apk";
17111        static final String PUBLIC_RES_FILE_NAME = "res.zip";
17112
17113        String cid;
17114        String packagePath;
17115        String resourcePath;
17116
17117        /** New install */
17118        AsecInstallArgs(InstallParams params) {
17119            super(params.origin, params.move, params.observer, params.installFlags,
17120                    params.installerPackageName, params.volumeUuid,
17121                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17122                    params.grantedRuntimePermissions,
17123                    params.traceMethod, params.traceCookie, params.certificates,
17124                    params.installReason);
17125        }
17126
17127        /** Existing install */
17128        AsecInstallArgs(String fullCodePath, String[] instructionSets,
17129                        boolean isExternal, boolean isForwardLocked) {
17130            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
17131                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17132                    instructionSets, null, null, null, 0, null /*certificates*/,
17133                    PackageManager.INSTALL_REASON_UNKNOWN);
17134            // Hackily pretend we're still looking at a full code path
17135            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
17136                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
17137            }
17138
17139            // Extract cid from fullCodePath
17140            int eidx = fullCodePath.lastIndexOf("/");
17141            String subStr1 = fullCodePath.substring(0, eidx);
17142            int sidx = subStr1.lastIndexOf("/");
17143            cid = subStr1.substring(sidx+1, eidx);
17144            setMountPath(subStr1);
17145        }
17146
17147        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
17148            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
17149                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
17150                    instructionSets, null, null, null, 0, null /*certificates*/,
17151                    PackageManager.INSTALL_REASON_UNKNOWN);
17152            this.cid = cid;
17153            setMountPath(PackageHelper.getSdDir(cid));
17154        }
17155
17156        void createCopyFile() {
17157            cid = mInstallerService.allocateExternalStageCidLegacy();
17158        }
17159
17160        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
17161            if (origin.staged && origin.cid != null) {
17162                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
17163                cid = origin.cid;
17164                setMountPath(PackageHelper.getSdDir(cid));
17165                return PackageManager.INSTALL_SUCCEEDED;
17166            }
17167
17168            if (temp) {
17169                createCopyFile();
17170            } else {
17171                /*
17172                 * Pre-emptively destroy the container since it's destroyed if
17173                 * copying fails due to it existing anyway.
17174                 */
17175                PackageHelper.destroySdDir(cid);
17176            }
17177
17178            final String newMountPath = imcs.copyPackageToContainer(
17179                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
17180                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
17181
17182            if (newMountPath != null) {
17183                setMountPath(newMountPath);
17184                return PackageManager.INSTALL_SUCCEEDED;
17185            } else {
17186                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17187            }
17188        }
17189
17190        @Override
17191        String getCodePath() {
17192            return packagePath;
17193        }
17194
17195        @Override
17196        String getResourcePath() {
17197            return resourcePath;
17198        }
17199
17200        int doPreInstall(int status) {
17201            if (status != PackageManager.INSTALL_SUCCEEDED) {
17202                // Destroy container
17203                PackageHelper.destroySdDir(cid);
17204            } else {
17205                boolean mounted = PackageHelper.isContainerMounted(cid);
17206                if (!mounted) {
17207                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
17208                            Process.SYSTEM_UID);
17209                    if (newMountPath != null) {
17210                        setMountPath(newMountPath);
17211                    } else {
17212                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17213                    }
17214                }
17215            }
17216            return status;
17217        }
17218
17219        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17220            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
17221            String newMountPath = null;
17222            if (PackageHelper.isContainerMounted(cid)) {
17223                // Unmount the container
17224                if (!PackageHelper.unMountSdDir(cid)) {
17225                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
17226                    return false;
17227                }
17228            }
17229            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17230                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
17231                        " which might be stale. Will try to clean up.");
17232                // Clean up the stale container and proceed to recreate.
17233                if (!PackageHelper.destroySdDir(newCacheId)) {
17234                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
17235                    return false;
17236                }
17237                // Successfully cleaned up stale container. Try to rename again.
17238                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17239                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
17240                            + " inspite of cleaning it up.");
17241                    return false;
17242                }
17243            }
17244            if (!PackageHelper.isContainerMounted(newCacheId)) {
17245                Slog.w(TAG, "Mounting container " + newCacheId);
17246                newMountPath = PackageHelper.mountSdDir(newCacheId,
17247                        getEncryptKey(), Process.SYSTEM_UID);
17248            } else {
17249                newMountPath = PackageHelper.getSdDir(newCacheId);
17250            }
17251            if (newMountPath == null) {
17252                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
17253                return false;
17254            }
17255            Log.i(TAG, "Succesfully renamed " + cid +
17256                    " to " + newCacheId +
17257                    " at new path: " + newMountPath);
17258            cid = newCacheId;
17259
17260            final File beforeCodeFile = new File(packagePath);
17261            setMountPath(newMountPath);
17262            final File afterCodeFile = new File(packagePath);
17263
17264            // Reflect the rename in scanned details
17265            pkg.setCodePath(afterCodeFile.getAbsolutePath());
17266            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17267                    afterCodeFile, pkg.baseCodePath));
17268            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17269                    afterCodeFile, pkg.splitCodePaths));
17270
17271            // Reflect the rename in app info
17272            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17273            pkg.setApplicationInfoCodePath(pkg.codePath);
17274            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17275            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17276            pkg.setApplicationInfoResourcePath(pkg.codePath);
17277            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17278            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17279
17280            return true;
17281        }
17282
17283        private void setMountPath(String mountPath) {
17284            final File mountFile = new File(mountPath);
17285
17286            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
17287            if (monolithicFile.exists()) {
17288                packagePath = monolithicFile.getAbsolutePath();
17289                if (isFwdLocked()) {
17290                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
17291                } else {
17292                    resourcePath = packagePath;
17293                }
17294            } else {
17295                packagePath = mountFile.getAbsolutePath();
17296                resourcePath = packagePath;
17297            }
17298        }
17299
17300        int doPostInstall(int status, int uid) {
17301            if (status != PackageManager.INSTALL_SUCCEEDED) {
17302                cleanUp();
17303            } else {
17304                final int groupOwner;
17305                final String protectedFile;
17306                if (isFwdLocked()) {
17307                    groupOwner = UserHandle.getSharedAppGid(uid);
17308                    protectedFile = RES_FILE_NAME;
17309                } else {
17310                    groupOwner = -1;
17311                    protectedFile = null;
17312                }
17313
17314                if (uid < Process.FIRST_APPLICATION_UID
17315                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
17316                    Slog.e(TAG, "Failed to finalize " + cid);
17317                    PackageHelper.destroySdDir(cid);
17318                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17319                }
17320
17321                boolean mounted = PackageHelper.isContainerMounted(cid);
17322                if (!mounted) {
17323                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
17324                }
17325            }
17326            return status;
17327        }
17328
17329        private void cleanUp() {
17330            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
17331
17332            // Destroy secure container
17333            PackageHelper.destroySdDir(cid);
17334        }
17335
17336        private List<String> getAllCodePaths() {
17337            final File codeFile = new File(getCodePath());
17338            if (codeFile != null && codeFile.exists()) {
17339                try {
17340                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17341                    return pkg.getAllCodePaths();
17342                } catch (PackageParserException e) {
17343                    // Ignored; we tried our best
17344                }
17345            }
17346            return Collections.EMPTY_LIST;
17347        }
17348
17349        void cleanUpResourcesLI() {
17350            // Enumerate all code paths before deleting
17351            cleanUpResourcesLI(getAllCodePaths());
17352        }
17353
17354        private void cleanUpResourcesLI(List<String> allCodePaths) {
17355            cleanUp();
17356            removeDexFiles(allCodePaths, instructionSets);
17357        }
17358
17359        String getPackageName() {
17360            return getAsecPackageName(cid);
17361        }
17362
17363        boolean doPostDeleteLI(boolean delete) {
17364            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17365            final List<String> allCodePaths = getAllCodePaths();
17366            boolean mounted = PackageHelper.isContainerMounted(cid);
17367            if (mounted) {
17368                // Unmount first
17369                if (PackageHelper.unMountSdDir(cid)) {
17370                    mounted = false;
17371                }
17372            }
17373            if (!mounted && delete) {
17374                cleanUpResourcesLI(allCodePaths);
17375            }
17376            return !mounted;
17377        }
17378
17379        @Override
17380        int doPreCopy() {
17381            if (isFwdLocked()) {
17382                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17383                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17384                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17385                }
17386            }
17387
17388            return PackageManager.INSTALL_SUCCEEDED;
17389        }
17390
17391        @Override
17392        int doPostCopy(int uid) {
17393            if (isFwdLocked()) {
17394                if (uid < Process.FIRST_APPLICATION_UID
17395                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17396                                RES_FILE_NAME)) {
17397                    Slog.e(TAG, "Failed to finalize " + cid);
17398                    PackageHelper.destroySdDir(cid);
17399                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17400                }
17401            }
17402
17403            return PackageManager.INSTALL_SUCCEEDED;
17404        }
17405    }
17406
17407    /**
17408     * Logic to handle movement of existing installed applications.
17409     */
17410    class MoveInstallArgs extends InstallArgs {
17411        private File codeFile;
17412        private File resourceFile;
17413
17414        /** New install */
17415        MoveInstallArgs(InstallParams params) {
17416            super(params.origin, params.move, params.observer, params.installFlags,
17417                    params.installerPackageName, params.volumeUuid,
17418                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17419                    params.grantedRuntimePermissions,
17420                    params.traceMethod, params.traceCookie, params.certificates,
17421                    params.installReason);
17422        }
17423
17424        int copyApk(IMediaContainerService imcs, boolean temp) {
17425            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17426                    + move.fromUuid + " to " + move.toUuid);
17427            synchronized (mInstaller) {
17428                try {
17429                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17430                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17431                } catch (InstallerException e) {
17432                    Slog.w(TAG, "Failed to move app", e);
17433                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17434                }
17435            }
17436
17437            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17438            resourceFile = codeFile;
17439            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17440
17441            return PackageManager.INSTALL_SUCCEEDED;
17442        }
17443
17444        int doPreInstall(int status) {
17445            if (status != PackageManager.INSTALL_SUCCEEDED) {
17446                cleanUp(move.toUuid);
17447            }
17448            return status;
17449        }
17450
17451        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17452            if (status != PackageManager.INSTALL_SUCCEEDED) {
17453                cleanUp(move.toUuid);
17454                return false;
17455            }
17456
17457            // Reflect the move in app info
17458            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17459            pkg.setApplicationInfoCodePath(pkg.codePath);
17460            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17461            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17462            pkg.setApplicationInfoResourcePath(pkg.codePath);
17463            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17464            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17465
17466            return true;
17467        }
17468
17469        int doPostInstall(int status, int uid) {
17470            if (status == PackageManager.INSTALL_SUCCEEDED) {
17471                cleanUp(move.fromUuid);
17472            } else {
17473                cleanUp(move.toUuid);
17474            }
17475            return status;
17476        }
17477
17478        @Override
17479        String getCodePath() {
17480            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17481        }
17482
17483        @Override
17484        String getResourcePath() {
17485            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17486        }
17487
17488        private boolean cleanUp(String volumeUuid) {
17489            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17490                    move.dataAppName);
17491            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17492            final int[] userIds = sUserManager.getUserIds();
17493            synchronized (mInstallLock) {
17494                // Clean up both app data and code
17495                // All package moves are frozen until finished
17496                for (int userId : userIds) {
17497                    try {
17498                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17499                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17500                    } catch (InstallerException e) {
17501                        Slog.w(TAG, String.valueOf(e));
17502                    }
17503                }
17504                removeCodePathLI(codeFile);
17505            }
17506            return true;
17507        }
17508
17509        void cleanUpResourcesLI() {
17510            throw new UnsupportedOperationException();
17511        }
17512
17513        boolean doPostDeleteLI(boolean delete) {
17514            throw new UnsupportedOperationException();
17515        }
17516    }
17517
17518    static String getAsecPackageName(String packageCid) {
17519        int idx = packageCid.lastIndexOf("-");
17520        if (idx == -1) {
17521            return packageCid;
17522        }
17523        return packageCid.substring(0, idx);
17524    }
17525
17526    // Utility method used to create code paths based on package name and available index.
17527    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17528        String idxStr = "";
17529        int idx = 1;
17530        // Fall back to default value of idx=1 if prefix is not
17531        // part of oldCodePath
17532        if (oldCodePath != null) {
17533            String subStr = oldCodePath;
17534            // Drop the suffix right away
17535            if (suffix != null && subStr.endsWith(suffix)) {
17536                subStr = subStr.substring(0, subStr.length() - suffix.length());
17537            }
17538            // If oldCodePath already contains prefix find out the
17539            // ending index to either increment or decrement.
17540            int sidx = subStr.lastIndexOf(prefix);
17541            if (sidx != -1) {
17542                subStr = subStr.substring(sidx + prefix.length());
17543                if (subStr != null) {
17544                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17545                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17546                    }
17547                    try {
17548                        idx = Integer.parseInt(subStr);
17549                        if (idx <= 1) {
17550                            idx++;
17551                        } else {
17552                            idx--;
17553                        }
17554                    } catch(NumberFormatException e) {
17555                    }
17556                }
17557            }
17558        }
17559        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17560        return prefix + idxStr;
17561    }
17562
17563    private File getNextCodePath(File targetDir, String packageName) {
17564        File result;
17565        SecureRandom random = new SecureRandom();
17566        byte[] bytes = new byte[16];
17567        do {
17568            random.nextBytes(bytes);
17569            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17570            result = new File(targetDir, packageName + "-" + suffix);
17571        } while (result.exists());
17572        return result;
17573    }
17574
17575    // Utility method that returns the relative package path with respect
17576    // to the installation directory. Like say for /data/data/com.test-1.apk
17577    // string com.test-1 is returned.
17578    static String deriveCodePathName(String codePath) {
17579        if (codePath == null) {
17580            return null;
17581        }
17582        final File codeFile = new File(codePath);
17583        final String name = codeFile.getName();
17584        if (codeFile.isDirectory()) {
17585            return name;
17586        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17587            final int lastDot = name.lastIndexOf('.');
17588            return name.substring(0, lastDot);
17589        } else {
17590            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17591            return null;
17592        }
17593    }
17594
17595    static class PackageInstalledInfo {
17596        String name;
17597        int uid;
17598        // The set of users that originally had this package installed.
17599        int[] origUsers;
17600        // The set of users that now have this package installed.
17601        int[] newUsers;
17602        PackageParser.Package pkg;
17603        int returnCode;
17604        String returnMsg;
17605        String installerPackageName;
17606        PackageRemovedInfo removedInfo;
17607        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17608
17609        public void setError(int code, String msg) {
17610            setReturnCode(code);
17611            setReturnMessage(msg);
17612            Slog.w(TAG, msg);
17613        }
17614
17615        public void setError(String msg, PackageParserException e) {
17616            setReturnCode(e.error);
17617            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17618            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17619            for (int i = 0; i < childCount; i++) {
17620                addedChildPackages.valueAt(i).setError(msg, e);
17621            }
17622            Slog.w(TAG, msg, e);
17623        }
17624
17625        public void setError(String msg, PackageManagerException e) {
17626            returnCode = e.error;
17627            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17628            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17629            for (int i = 0; i < childCount; i++) {
17630                addedChildPackages.valueAt(i).setError(msg, e);
17631            }
17632            Slog.w(TAG, msg, e);
17633        }
17634
17635        public void setReturnCode(int returnCode) {
17636            this.returnCode = returnCode;
17637            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17638            for (int i = 0; i < childCount; i++) {
17639                addedChildPackages.valueAt(i).returnCode = returnCode;
17640            }
17641        }
17642
17643        private void setReturnMessage(String returnMsg) {
17644            this.returnMsg = returnMsg;
17645            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17646            for (int i = 0; i < childCount; i++) {
17647                addedChildPackages.valueAt(i).returnMsg = returnMsg;
17648            }
17649        }
17650
17651        // In some error cases we want to convey more info back to the observer
17652        String origPackage;
17653        String origPermission;
17654    }
17655
17656    /*
17657     * Install a non-existing package.
17658     */
17659    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17660            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17661            PackageInstalledInfo res, int installReason) {
17662        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17663
17664        // Remember this for later, in case we need to rollback this install
17665        String pkgName = pkg.packageName;
17666
17667        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17668
17669        synchronized(mPackages) {
17670            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17671            if (renamedPackage != null) {
17672                // A package with the same name is already installed, though
17673                // it has been renamed to an older name.  The package we
17674                // are trying to install should be installed as an update to
17675                // the existing one, but that has not been requested, so bail.
17676                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17677                        + " without first uninstalling package running as "
17678                        + renamedPackage);
17679                return;
17680            }
17681            if (mPackages.containsKey(pkgName)) {
17682                // Don't allow installation over an existing package with the same name.
17683                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17684                        + " without first uninstalling.");
17685                return;
17686            }
17687        }
17688
17689        try {
17690            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17691                    System.currentTimeMillis(), user);
17692
17693            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17694
17695            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17696                prepareAppDataAfterInstallLIF(newPackage);
17697
17698            } else {
17699                // Remove package from internal structures, but keep around any
17700                // data that might have already existed
17701                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17702                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17703            }
17704        } catch (PackageManagerException e) {
17705            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17706        }
17707
17708        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17709    }
17710
17711    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17712        // Can't rotate keys during boot or if sharedUser.
17713        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17714                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17715            return false;
17716        }
17717        // app is using upgradeKeySets; make sure all are valid
17718        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17719        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17720        for (int i = 0; i < upgradeKeySets.length; i++) {
17721            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17722                Slog.wtf(TAG, "Package "
17723                         + (oldPs.name != null ? oldPs.name : "<null>")
17724                         + " contains upgrade-key-set reference to unknown key-set: "
17725                         + upgradeKeySets[i]
17726                         + " reverting to signatures check.");
17727                return false;
17728            }
17729        }
17730        return true;
17731    }
17732
17733    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17734        // Upgrade keysets are being used.  Determine if new package has a superset of the
17735        // required keys.
17736        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17737        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17738        for (int i = 0; i < upgradeKeySets.length; i++) {
17739            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17740            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17741                return true;
17742            }
17743        }
17744        return false;
17745    }
17746
17747    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17748        try (DigestInputStream digestStream =
17749                new DigestInputStream(new FileInputStream(file), digest)) {
17750            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17751        }
17752    }
17753
17754    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17755            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17756            int installReason) {
17757        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17758
17759        final PackageParser.Package oldPackage;
17760        final PackageSetting ps;
17761        final String pkgName = pkg.packageName;
17762        final int[] allUsers;
17763        final int[] installedUsers;
17764
17765        synchronized(mPackages) {
17766            oldPackage = mPackages.get(pkgName);
17767            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17768
17769            // don't allow upgrade to target a release SDK from a pre-release SDK
17770            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17771                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17772            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17773                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17774            if (oldTargetsPreRelease
17775                    && !newTargetsPreRelease
17776                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17777                Slog.w(TAG, "Can't install package targeting released sdk");
17778                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17779                return;
17780            }
17781
17782            ps = mSettings.mPackages.get(pkgName);
17783
17784            // verify signatures are valid
17785            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17786                if (!checkUpgradeKeySetLP(ps, pkg)) {
17787                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17788                            "New package not signed by keys specified by upgrade-keysets: "
17789                                    + pkgName);
17790                    return;
17791                }
17792            } else {
17793                // default to original signature matching
17794                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17795                        != PackageManager.SIGNATURE_MATCH) {
17796                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17797                            "New package has a different signature: " + pkgName);
17798                    return;
17799                }
17800            }
17801
17802            // don't allow a system upgrade unless the upgrade hash matches
17803            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17804                byte[] digestBytes = null;
17805                try {
17806                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17807                    updateDigest(digest, new File(pkg.baseCodePath));
17808                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17809                        for (String path : pkg.splitCodePaths) {
17810                            updateDigest(digest, new File(path));
17811                        }
17812                    }
17813                    digestBytes = digest.digest();
17814                } catch (NoSuchAlgorithmException | IOException e) {
17815                    res.setError(INSTALL_FAILED_INVALID_APK,
17816                            "Could not compute hash: " + pkgName);
17817                    return;
17818                }
17819                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17820                    res.setError(INSTALL_FAILED_INVALID_APK,
17821                            "New package fails restrict-update check: " + pkgName);
17822                    return;
17823                }
17824                // retain upgrade restriction
17825                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17826            }
17827
17828            // Check for shared user id changes
17829            String invalidPackageName =
17830                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17831            if (invalidPackageName != null) {
17832                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17833                        "Package " + invalidPackageName + " tried to change user "
17834                                + oldPackage.mSharedUserId);
17835                return;
17836            }
17837
17838            // In case of rollback, remember per-user/profile install state
17839            allUsers = sUserManager.getUserIds();
17840            installedUsers = ps.queryInstalledUsers(allUsers, true);
17841
17842            // don't allow an upgrade from full to ephemeral
17843            if (isInstantApp) {
17844                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17845                    for (int currentUser : allUsers) {
17846                        if (!ps.getInstantApp(currentUser)) {
17847                            // can't downgrade from full to instant
17848                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17849                                    + " for user: " + currentUser);
17850                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17851                            return;
17852                        }
17853                    }
17854                } else if (!ps.getInstantApp(user.getIdentifier())) {
17855                    // can't downgrade from full to instant
17856                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17857                            + " for user: " + user.getIdentifier());
17858                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17859                    return;
17860                }
17861            }
17862        }
17863
17864        // Update what is removed
17865        res.removedInfo = new PackageRemovedInfo(this);
17866        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17867        res.removedInfo.removedPackage = oldPackage.packageName;
17868        res.removedInfo.installerPackageName = ps.installerPackageName;
17869        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17870        res.removedInfo.isUpdate = true;
17871        res.removedInfo.origUsers = installedUsers;
17872        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17873        for (int i = 0; i < installedUsers.length; i++) {
17874            final int userId = installedUsers[i];
17875            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17876        }
17877
17878        final int childCount = (oldPackage.childPackages != null)
17879                ? oldPackage.childPackages.size() : 0;
17880        for (int i = 0; i < childCount; i++) {
17881            boolean childPackageUpdated = false;
17882            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17883            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17884            if (res.addedChildPackages != null) {
17885                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17886                if (childRes != null) {
17887                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17888                    childRes.removedInfo.removedPackage = childPkg.packageName;
17889                    if (childPs != null) {
17890                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17891                    }
17892                    childRes.removedInfo.isUpdate = true;
17893                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17894                    childPackageUpdated = true;
17895                }
17896            }
17897            if (!childPackageUpdated) {
17898                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17899                childRemovedRes.removedPackage = childPkg.packageName;
17900                if (childPs != null) {
17901                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17902                }
17903                childRemovedRes.isUpdate = false;
17904                childRemovedRes.dataRemoved = true;
17905                synchronized (mPackages) {
17906                    if (childPs != null) {
17907                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17908                    }
17909                }
17910                if (res.removedInfo.removedChildPackages == null) {
17911                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17912                }
17913                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17914            }
17915        }
17916
17917        boolean sysPkg = (isSystemApp(oldPackage));
17918        if (sysPkg) {
17919            // Set the system/privileged flags as needed
17920            final boolean privileged =
17921                    (oldPackage.applicationInfo.privateFlags
17922                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17923            final int systemPolicyFlags = policyFlags
17924                    | PackageParser.PARSE_IS_SYSTEM
17925                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17926
17927            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17928                    user, allUsers, installerPackageName, res, installReason);
17929        } else {
17930            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17931                    user, allUsers, installerPackageName, res, installReason);
17932        }
17933    }
17934
17935    @Override
17936    public List<String> getPreviousCodePaths(String packageName) {
17937        final int callingUid = Binder.getCallingUid();
17938        final List<String> result = new ArrayList<>();
17939        if (getInstantAppPackageName(callingUid) != null) {
17940            return result;
17941        }
17942        final PackageSetting ps = mSettings.mPackages.get(packageName);
17943        if (ps != null
17944                && ps.oldCodePaths != null
17945                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17946            result.addAll(ps.oldCodePaths);
17947        }
17948        return result;
17949    }
17950
17951    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17952            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17953            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17954            int installReason) {
17955        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17956                + deletedPackage);
17957
17958        String pkgName = deletedPackage.packageName;
17959        boolean deletedPkg = true;
17960        boolean addedPkg = false;
17961        boolean updatedSettings = false;
17962        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17963        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17964                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17965
17966        final long origUpdateTime = (pkg.mExtras != null)
17967                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17968
17969        // First delete the existing package while retaining the data directory
17970        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17971                res.removedInfo, true, pkg)) {
17972            // If the existing package wasn't successfully deleted
17973            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17974            deletedPkg = false;
17975        } else {
17976            // Successfully deleted the old package; proceed with replace.
17977
17978            // If deleted package lived in a container, give users a chance to
17979            // relinquish resources before killing.
17980            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17981                if (DEBUG_INSTALL) {
17982                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17983                }
17984                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17985                final ArrayList<String> pkgList = new ArrayList<String>(1);
17986                pkgList.add(deletedPackage.applicationInfo.packageName);
17987                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17988            }
17989
17990            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17991                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17992            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17993
17994            try {
17995                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17996                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17997                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17998                        installReason);
17999
18000                // Update the in-memory copy of the previous code paths.
18001                PackageSetting ps = mSettings.mPackages.get(pkgName);
18002                if (!killApp) {
18003                    if (ps.oldCodePaths == null) {
18004                        ps.oldCodePaths = new ArraySet<>();
18005                    }
18006                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
18007                    if (deletedPackage.splitCodePaths != null) {
18008                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
18009                    }
18010                } else {
18011                    ps.oldCodePaths = null;
18012                }
18013                if (ps.childPackageNames != null) {
18014                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
18015                        final String childPkgName = ps.childPackageNames.get(i);
18016                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
18017                        childPs.oldCodePaths = ps.oldCodePaths;
18018                    }
18019                }
18020                // set instant app status, but, only if it's explicitly specified
18021                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
18022                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
18023                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
18024                prepareAppDataAfterInstallLIF(newPackage);
18025                addedPkg = true;
18026                mDexManager.notifyPackageUpdated(newPackage.packageName,
18027                        newPackage.baseCodePath, newPackage.splitCodePaths);
18028            } catch (PackageManagerException e) {
18029                res.setError("Package couldn't be installed in " + pkg.codePath, e);
18030            }
18031        }
18032
18033        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18034            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
18035
18036            // Revert all internal state mutations and added folders for the failed install
18037            if (addedPkg) {
18038                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
18039                        res.removedInfo, true, null);
18040            }
18041
18042            // Restore the old package
18043            if (deletedPkg) {
18044                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
18045                File restoreFile = new File(deletedPackage.codePath);
18046                // Parse old package
18047                boolean oldExternal = isExternal(deletedPackage);
18048                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
18049                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
18050                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
18051                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
18052                try {
18053                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
18054                            null);
18055                } catch (PackageManagerException e) {
18056                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
18057                            + e.getMessage());
18058                    return;
18059                }
18060
18061                synchronized (mPackages) {
18062                    // Ensure the installer package name up to date
18063                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18064
18065                    // Update permissions for restored package
18066                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18067
18068                    mSettings.writeLPr();
18069                }
18070
18071                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
18072            }
18073        } else {
18074            synchronized (mPackages) {
18075                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
18076                if (ps != null) {
18077                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18078                    if (res.removedInfo.removedChildPackages != null) {
18079                        final int childCount = res.removedInfo.removedChildPackages.size();
18080                        // Iterate in reverse as we may modify the collection
18081                        for (int i = childCount - 1; i >= 0; i--) {
18082                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
18083                            if (res.addedChildPackages.containsKey(childPackageName)) {
18084                                res.removedInfo.removedChildPackages.removeAt(i);
18085                            } else {
18086                                PackageRemovedInfo childInfo = res.removedInfo
18087                                        .removedChildPackages.valueAt(i);
18088                                childInfo.removedForAllUsers = mPackages.get(
18089                                        childInfo.removedPackage) == null;
18090                            }
18091                        }
18092                    }
18093                }
18094            }
18095        }
18096    }
18097
18098    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
18099            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
18100            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
18101            int installReason) {
18102        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
18103                + ", old=" + deletedPackage);
18104
18105        final boolean disabledSystem;
18106
18107        // Remove existing system package
18108        removePackageLI(deletedPackage, true);
18109
18110        synchronized (mPackages) {
18111            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
18112        }
18113        if (!disabledSystem) {
18114            // We didn't need to disable the .apk as a current system package,
18115            // which means we are replacing another update that is already
18116            // installed.  We need to make sure to delete the older one's .apk.
18117            res.removedInfo.args = createInstallArgsForExisting(0,
18118                    deletedPackage.applicationInfo.getCodePath(),
18119                    deletedPackage.applicationInfo.getResourcePath(),
18120                    getAppDexInstructionSets(deletedPackage.applicationInfo));
18121        } else {
18122            res.removedInfo.args = null;
18123        }
18124
18125        // Successfully disabled the old package. Now proceed with re-installation
18126        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
18127                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18128        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
18129
18130        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18131        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
18132                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
18133
18134        PackageParser.Package newPackage = null;
18135        try {
18136            // Add the package to the internal data structures
18137            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
18138
18139            // Set the update and install times
18140            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
18141            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
18142                    System.currentTimeMillis());
18143
18144            // Update the package dynamic state if succeeded
18145            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18146                // Now that the install succeeded make sure we remove data
18147                // directories for any child package the update removed.
18148                final int deletedChildCount = (deletedPackage.childPackages != null)
18149                        ? deletedPackage.childPackages.size() : 0;
18150                final int newChildCount = (newPackage.childPackages != null)
18151                        ? newPackage.childPackages.size() : 0;
18152                for (int i = 0; i < deletedChildCount; i++) {
18153                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
18154                    boolean childPackageDeleted = true;
18155                    for (int j = 0; j < newChildCount; j++) {
18156                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
18157                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
18158                            childPackageDeleted = false;
18159                            break;
18160                        }
18161                    }
18162                    if (childPackageDeleted) {
18163                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
18164                                deletedChildPkg.packageName);
18165                        if (ps != null && res.removedInfo.removedChildPackages != null) {
18166                            PackageRemovedInfo removedChildRes = res.removedInfo
18167                                    .removedChildPackages.get(deletedChildPkg.packageName);
18168                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
18169                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
18170                        }
18171                    }
18172                }
18173
18174                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
18175                        installReason);
18176                prepareAppDataAfterInstallLIF(newPackage);
18177
18178                mDexManager.notifyPackageUpdated(newPackage.packageName,
18179                            newPackage.baseCodePath, newPackage.splitCodePaths);
18180            }
18181        } catch (PackageManagerException e) {
18182            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
18183            res.setError("Package couldn't be installed in " + pkg.codePath, e);
18184        }
18185
18186        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18187            // Re installation failed. Restore old information
18188            // Remove new pkg information
18189            if (newPackage != null) {
18190                removeInstalledPackageLI(newPackage, true);
18191            }
18192            // Add back the old system package
18193            try {
18194                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
18195            } catch (PackageManagerException e) {
18196                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
18197            }
18198
18199            synchronized (mPackages) {
18200                if (disabledSystem) {
18201                    enableSystemPackageLPw(deletedPackage);
18202                }
18203
18204                // Ensure the installer package name up to date
18205                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18206
18207                // Update permissions for restored package
18208                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18209
18210                mSettings.writeLPr();
18211            }
18212
18213            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
18214                    + " after failed upgrade");
18215        }
18216    }
18217
18218    /**
18219     * Checks whether the parent or any of the child packages have a change shared
18220     * user. For a package to be a valid update the shred users of the parent and
18221     * the children should match. We may later support changing child shared users.
18222     * @param oldPkg The updated package.
18223     * @param newPkg The update package.
18224     * @return The shared user that change between the versions.
18225     */
18226    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
18227            PackageParser.Package newPkg) {
18228        // Check parent shared user
18229        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
18230            return newPkg.packageName;
18231        }
18232        // Check child shared users
18233        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18234        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
18235        for (int i = 0; i < newChildCount; i++) {
18236            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
18237            // If this child was present, did it have the same shared user?
18238            for (int j = 0; j < oldChildCount; j++) {
18239                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
18240                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
18241                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
18242                    return newChildPkg.packageName;
18243                }
18244            }
18245        }
18246        return null;
18247    }
18248
18249    private void removeNativeBinariesLI(PackageSetting ps) {
18250        // Remove the lib path for the parent package
18251        if (ps != null) {
18252            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
18253            // Remove the lib path for the child packages
18254            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18255            for (int i = 0; i < childCount; i++) {
18256                PackageSetting childPs = null;
18257                synchronized (mPackages) {
18258                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18259                }
18260                if (childPs != null) {
18261                    NativeLibraryHelper.removeNativeBinariesLI(childPs
18262                            .legacyNativeLibraryPathString);
18263                }
18264            }
18265        }
18266    }
18267
18268    private void enableSystemPackageLPw(PackageParser.Package pkg) {
18269        // Enable the parent package
18270        mSettings.enableSystemPackageLPw(pkg.packageName);
18271        // Enable the child packages
18272        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18273        for (int i = 0; i < childCount; i++) {
18274            PackageParser.Package childPkg = pkg.childPackages.get(i);
18275            mSettings.enableSystemPackageLPw(childPkg.packageName);
18276        }
18277    }
18278
18279    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
18280            PackageParser.Package newPkg) {
18281        // Disable the parent package (parent always replaced)
18282        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
18283        // Disable the child packages
18284        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18285        for (int i = 0; i < childCount; i++) {
18286            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
18287            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
18288            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
18289        }
18290        return disabled;
18291    }
18292
18293    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
18294            String installerPackageName) {
18295        // Enable the parent package
18296        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
18297        // Enable the child packages
18298        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18299        for (int i = 0; i < childCount; i++) {
18300            PackageParser.Package childPkg = pkg.childPackages.get(i);
18301            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
18302        }
18303    }
18304
18305    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
18306        // Collect all used permissions in the UID
18307        ArraySet<String> usedPermissions = new ArraySet<>();
18308        final int packageCount = su.packages.size();
18309        for (int i = 0; i < packageCount; i++) {
18310            PackageSetting ps = su.packages.valueAt(i);
18311            if (ps.pkg == null) {
18312                continue;
18313            }
18314            final int requestedPermCount = ps.pkg.requestedPermissions.size();
18315            for (int j = 0; j < requestedPermCount; j++) {
18316                String permission = ps.pkg.requestedPermissions.get(j);
18317                BasePermission bp = mSettings.mPermissions.get(permission);
18318                if (bp != null) {
18319                    usedPermissions.add(permission);
18320                }
18321            }
18322        }
18323
18324        PermissionsState permissionsState = su.getPermissionsState();
18325        // Prune install permissions
18326        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
18327        final int installPermCount = installPermStates.size();
18328        for (int i = installPermCount - 1; i >= 0;  i--) {
18329            PermissionState permissionState = installPermStates.get(i);
18330            if (!usedPermissions.contains(permissionState.getName())) {
18331                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18332                if (bp != null) {
18333                    permissionsState.revokeInstallPermission(bp);
18334                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
18335                            PackageManager.MASK_PERMISSION_FLAGS, 0);
18336                }
18337            }
18338        }
18339
18340        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
18341
18342        // Prune runtime permissions
18343        for (int userId : allUserIds) {
18344            List<PermissionState> runtimePermStates = permissionsState
18345                    .getRuntimePermissionStates(userId);
18346            final int runtimePermCount = runtimePermStates.size();
18347            for (int i = runtimePermCount - 1; i >= 0; i--) {
18348                PermissionState permissionState = runtimePermStates.get(i);
18349                if (!usedPermissions.contains(permissionState.getName())) {
18350                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18351                    if (bp != null) {
18352                        permissionsState.revokeRuntimePermission(bp, userId);
18353                        permissionsState.updatePermissionFlags(bp, userId,
18354                                PackageManager.MASK_PERMISSION_FLAGS, 0);
18355                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
18356                                runtimePermissionChangedUserIds, userId);
18357                    }
18358                }
18359            }
18360        }
18361
18362        return runtimePermissionChangedUserIds;
18363    }
18364
18365    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18366            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18367        // Update the parent package setting
18368        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18369                res, user, installReason);
18370        // Update the child packages setting
18371        final int childCount = (newPackage.childPackages != null)
18372                ? newPackage.childPackages.size() : 0;
18373        for (int i = 0; i < childCount; i++) {
18374            PackageParser.Package childPackage = newPackage.childPackages.get(i);
18375            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18376            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18377                    childRes.origUsers, childRes, user, installReason);
18378        }
18379    }
18380
18381    private void updateSettingsInternalLI(PackageParser.Package newPackage,
18382            String installerPackageName, int[] allUsers, int[] installedForUsers,
18383            PackageInstalledInfo res, UserHandle user, int installReason) {
18384        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18385
18386        String pkgName = newPackage.packageName;
18387        synchronized (mPackages) {
18388            //write settings. the installStatus will be incomplete at this stage.
18389            //note that the new package setting would have already been
18390            //added to mPackages. It hasn't been persisted yet.
18391            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18392            // TODO: Remove this write? It's also written at the end of this method
18393            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18394            mSettings.writeLPr();
18395            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18396        }
18397
18398        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18399        synchronized (mPackages) {
18400            updatePermissionsLPw(newPackage.packageName, newPackage,
18401                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18402                            ? UPDATE_PERMISSIONS_ALL : 0));
18403            // For system-bundled packages, we assume that installing an upgraded version
18404            // of the package implies that the user actually wants to run that new code,
18405            // so we enable the package.
18406            PackageSetting ps = mSettings.mPackages.get(pkgName);
18407            final int userId = user.getIdentifier();
18408            if (ps != null) {
18409                if (isSystemApp(newPackage)) {
18410                    if (DEBUG_INSTALL) {
18411                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18412                    }
18413                    // Enable system package for requested users
18414                    if (res.origUsers != null) {
18415                        for (int origUserId : res.origUsers) {
18416                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
18417                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18418                                        origUserId, installerPackageName);
18419                            }
18420                        }
18421                    }
18422                    // Also convey the prior install/uninstall state
18423                    if (allUsers != null && installedForUsers != null) {
18424                        for (int currentUserId : allUsers) {
18425                            final boolean installed = ArrayUtils.contains(
18426                                    installedForUsers, currentUserId);
18427                            if (DEBUG_INSTALL) {
18428                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
18429                            }
18430                            ps.setInstalled(installed, currentUserId);
18431                        }
18432                        // these install state changes will be persisted in the
18433                        // upcoming call to mSettings.writeLPr().
18434                    }
18435                }
18436                // It's implied that when a user requests installation, they want the app to be
18437                // installed and enabled.
18438                if (userId != UserHandle.USER_ALL) {
18439                    ps.setInstalled(true, userId);
18440                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18441                }
18442
18443                // When replacing an existing package, preserve the original install reason for all
18444                // users that had the package installed before.
18445                final Set<Integer> previousUserIds = new ArraySet<>();
18446                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18447                    final int installReasonCount = res.removedInfo.installReasons.size();
18448                    for (int i = 0; i < installReasonCount; i++) {
18449                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18450                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18451                        ps.setInstallReason(previousInstallReason, previousUserId);
18452                        previousUserIds.add(previousUserId);
18453                    }
18454                }
18455
18456                // Set install reason for users that are having the package newly installed.
18457                if (userId == UserHandle.USER_ALL) {
18458                    for (int currentUserId : sUserManager.getUserIds()) {
18459                        if (!previousUserIds.contains(currentUserId)) {
18460                            ps.setInstallReason(installReason, currentUserId);
18461                        }
18462                    }
18463                } else if (!previousUserIds.contains(userId)) {
18464                    ps.setInstallReason(installReason, userId);
18465                }
18466                mSettings.writeKernelMappingLPr(ps);
18467            }
18468            res.name = pkgName;
18469            res.uid = newPackage.applicationInfo.uid;
18470            res.pkg = newPackage;
18471            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18472            mSettings.setInstallerPackageName(pkgName, installerPackageName);
18473            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18474            //to update install status
18475            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18476            mSettings.writeLPr();
18477            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18478        }
18479
18480        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18481    }
18482
18483    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18484        try {
18485            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18486            installPackageLI(args, res);
18487        } finally {
18488            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18489        }
18490    }
18491
18492    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18493        final int installFlags = args.installFlags;
18494        final String installerPackageName = args.installerPackageName;
18495        final String volumeUuid = args.volumeUuid;
18496        final File tmpPackageFile = new File(args.getCodePath());
18497        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18498        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18499                || (args.volumeUuid != null));
18500        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18501        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18502        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18503        final boolean virtualPreload =
18504                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
18505        boolean replace = false;
18506        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18507        if (args.move != null) {
18508            // moving a complete application; perform an initial scan on the new install location
18509            scanFlags |= SCAN_INITIAL;
18510        }
18511        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18512            scanFlags |= SCAN_DONT_KILL_APP;
18513        }
18514        if (instantApp) {
18515            scanFlags |= SCAN_AS_INSTANT_APP;
18516        }
18517        if (fullApp) {
18518            scanFlags |= SCAN_AS_FULL_APP;
18519        }
18520        if (virtualPreload) {
18521            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
18522        }
18523
18524        // Result object to be returned
18525        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18526        res.installerPackageName = installerPackageName;
18527
18528        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18529
18530        // Sanity check
18531        if (instantApp && (forwardLocked || onExternal)) {
18532            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18533                    + " external=" + onExternal);
18534            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18535            return;
18536        }
18537
18538        // Retrieve PackageSettings and parse package
18539        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18540                | PackageParser.PARSE_ENFORCE_CODE
18541                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18542                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18543                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18544                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18545        PackageParser pp = new PackageParser();
18546        pp.setSeparateProcesses(mSeparateProcesses);
18547        pp.setDisplayMetrics(mMetrics);
18548        pp.setCallback(mPackageParserCallback);
18549
18550        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18551        final PackageParser.Package pkg;
18552        try {
18553            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18554        } catch (PackageParserException e) {
18555            res.setError("Failed parse during installPackageLI", e);
18556            return;
18557        } finally {
18558            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18559        }
18560
18561        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18562        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18563            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18564            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18565                    "Instant app package must target O");
18566            return;
18567        }
18568        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18569            Slog.w(TAG, "Instant app package " + pkg.packageName
18570                    + " does not target targetSandboxVersion 2");
18571            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18572                    "Instant app package must use targetSanboxVersion 2");
18573            return;
18574        }
18575
18576        if (pkg.applicationInfo.isStaticSharedLibrary()) {
18577            // Static shared libraries have synthetic package names
18578            renameStaticSharedLibraryPackage(pkg);
18579
18580            // No static shared libs on external storage
18581            if (onExternal) {
18582                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18583                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18584                        "Packages declaring static-shared libs cannot be updated");
18585                return;
18586            }
18587        }
18588
18589        // If we are installing a clustered package add results for the children
18590        if (pkg.childPackages != null) {
18591            synchronized (mPackages) {
18592                final int childCount = pkg.childPackages.size();
18593                for (int i = 0; i < childCount; i++) {
18594                    PackageParser.Package childPkg = pkg.childPackages.get(i);
18595                    PackageInstalledInfo childRes = new PackageInstalledInfo();
18596                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18597                    childRes.pkg = childPkg;
18598                    childRes.name = childPkg.packageName;
18599                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18600                    if (childPs != null) {
18601                        childRes.origUsers = childPs.queryInstalledUsers(
18602                                sUserManager.getUserIds(), true);
18603                    }
18604                    if ((mPackages.containsKey(childPkg.packageName))) {
18605                        childRes.removedInfo = new PackageRemovedInfo(this);
18606                        childRes.removedInfo.removedPackage = childPkg.packageName;
18607                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18608                    }
18609                    if (res.addedChildPackages == null) {
18610                        res.addedChildPackages = new ArrayMap<>();
18611                    }
18612                    res.addedChildPackages.put(childPkg.packageName, childRes);
18613                }
18614            }
18615        }
18616
18617        // If package doesn't declare API override, mark that we have an install
18618        // time CPU ABI override.
18619        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18620            pkg.cpuAbiOverride = args.abiOverride;
18621        }
18622
18623        String pkgName = res.name = pkg.packageName;
18624        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18625            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18626                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18627                return;
18628            }
18629        }
18630
18631        try {
18632            // either use what we've been given or parse directly from the APK
18633            if (args.certificates != null) {
18634                try {
18635                    PackageParser.populateCertificates(pkg, args.certificates);
18636                } catch (PackageParserException e) {
18637                    // there was something wrong with the certificates we were given;
18638                    // try to pull them from the APK
18639                    PackageParser.collectCertificates(pkg, parseFlags);
18640                }
18641            } else {
18642                PackageParser.collectCertificates(pkg, parseFlags);
18643            }
18644        } catch (PackageParserException e) {
18645            res.setError("Failed collect during installPackageLI", e);
18646            return;
18647        }
18648
18649        // Get rid of all references to package scan path via parser.
18650        pp = null;
18651        String oldCodePath = null;
18652        boolean systemApp = false;
18653        synchronized (mPackages) {
18654            // Check if installing already existing package
18655            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18656                String oldName = mSettings.getRenamedPackageLPr(pkgName);
18657                if (pkg.mOriginalPackages != null
18658                        && pkg.mOriginalPackages.contains(oldName)
18659                        && mPackages.containsKey(oldName)) {
18660                    // This package is derived from an original package,
18661                    // and this device has been updating from that original
18662                    // name.  We must continue using the original name, so
18663                    // rename the new package here.
18664                    pkg.setPackageName(oldName);
18665                    pkgName = pkg.packageName;
18666                    replace = true;
18667                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18668                            + oldName + " pkgName=" + pkgName);
18669                } else if (mPackages.containsKey(pkgName)) {
18670                    // This package, under its official name, already exists
18671                    // on the device; we should replace it.
18672                    replace = true;
18673                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18674                }
18675
18676                // Child packages are installed through the parent package
18677                if (pkg.parentPackage != null) {
18678                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18679                            "Package " + pkg.packageName + " is child of package "
18680                                    + pkg.parentPackage.parentPackage + ". Child packages "
18681                                    + "can be updated only through the parent package.");
18682                    return;
18683                }
18684
18685                if (replace) {
18686                    // Prevent apps opting out from runtime permissions
18687                    PackageParser.Package oldPackage = mPackages.get(pkgName);
18688                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18689                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18690                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18691                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18692                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18693                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18694                                        + " doesn't support runtime permissions but the old"
18695                                        + " target SDK " + oldTargetSdk + " does.");
18696                        return;
18697                    }
18698                    // Prevent apps from downgrading their targetSandbox.
18699                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18700                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18701                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18702                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18703                                "Package " + pkg.packageName + " new target sandbox "
18704                                + newTargetSandbox + " is incompatible with the previous value of"
18705                                + oldTargetSandbox + ".");
18706                        return;
18707                    }
18708
18709                    // Prevent installing of child packages
18710                    if (oldPackage.parentPackage != null) {
18711                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18712                                "Package " + pkg.packageName + " is child of package "
18713                                        + oldPackage.parentPackage + ". Child packages "
18714                                        + "can be updated only through the parent package.");
18715                        return;
18716                    }
18717                }
18718            }
18719
18720            PackageSetting ps = mSettings.mPackages.get(pkgName);
18721            if (ps != null) {
18722                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18723
18724                // Static shared libs have same package with different versions where
18725                // we internally use a synthetic package name to allow multiple versions
18726                // of the same package, therefore we need to compare signatures against
18727                // the package setting for the latest library version.
18728                PackageSetting signatureCheckPs = ps;
18729                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18730                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18731                    if (libraryEntry != null) {
18732                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18733                    }
18734                }
18735
18736                // Quick sanity check that we're signed correctly if updating;
18737                // we'll check this again later when scanning, but we want to
18738                // bail early here before tripping over redefined permissions.
18739                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18740                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18741                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18742                                + pkg.packageName + " upgrade keys do not match the "
18743                                + "previously installed version");
18744                        return;
18745                    }
18746                } else {
18747                    try {
18748                        verifySignaturesLP(signatureCheckPs, pkg);
18749                    } catch (PackageManagerException e) {
18750                        res.setError(e.error, e.getMessage());
18751                        return;
18752                    }
18753                }
18754
18755                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18756                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18757                    systemApp = (ps.pkg.applicationInfo.flags &
18758                            ApplicationInfo.FLAG_SYSTEM) != 0;
18759                }
18760                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18761            }
18762
18763            int N = pkg.permissions.size();
18764            for (int i = N-1; i >= 0; i--) {
18765                PackageParser.Permission perm = pkg.permissions.get(i);
18766                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18767
18768                // Don't allow anyone but the system to define ephemeral permissions.
18769                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
18770                        && !systemApp) {
18771                    Slog.w(TAG, "Non-System package " + pkg.packageName
18772                            + " attempting to delcare ephemeral permission "
18773                            + perm.info.name + "; Removing ephemeral.");
18774                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
18775                }
18776                // Check whether the newly-scanned package wants to define an already-defined perm
18777                if (bp != null) {
18778                    // If the defining package is signed with our cert, it's okay.  This
18779                    // also includes the "updating the same package" case, of course.
18780                    // "updating same package" could also involve key-rotation.
18781                    final boolean sigsOk;
18782                    if (bp.sourcePackage.equals(pkg.packageName)
18783                            && (bp.packageSetting instanceof PackageSetting)
18784                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18785                                    scanFlags))) {
18786                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18787                    } else {
18788                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18789                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18790                    }
18791                    if (!sigsOk) {
18792                        // If the owning package is the system itself, we log but allow
18793                        // install to proceed; we fail the install on all other permission
18794                        // redefinitions.
18795                        if (!bp.sourcePackage.equals("android")) {
18796                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18797                                    + pkg.packageName + " attempting to redeclare permission "
18798                                    + perm.info.name + " already owned by " + bp.sourcePackage);
18799                            res.origPermission = perm.info.name;
18800                            res.origPackage = bp.sourcePackage;
18801                            return;
18802                        } else {
18803                            Slog.w(TAG, "Package " + pkg.packageName
18804                                    + " attempting to redeclare system permission "
18805                                    + perm.info.name + "; ignoring new declaration");
18806                            pkg.permissions.remove(i);
18807                        }
18808                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18809                        // Prevent apps to change protection level to dangerous from any other
18810                        // type as this would allow a privilege escalation where an app adds a
18811                        // normal/signature permission in other app's group and later redefines
18812                        // it as dangerous leading to the group auto-grant.
18813                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18814                                == PermissionInfo.PROTECTION_DANGEROUS) {
18815                            if (bp != null && !bp.isRuntime()) {
18816                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18817                                        + "non-runtime permission " + perm.info.name
18818                                        + " to runtime; keeping old protection level");
18819                                perm.info.protectionLevel = bp.protectionLevel;
18820                            }
18821                        }
18822                    }
18823                }
18824            }
18825        }
18826
18827        if (systemApp) {
18828            if (onExternal) {
18829                // Abort update; system app can't be replaced with app on sdcard
18830                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18831                        "Cannot install updates to system apps on sdcard");
18832                return;
18833            } else if (instantApp) {
18834                // Abort update; system app can't be replaced with an instant app
18835                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18836                        "Cannot update a system app with an instant app");
18837                return;
18838            }
18839        }
18840
18841        if (args.move != null) {
18842            // We did an in-place move, so dex is ready to roll
18843            scanFlags |= SCAN_NO_DEX;
18844            scanFlags |= SCAN_MOVE;
18845
18846            synchronized (mPackages) {
18847                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18848                if (ps == null) {
18849                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18850                            "Missing settings for moved package " + pkgName);
18851                }
18852
18853                // We moved the entire application as-is, so bring over the
18854                // previously derived ABI information.
18855                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18856                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18857            }
18858
18859        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18860            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18861            scanFlags |= SCAN_NO_DEX;
18862
18863            try {
18864                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18865                    args.abiOverride : pkg.cpuAbiOverride);
18866                final boolean extractNativeLibs = !pkg.isLibrary();
18867                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18868                        extractNativeLibs, mAppLib32InstallDir);
18869            } catch (PackageManagerException pme) {
18870                Slog.e(TAG, "Error deriving application ABI", pme);
18871                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18872                return;
18873            }
18874
18875            // Shared libraries for the package need to be updated.
18876            synchronized (mPackages) {
18877                try {
18878                    updateSharedLibrariesLPr(pkg, null);
18879                } catch (PackageManagerException e) {
18880                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18881                }
18882            }
18883        }
18884
18885        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18886            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18887            return;
18888        }
18889
18890        // Verify if we need to dexopt the app.
18891        //
18892        // NOTE: it is *important* to call dexopt after doRename which will sync the
18893        // package data from PackageParser.Package and its corresponding ApplicationInfo.
18894        //
18895        // We only need to dexopt if the package meets ALL of the following conditions:
18896        //   1) it is not forward locked.
18897        //   2) it is not on on an external ASEC container.
18898        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
18899        //
18900        // Note that we do not dexopt instant apps by default. dexopt can take some time to
18901        // complete, so we skip this step during installation. Instead, we'll take extra time
18902        // the first time the instant app starts. It's preferred to do it this way to provide
18903        // continuous progress to the useur instead of mysteriously blocking somewhere in the
18904        // middle of running an instant app. The default behaviour can be overridden
18905        // via gservices.
18906        final boolean performDexopt = !forwardLocked
18907            && !pkg.applicationInfo.isExternalAsec()
18908            && (!instantApp || Global.getInt(mContext.getContentResolver(),
18909                    Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
18910
18911        if (performDexopt) {
18912            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18913            // Do not run PackageDexOptimizer through the local performDexOpt
18914            // method because `pkg` may not be in `mPackages` yet.
18915            //
18916            // Also, don't fail application installs if the dexopt step fails.
18917            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18918                REASON_INSTALL,
18919                DexoptOptions.DEXOPT_BOOT_COMPLETE);
18920            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18921                null /* instructionSets */,
18922                getOrCreateCompilerPackageStats(pkg),
18923                mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
18924                dexoptOptions);
18925            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18926        }
18927
18928        // Notify BackgroundDexOptService that the package has been changed.
18929        // If this is an update of a package which used to fail to compile,
18930        // BackgroundDexOptService will remove it from its blacklist.
18931        // TODO: Layering violation
18932        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18933
18934        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18935
18936        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18937                "installPackageLI")) {
18938            if (replace) {
18939                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18940                    // Static libs have a synthetic package name containing the version
18941                    // and cannot be updated as an update would get a new package name,
18942                    // unless this is the exact same version code which is useful for
18943                    // development.
18944                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18945                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18946                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18947                                + "static-shared libs cannot be updated");
18948                        return;
18949                    }
18950                }
18951                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18952                        installerPackageName, res, args.installReason);
18953            } else {
18954                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18955                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18956            }
18957        }
18958
18959        synchronized (mPackages) {
18960            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18961            if (ps != null) {
18962                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18963                ps.setUpdateAvailable(false /*updateAvailable*/);
18964            }
18965
18966            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18967            for (int i = 0; i < childCount; i++) {
18968                PackageParser.Package childPkg = pkg.childPackages.get(i);
18969                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18970                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18971                if (childPs != null) {
18972                    childRes.newUsers = childPs.queryInstalledUsers(
18973                            sUserManager.getUserIds(), true);
18974                }
18975            }
18976
18977            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18978                updateSequenceNumberLP(ps, res.newUsers);
18979                updateInstantAppInstallerLocked(pkgName);
18980            }
18981        }
18982    }
18983
18984    private void startIntentFilterVerifications(int userId, boolean replacing,
18985            PackageParser.Package pkg) {
18986        if (mIntentFilterVerifierComponent == null) {
18987            Slog.w(TAG, "No IntentFilter verification will not be done as "
18988                    + "there is no IntentFilterVerifier available!");
18989            return;
18990        }
18991
18992        final int verifierUid = getPackageUid(
18993                mIntentFilterVerifierComponent.getPackageName(),
18994                MATCH_DEBUG_TRIAGED_MISSING,
18995                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18996
18997        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18998        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18999        mHandler.sendMessage(msg);
19000
19001        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
19002        for (int i = 0; i < childCount; i++) {
19003            PackageParser.Package childPkg = pkg.childPackages.get(i);
19004            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
19005            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
19006            mHandler.sendMessage(msg);
19007        }
19008    }
19009
19010    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
19011            PackageParser.Package pkg) {
19012        int size = pkg.activities.size();
19013        if (size == 0) {
19014            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19015                    "No activity, so no need to verify any IntentFilter!");
19016            return;
19017        }
19018
19019        final boolean hasDomainURLs = hasDomainURLs(pkg);
19020        if (!hasDomainURLs) {
19021            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19022                    "No domain URLs, so no need to verify any IntentFilter!");
19023            return;
19024        }
19025
19026        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
19027                + " if any IntentFilter from the " + size
19028                + " Activities needs verification ...");
19029
19030        int count = 0;
19031        final String packageName = pkg.packageName;
19032
19033        synchronized (mPackages) {
19034            // If this is a new install and we see that we've already run verification for this
19035            // package, we have nothing to do: it means the state was restored from backup.
19036            if (!replacing) {
19037                IntentFilterVerificationInfo ivi =
19038                        mSettings.getIntentFilterVerificationLPr(packageName);
19039                if (ivi != null) {
19040                    if (DEBUG_DOMAIN_VERIFICATION) {
19041                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
19042                                + ivi.getStatusString());
19043                    }
19044                    return;
19045                }
19046            }
19047
19048            // If any filters need to be verified, then all need to be.
19049            boolean needToVerify = false;
19050            for (PackageParser.Activity a : pkg.activities) {
19051                for (ActivityIntentInfo filter : a.intents) {
19052                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
19053                        if (DEBUG_DOMAIN_VERIFICATION) {
19054                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
19055                        }
19056                        needToVerify = true;
19057                        break;
19058                    }
19059                }
19060            }
19061
19062            if (needToVerify) {
19063                final int verificationId = mIntentFilterVerificationToken++;
19064                for (PackageParser.Activity a : pkg.activities) {
19065                    for (ActivityIntentInfo filter : a.intents) {
19066                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
19067                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
19068                                    "Verification needed for IntentFilter:" + filter.toString());
19069                            mIntentFilterVerifier.addOneIntentFilterVerification(
19070                                    verifierUid, userId, verificationId, filter, packageName);
19071                            count++;
19072                        }
19073                    }
19074                }
19075            }
19076        }
19077
19078        if (count > 0) {
19079            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
19080                    + " IntentFilter verification" + (count > 1 ? "s" : "")
19081                    +  " for userId:" + userId);
19082            mIntentFilterVerifier.startVerifications(userId);
19083        } else {
19084            if (DEBUG_DOMAIN_VERIFICATION) {
19085                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
19086            }
19087        }
19088    }
19089
19090    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
19091        final ComponentName cn  = filter.activity.getComponentName();
19092        final String packageName = cn.getPackageName();
19093
19094        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
19095                packageName);
19096        if (ivi == null) {
19097            return true;
19098        }
19099        int status = ivi.getStatus();
19100        switch (status) {
19101            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
19102            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
19103                return true;
19104
19105            default:
19106                // Nothing to do
19107                return false;
19108        }
19109    }
19110
19111    private static boolean isMultiArch(ApplicationInfo info) {
19112        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
19113    }
19114
19115    private static boolean isExternal(PackageParser.Package pkg) {
19116        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19117    }
19118
19119    private static boolean isExternal(PackageSetting ps) {
19120        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
19121    }
19122
19123    private static boolean isSystemApp(PackageParser.Package pkg) {
19124        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
19125    }
19126
19127    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
19128        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
19129    }
19130
19131    private static boolean hasDomainURLs(PackageParser.Package pkg) {
19132        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
19133    }
19134
19135    private static boolean isSystemApp(PackageSetting ps) {
19136        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
19137    }
19138
19139    private static boolean isUpdatedSystemApp(PackageSetting ps) {
19140        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
19141    }
19142
19143    private int packageFlagsToInstallFlags(PackageSetting ps) {
19144        int installFlags = 0;
19145        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
19146            // This existing package was an external ASEC install when we have
19147            // the external flag without a UUID
19148            installFlags |= PackageManager.INSTALL_EXTERNAL;
19149        }
19150        if (ps.isForwardLocked()) {
19151            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
19152        }
19153        return installFlags;
19154    }
19155
19156    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
19157        if (isExternal(pkg)) {
19158            if (TextUtils.isEmpty(pkg.volumeUuid)) {
19159                return StorageManager.UUID_PRIMARY_PHYSICAL;
19160            } else {
19161                return pkg.volumeUuid;
19162            }
19163        } else {
19164            return StorageManager.UUID_PRIVATE_INTERNAL;
19165        }
19166    }
19167
19168    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
19169        if (isExternal(pkg)) {
19170            if (TextUtils.isEmpty(pkg.volumeUuid)) {
19171                return mSettings.getExternalVersion();
19172            } else {
19173                return mSettings.findOrCreateVersion(pkg.volumeUuid);
19174            }
19175        } else {
19176            return mSettings.getInternalVersion();
19177        }
19178    }
19179
19180    private void deleteTempPackageFiles() {
19181        final FilenameFilter filter = new FilenameFilter() {
19182            public boolean accept(File dir, String name) {
19183                return name.startsWith("vmdl") && name.endsWith(".tmp");
19184            }
19185        };
19186        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
19187            file.delete();
19188        }
19189    }
19190
19191    @Override
19192    public void deletePackageAsUser(String packageName, int versionCode,
19193            IPackageDeleteObserver observer, int userId, int flags) {
19194        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
19195                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
19196    }
19197
19198    @Override
19199    public void deletePackageVersioned(VersionedPackage versionedPackage,
19200            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
19201        final int callingUid = Binder.getCallingUid();
19202        mContext.enforceCallingOrSelfPermission(
19203                android.Manifest.permission.DELETE_PACKAGES, null);
19204        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
19205        Preconditions.checkNotNull(versionedPackage);
19206        Preconditions.checkNotNull(observer);
19207        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
19208                PackageManager.VERSION_CODE_HIGHEST,
19209                Integer.MAX_VALUE, "versionCode must be >= -1");
19210
19211        final String packageName = versionedPackage.getPackageName();
19212        final int versionCode = versionedPackage.getVersionCode();
19213        final String internalPackageName;
19214        synchronized (mPackages) {
19215            // Normalize package name to handle renamed packages and static libs
19216            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
19217                    versionedPackage.getVersionCode());
19218        }
19219
19220        final int uid = Binder.getCallingUid();
19221        if (!isOrphaned(internalPackageName)
19222                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
19223            try {
19224                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
19225                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
19226                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
19227                observer.onUserActionRequired(intent);
19228            } catch (RemoteException re) {
19229            }
19230            return;
19231        }
19232        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
19233        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
19234        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
19235            mContext.enforceCallingOrSelfPermission(
19236                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
19237                    "deletePackage for user " + userId);
19238        }
19239
19240        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
19241            try {
19242                observer.onPackageDeleted(packageName,
19243                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
19244            } catch (RemoteException re) {
19245            }
19246            return;
19247        }
19248
19249        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
19250            try {
19251                observer.onPackageDeleted(packageName,
19252                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
19253            } catch (RemoteException re) {
19254            }
19255            return;
19256        }
19257
19258        if (DEBUG_REMOVE) {
19259            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
19260                    + " deleteAllUsers: " + deleteAllUsers + " version="
19261                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
19262                    ? "VERSION_CODE_HIGHEST" : versionCode));
19263        }
19264        // Queue up an async operation since the package deletion may take a little while.
19265        mHandler.post(new Runnable() {
19266            public void run() {
19267                mHandler.removeCallbacks(this);
19268                int returnCode;
19269                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
19270                boolean doDeletePackage = true;
19271                if (ps != null) {
19272                    final boolean targetIsInstantApp =
19273                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19274                    doDeletePackage = !targetIsInstantApp
19275                            || canViewInstantApps;
19276                }
19277                if (doDeletePackage) {
19278                    if (!deleteAllUsers) {
19279                        returnCode = deletePackageX(internalPackageName, versionCode,
19280                                userId, deleteFlags);
19281                    } else {
19282                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
19283                                internalPackageName, users);
19284                        // If nobody is blocking uninstall, proceed with delete for all users
19285                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
19286                            returnCode = deletePackageX(internalPackageName, versionCode,
19287                                    userId, deleteFlags);
19288                        } else {
19289                            // Otherwise uninstall individually for users with blockUninstalls=false
19290                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
19291                            for (int userId : users) {
19292                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
19293                                    returnCode = deletePackageX(internalPackageName, versionCode,
19294                                            userId, userFlags);
19295                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
19296                                        Slog.w(TAG, "Package delete failed for user " + userId
19297                                                + ", returnCode " + returnCode);
19298                                    }
19299                                }
19300                            }
19301                            // The app has only been marked uninstalled for certain users.
19302                            // We still need to report that delete was blocked
19303                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
19304                        }
19305                    }
19306                } else {
19307                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19308                }
19309                try {
19310                    observer.onPackageDeleted(packageName, returnCode, null);
19311                } catch (RemoteException e) {
19312                    Log.i(TAG, "Observer no longer exists.");
19313                } //end catch
19314            } //end run
19315        });
19316    }
19317
19318    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
19319        if (pkg.staticSharedLibName != null) {
19320            return pkg.manifestPackageName;
19321        }
19322        return pkg.packageName;
19323    }
19324
19325    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
19326        // Handle renamed packages
19327        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
19328        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
19329
19330        // Is this a static library?
19331        SparseArray<SharedLibraryEntry> versionedLib =
19332                mStaticLibsByDeclaringPackage.get(packageName);
19333        if (versionedLib == null || versionedLib.size() <= 0) {
19334            return packageName;
19335        }
19336
19337        // Figure out which lib versions the caller can see
19338        SparseIntArray versionsCallerCanSee = null;
19339        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
19340        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
19341                && callingAppId != Process.ROOT_UID) {
19342            versionsCallerCanSee = new SparseIntArray();
19343            String libName = versionedLib.valueAt(0).info.getName();
19344            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
19345            if (uidPackages != null) {
19346                for (String uidPackage : uidPackages) {
19347                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
19348                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
19349                    if (libIdx >= 0) {
19350                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
19351                        versionsCallerCanSee.append(libVersion, libVersion);
19352                    }
19353                }
19354            }
19355        }
19356
19357        // Caller can see nothing - done
19358        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
19359            return packageName;
19360        }
19361
19362        // Find the version the caller can see and the app version code
19363        SharedLibraryEntry highestVersion = null;
19364        final int versionCount = versionedLib.size();
19365        for (int i = 0; i < versionCount; i++) {
19366            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
19367            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
19368                    libEntry.info.getVersion()) < 0) {
19369                continue;
19370            }
19371            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
19372            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
19373                if (libVersionCode == versionCode) {
19374                    return libEntry.apk;
19375                }
19376            } else if (highestVersion == null) {
19377                highestVersion = libEntry;
19378            } else if (libVersionCode  > highestVersion.info
19379                    .getDeclaringPackage().getVersionCode()) {
19380                highestVersion = libEntry;
19381            }
19382        }
19383
19384        if (highestVersion != null) {
19385            return highestVersion.apk;
19386        }
19387
19388        return packageName;
19389    }
19390
19391    boolean isCallerVerifier(int callingUid) {
19392        final int callingUserId = UserHandle.getUserId(callingUid);
19393        return mRequiredVerifierPackage != null &&
19394                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19395    }
19396
19397    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19398        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19399              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19400            return true;
19401        }
19402        final int callingUserId = UserHandle.getUserId(callingUid);
19403        // If the caller installed the pkgName, then allow it to silently uninstall.
19404        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19405            return true;
19406        }
19407
19408        // Allow package verifier to silently uninstall.
19409        if (mRequiredVerifierPackage != null &&
19410                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19411            return true;
19412        }
19413
19414        // Allow package uninstaller to silently uninstall.
19415        if (mRequiredUninstallerPackage != null &&
19416                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19417            return true;
19418        }
19419
19420        // Allow storage manager to silently uninstall.
19421        if (mStorageManagerPackage != null &&
19422                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19423            return true;
19424        }
19425
19426        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19427        // uninstall for device owner provisioning.
19428        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19429                == PERMISSION_GRANTED) {
19430            return true;
19431        }
19432
19433        return false;
19434    }
19435
19436    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19437        int[] result = EMPTY_INT_ARRAY;
19438        for (int userId : userIds) {
19439            if (getBlockUninstallForUser(packageName, userId)) {
19440                result = ArrayUtils.appendInt(result, userId);
19441            }
19442        }
19443        return result;
19444    }
19445
19446    @Override
19447    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19448        final int callingUid = Binder.getCallingUid();
19449        if (getInstantAppPackageName(callingUid) != null
19450                && !isCallerSameApp(packageName, callingUid)) {
19451            return false;
19452        }
19453        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19454    }
19455
19456    private boolean isPackageDeviceAdmin(String packageName, int userId) {
19457        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19458                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19459        try {
19460            if (dpm != null) {
19461                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19462                        /* callingUserOnly =*/ false);
19463                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19464                        : deviceOwnerComponentName.getPackageName();
19465                // Does the package contains the device owner?
19466                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
19467                // this check is probably not needed, since DO should be registered as a device
19468                // admin on some user too. (Original bug for this: b/17657954)
19469                if (packageName.equals(deviceOwnerPackageName)) {
19470                    return true;
19471                }
19472                // Does it contain a device admin for any user?
19473                int[] users;
19474                if (userId == UserHandle.USER_ALL) {
19475                    users = sUserManager.getUserIds();
19476                } else {
19477                    users = new int[]{userId};
19478                }
19479                for (int i = 0; i < users.length; ++i) {
19480                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19481                        return true;
19482                    }
19483                }
19484            }
19485        } catch (RemoteException e) {
19486        }
19487        return false;
19488    }
19489
19490    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19491        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19492    }
19493
19494    /**
19495     *  This method is an internal method that could be get invoked either
19496     *  to delete an installed package or to clean up a failed installation.
19497     *  After deleting an installed package, a broadcast is sent to notify any
19498     *  listeners that the package has been removed. For cleaning up a failed
19499     *  installation, the broadcast is not necessary since the package's
19500     *  installation wouldn't have sent the initial broadcast either
19501     *  The key steps in deleting a package are
19502     *  deleting the package information in internal structures like mPackages,
19503     *  deleting the packages base directories through installd
19504     *  updating mSettings to reflect current status
19505     *  persisting settings for later use
19506     *  sending a broadcast if necessary
19507     */
19508    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19509        final PackageRemovedInfo info = new PackageRemovedInfo(this);
19510        final boolean res;
19511
19512        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19513                ? UserHandle.USER_ALL : userId;
19514
19515        if (isPackageDeviceAdmin(packageName, removeUser)) {
19516            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19517            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19518        }
19519
19520        PackageSetting uninstalledPs = null;
19521        PackageParser.Package pkg = null;
19522
19523        // for the uninstall-updates case and restricted profiles, remember the per-
19524        // user handle installed state
19525        int[] allUsers;
19526        synchronized (mPackages) {
19527            uninstalledPs = mSettings.mPackages.get(packageName);
19528            if (uninstalledPs == null) {
19529                Slog.w(TAG, "Not removing non-existent package " + packageName);
19530                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19531            }
19532
19533            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19534                    && uninstalledPs.versionCode != versionCode) {
19535                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19536                        + uninstalledPs.versionCode + " != " + versionCode);
19537                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19538            }
19539
19540            // Static shared libs can be declared by any package, so let us not
19541            // allow removing a package if it provides a lib others depend on.
19542            pkg = mPackages.get(packageName);
19543
19544            allUsers = sUserManager.getUserIds();
19545
19546            if (pkg != null && pkg.staticSharedLibName != null) {
19547                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19548                        pkg.staticSharedLibVersion);
19549                if (libEntry != null) {
19550                    for (int currUserId : allUsers) {
19551                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19552                            continue;
19553                        }
19554                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19555                                libEntry.info, 0, currUserId);
19556                        if (!ArrayUtils.isEmpty(libClientPackages)) {
19557                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19558                                    + " hosting lib " + libEntry.info.getName() + " version "
19559                                    + libEntry.info.getVersion() + " used by " + libClientPackages
19560                                    + " for user " + currUserId);
19561                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19562                        }
19563                    }
19564                }
19565            }
19566
19567            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19568        }
19569
19570        final int freezeUser;
19571        if (isUpdatedSystemApp(uninstalledPs)
19572                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19573            // We're downgrading a system app, which will apply to all users, so
19574            // freeze them all during the downgrade
19575            freezeUser = UserHandle.USER_ALL;
19576        } else {
19577            freezeUser = removeUser;
19578        }
19579
19580        synchronized (mInstallLock) {
19581            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19582            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19583                    deleteFlags, "deletePackageX")) {
19584                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19585                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19586            }
19587            synchronized (mPackages) {
19588                if (res) {
19589                    if (pkg != null) {
19590                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19591                    }
19592                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19593                    updateInstantAppInstallerLocked(packageName);
19594                }
19595            }
19596        }
19597
19598        if (res) {
19599            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19600            info.sendPackageRemovedBroadcasts(killApp);
19601            info.sendSystemPackageUpdatedBroadcasts();
19602            info.sendSystemPackageAppearedBroadcasts();
19603        }
19604        // Force a gc here.
19605        Runtime.getRuntime().gc();
19606        // Delete the resources here after sending the broadcast to let
19607        // other processes clean up before deleting resources.
19608        if (info.args != null) {
19609            synchronized (mInstallLock) {
19610                info.args.doPostDeleteLI(true);
19611            }
19612        }
19613
19614        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19615    }
19616
19617    static class PackageRemovedInfo {
19618        final PackageSender packageSender;
19619        String removedPackage;
19620        String installerPackageName;
19621        int uid = -1;
19622        int removedAppId = -1;
19623        int[] origUsers;
19624        int[] removedUsers = null;
19625        int[] broadcastUsers = null;
19626        SparseArray<Integer> installReasons;
19627        boolean isRemovedPackageSystemUpdate = false;
19628        boolean isUpdate;
19629        boolean dataRemoved;
19630        boolean removedForAllUsers;
19631        boolean isStaticSharedLib;
19632        // Clean up resources deleted packages.
19633        InstallArgs args = null;
19634        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19635        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19636
19637        PackageRemovedInfo(PackageSender packageSender) {
19638            this.packageSender = packageSender;
19639        }
19640
19641        void sendPackageRemovedBroadcasts(boolean killApp) {
19642            sendPackageRemovedBroadcastInternal(killApp);
19643            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19644            for (int i = 0; i < childCount; i++) {
19645                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19646                childInfo.sendPackageRemovedBroadcastInternal(killApp);
19647            }
19648        }
19649
19650        void sendSystemPackageUpdatedBroadcasts() {
19651            if (isRemovedPackageSystemUpdate) {
19652                sendSystemPackageUpdatedBroadcastsInternal();
19653                final int childCount = (removedChildPackages != null)
19654                        ? removedChildPackages.size() : 0;
19655                for (int i = 0; i < childCount; i++) {
19656                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19657                    if (childInfo.isRemovedPackageSystemUpdate) {
19658                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19659                    }
19660                }
19661            }
19662        }
19663
19664        void sendSystemPackageAppearedBroadcasts() {
19665            final int packageCount = (appearedChildPackages != null)
19666                    ? appearedChildPackages.size() : 0;
19667            for (int i = 0; i < packageCount; i++) {
19668                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19669                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19670                    true /*sendBootCompleted*/, false /*startReceiver*/,
19671                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19672            }
19673        }
19674
19675        private void sendSystemPackageUpdatedBroadcastsInternal() {
19676            Bundle extras = new Bundle(2);
19677            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19678            extras.putBoolean(Intent.EXTRA_REPLACING, true);
19679            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19680                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19681            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19682                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19683            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19684                null, null, 0, removedPackage, null, null);
19685            if (installerPackageName != null) {
19686                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19687                        removedPackage, extras, 0 /*flags*/,
19688                        installerPackageName, null, null);
19689                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19690                        removedPackage, extras, 0 /*flags*/,
19691                        installerPackageName, null, null);
19692            }
19693        }
19694
19695        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19696            // Don't send static shared library removal broadcasts as these
19697            // libs are visible only the the apps that depend on them an one
19698            // cannot remove the library if it has a dependency.
19699            if (isStaticSharedLib) {
19700                return;
19701            }
19702            Bundle extras = new Bundle(2);
19703            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19704            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19705            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19706            if (isUpdate || isRemovedPackageSystemUpdate) {
19707                extras.putBoolean(Intent.EXTRA_REPLACING, true);
19708            }
19709            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19710            if (removedPackage != null) {
19711                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19712                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19713                if (installerPackageName != null) {
19714                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19715                            removedPackage, extras, 0 /*flags*/,
19716                            installerPackageName, null, broadcastUsers);
19717                }
19718                if (dataRemoved && !isRemovedPackageSystemUpdate) {
19719                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19720                        removedPackage, extras,
19721                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19722                        null, null, broadcastUsers);
19723                }
19724            }
19725            if (removedAppId >= 0) {
19726                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19727                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19728                    null, null, broadcastUsers);
19729            }
19730        }
19731
19732        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19733            removedUsers = userIds;
19734            if (removedUsers == null) {
19735                broadcastUsers = null;
19736                return;
19737            }
19738
19739            broadcastUsers = EMPTY_INT_ARRAY;
19740            for (int i = userIds.length - 1; i >= 0; --i) {
19741                final int userId = userIds[i];
19742                if (deletedPackageSetting.getInstantApp(userId)) {
19743                    continue;
19744                }
19745                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19746            }
19747        }
19748    }
19749
19750    /*
19751     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19752     * flag is not set, the data directory is removed as well.
19753     * make sure this flag is set for partially installed apps. If not its meaningless to
19754     * delete a partially installed application.
19755     */
19756    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19757            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19758        String packageName = ps.name;
19759        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19760        // Retrieve object to delete permissions for shared user later on
19761        final PackageParser.Package deletedPkg;
19762        final PackageSetting deletedPs;
19763        // reader
19764        synchronized (mPackages) {
19765            deletedPkg = mPackages.get(packageName);
19766            deletedPs = mSettings.mPackages.get(packageName);
19767            if (outInfo != null) {
19768                outInfo.removedPackage = packageName;
19769                outInfo.installerPackageName = ps.installerPackageName;
19770                outInfo.isStaticSharedLib = deletedPkg != null
19771                        && deletedPkg.staticSharedLibName != null;
19772                outInfo.populateUsers(deletedPs == null ? null
19773                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19774            }
19775        }
19776
19777        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19778
19779        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19780            final PackageParser.Package resolvedPkg;
19781            if (deletedPkg != null) {
19782                resolvedPkg = deletedPkg;
19783            } else {
19784                // We don't have a parsed package when it lives on an ejected
19785                // adopted storage device, so fake something together
19786                resolvedPkg = new PackageParser.Package(ps.name);
19787                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19788            }
19789            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19790                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19791            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19792            if (outInfo != null) {
19793                outInfo.dataRemoved = true;
19794            }
19795            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19796        }
19797
19798        int removedAppId = -1;
19799
19800        // writer
19801        synchronized (mPackages) {
19802            boolean installedStateChanged = false;
19803            if (deletedPs != null) {
19804                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19805                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19806                    clearDefaultBrowserIfNeeded(packageName);
19807                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19808                    removedAppId = mSettings.removePackageLPw(packageName);
19809                    if (outInfo != null) {
19810                        outInfo.removedAppId = removedAppId;
19811                    }
19812                    updatePermissionsLPw(deletedPs.name, null, 0);
19813                    if (deletedPs.sharedUser != null) {
19814                        // Remove permissions associated with package. Since runtime
19815                        // permissions are per user we have to kill the removed package
19816                        // or packages running under the shared user of the removed
19817                        // package if revoking the permissions requested only by the removed
19818                        // package is successful and this causes a change in gids.
19819                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19820                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19821                                    userId);
19822                            if (userIdToKill == UserHandle.USER_ALL
19823                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19824                                // If gids changed for this user, kill all affected packages.
19825                                mHandler.post(new Runnable() {
19826                                    @Override
19827                                    public void run() {
19828                                        // This has to happen with no lock held.
19829                                        killApplication(deletedPs.name, deletedPs.appId,
19830                                                KILL_APP_REASON_GIDS_CHANGED);
19831                                    }
19832                                });
19833                                break;
19834                            }
19835                        }
19836                    }
19837                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19838                }
19839                // make sure to preserve per-user disabled state if this removal was just
19840                // a downgrade of a system app to the factory package
19841                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19842                    if (DEBUG_REMOVE) {
19843                        Slog.d(TAG, "Propagating install state across downgrade");
19844                    }
19845                    for (int userId : allUserHandles) {
19846                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19847                        if (DEBUG_REMOVE) {
19848                            Slog.d(TAG, "    user " + userId + " => " + installed);
19849                        }
19850                        if (installed != ps.getInstalled(userId)) {
19851                            installedStateChanged = true;
19852                        }
19853                        ps.setInstalled(installed, userId);
19854                    }
19855                }
19856            }
19857            // can downgrade to reader
19858            if (writeSettings) {
19859                // Save settings now
19860                mSettings.writeLPr();
19861            }
19862            if (installedStateChanged) {
19863                mSettings.writeKernelMappingLPr(ps);
19864            }
19865        }
19866        if (removedAppId != -1) {
19867            // A user ID was deleted here. Go through all users and remove it
19868            // from KeyStore.
19869            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19870        }
19871    }
19872
19873    static boolean locationIsPrivileged(File path) {
19874        try {
19875            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19876                    .getCanonicalPath();
19877            return path.getCanonicalPath().startsWith(privilegedAppDir);
19878        } catch (IOException e) {
19879            Slog.e(TAG, "Unable to access code path " + path);
19880        }
19881        return false;
19882    }
19883
19884    /*
19885     * Tries to delete system package.
19886     */
19887    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19888            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19889            boolean writeSettings) {
19890        if (deletedPs.parentPackageName != null) {
19891            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19892            return false;
19893        }
19894
19895        final boolean applyUserRestrictions
19896                = (allUserHandles != null) && (outInfo.origUsers != null);
19897        final PackageSetting disabledPs;
19898        // Confirm if the system package has been updated
19899        // An updated system app can be deleted. This will also have to restore
19900        // the system pkg from system partition
19901        // reader
19902        synchronized (mPackages) {
19903            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19904        }
19905
19906        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19907                + " disabledPs=" + disabledPs);
19908
19909        if (disabledPs == null) {
19910            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19911            return false;
19912        } else if (DEBUG_REMOVE) {
19913            Slog.d(TAG, "Deleting system pkg from data partition");
19914        }
19915
19916        if (DEBUG_REMOVE) {
19917            if (applyUserRestrictions) {
19918                Slog.d(TAG, "Remembering install states:");
19919                for (int userId : allUserHandles) {
19920                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19921                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19922                }
19923            }
19924        }
19925
19926        // Delete the updated package
19927        outInfo.isRemovedPackageSystemUpdate = true;
19928        if (outInfo.removedChildPackages != null) {
19929            final int childCount = (deletedPs.childPackageNames != null)
19930                    ? deletedPs.childPackageNames.size() : 0;
19931            for (int i = 0; i < childCount; i++) {
19932                String childPackageName = deletedPs.childPackageNames.get(i);
19933                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19934                        .contains(childPackageName)) {
19935                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19936                            childPackageName);
19937                    if (childInfo != null) {
19938                        childInfo.isRemovedPackageSystemUpdate = true;
19939                    }
19940                }
19941            }
19942        }
19943
19944        if (disabledPs.versionCode < deletedPs.versionCode) {
19945            // Delete data for downgrades
19946            flags &= ~PackageManager.DELETE_KEEP_DATA;
19947        } else {
19948            // Preserve data by setting flag
19949            flags |= PackageManager.DELETE_KEEP_DATA;
19950        }
19951
19952        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19953                outInfo, writeSettings, disabledPs.pkg);
19954        if (!ret) {
19955            return false;
19956        }
19957
19958        // writer
19959        synchronized (mPackages) {
19960            // NOTE: The system package always needs to be enabled; even if it's for
19961            // a compressed stub. If we don't, installing the system package fails
19962            // during scan [scanning checks the disabled packages]. We will reverse
19963            // this later, after we've "installed" the stub.
19964            // Reinstate the old system package
19965            enableSystemPackageLPw(disabledPs.pkg);
19966            // Remove any native libraries from the upgraded package.
19967            removeNativeBinariesLI(deletedPs);
19968        }
19969
19970        // Install the system package
19971        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19972        try {
19973            installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
19974                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
19975        } catch (PackageManagerException e) {
19976            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19977                    + e.getMessage());
19978            return false;
19979        } finally {
19980            if (disabledPs.pkg.isStub) {
19981                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
19982            }
19983        }
19984        return true;
19985    }
19986
19987    /**
19988     * Installs a package that's already on the system partition.
19989     */
19990    private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
19991            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
19992            @Nullable PermissionsState origPermissionState, boolean writeSettings)
19993                    throws PackageManagerException {
19994        int parseFlags = mDefParseFlags
19995                | PackageParser.PARSE_MUST_BE_APK
19996                | PackageParser.PARSE_IS_SYSTEM
19997                | PackageParser.PARSE_IS_SYSTEM_DIR;
19998        if (isPrivileged || locationIsPrivileged(codePath)) {
19999            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
20000        }
20001
20002        final PackageParser.Package newPkg =
20003                scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
20004
20005        try {
20006            // update shared libraries for the newly re-installed system package
20007            updateSharedLibrariesLPr(newPkg, null);
20008        } catch (PackageManagerException e) {
20009            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
20010        }
20011
20012        prepareAppDataAfterInstallLIF(newPkg);
20013
20014        // writer
20015        synchronized (mPackages) {
20016            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
20017
20018            // Propagate the permissions state as we do not want to drop on the floor
20019            // runtime permissions. The update permissions method below will take
20020            // care of removing obsolete permissions and grant install permissions.
20021            if (origPermissionState != null) {
20022                ps.getPermissionsState().copyFrom(origPermissionState);
20023            }
20024            updatePermissionsLPw(newPkg.packageName, newPkg,
20025                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
20026
20027            final boolean applyUserRestrictions
20028                    = (allUserHandles != null) && (origUserHandles != null);
20029            if (applyUserRestrictions) {
20030                boolean installedStateChanged = false;
20031                if (DEBUG_REMOVE) {
20032                    Slog.d(TAG, "Propagating install state across reinstall");
20033                }
20034                for (int userId : allUserHandles) {
20035                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
20036                    if (DEBUG_REMOVE) {
20037                        Slog.d(TAG, "    user " + userId + " => " + installed);
20038                    }
20039                    if (installed != ps.getInstalled(userId)) {
20040                        installedStateChanged = true;
20041                    }
20042                    ps.setInstalled(installed, userId);
20043
20044                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20045                }
20046                // Regardless of writeSettings we need to ensure that this restriction
20047                // state propagation is persisted
20048                mSettings.writeAllUsersPackageRestrictionsLPr();
20049                if (installedStateChanged) {
20050                    mSettings.writeKernelMappingLPr(ps);
20051                }
20052            }
20053            // can downgrade to reader here
20054            if (writeSettings) {
20055                mSettings.writeLPr();
20056            }
20057        }
20058        return newPkg;
20059    }
20060
20061    private boolean deleteInstalledPackageLIF(PackageSetting ps,
20062            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
20063            PackageRemovedInfo outInfo, boolean writeSettings,
20064            PackageParser.Package replacingPackage) {
20065        synchronized (mPackages) {
20066            if (outInfo != null) {
20067                outInfo.uid = ps.appId;
20068            }
20069
20070            if (outInfo != null && outInfo.removedChildPackages != null) {
20071                final int childCount = (ps.childPackageNames != null)
20072                        ? ps.childPackageNames.size() : 0;
20073                for (int i = 0; i < childCount; i++) {
20074                    String childPackageName = ps.childPackageNames.get(i);
20075                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
20076                    if (childPs == null) {
20077                        return false;
20078                    }
20079                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
20080                            childPackageName);
20081                    if (childInfo != null) {
20082                        childInfo.uid = childPs.appId;
20083                    }
20084                }
20085            }
20086        }
20087
20088        // Delete package data from internal structures and also remove data if flag is set
20089        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
20090
20091        // Delete the child packages data
20092        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
20093        for (int i = 0; i < childCount; i++) {
20094            PackageSetting childPs;
20095            synchronized (mPackages) {
20096                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
20097            }
20098            if (childPs != null) {
20099                PackageRemovedInfo childOutInfo = (outInfo != null
20100                        && outInfo.removedChildPackages != null)
20101                        ? outInfo.removedChildPackages.get(childPs.name) : null;
20102                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
20103                        && (replacingPackage != null
20104                        && !replacingPackage.hasChildPackage(childPs.name))
20105                        ? flags & ~DELETE_KEEP_DATA : flags;
20106                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
20107                        deleteFlags, writeSettings);
20108            }
20109        }
20110
20111        // Delete application code and resources only for parent packages
20112        if (ps.parentPackageName == null) {
20113            if (deleteCodeAndResources && (outInfo != null)) {
20114                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
20115                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
20116                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
20117            }
20118        }
20119
20120        return true;
20121    }
20122
20123    @Override
20124    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
20125            int userId) {
20126        mContext.enforceCallingOrSelfPermission(
20127                android.Manifest.permission.DELETE_PACKAGES, null);
20128        synchronized (mPackages) {
20129            // Cannot block uninstall of static shared libs as they are
20130            // considered a part of the using app (emulating static linking).
20131            // Also static libs are installed always on internal storage.
20132            PackageParser.Package pkg = mPackages.get(packageName);
20133            if (pkg != null && pkg.staticSharedLibName != null) {
20134                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
20135                        + " providing static shared library: " + pkg.staticSharedLibName);
20136                return false;
20137            }
20138            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
20139            mSettings.writePackageRestrictionsLPr(userId);
20140        }
20141        return true;
20142    }
20143
20144    @Override
20145    public boolean getBlockUninstallForUser(String packageName, int userId) {
20146        synchronized (mPackages) {
20147            final PackageSetting ps = mSettings.mPackages.get(packageName);
20148            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
20149                return false;
20150            }
20151            return mSettings.getBlockUninstallLPr(userId, packageName);
20152        }
20153    }
20154
20155    @Override
20156    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
20157        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
20158        synchronized (mPackages) {
20159            PackageSetting ps = mSettings.mPackages.get(packageName);
20160            if (ps == null) {
20161                Log.w(TAG, "Package doesn't exist: " + packageName);
20162                return false;
20163            }
20164            if (systemUserApp) {
20165                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20166            } else {
20167                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20168            }
20169            mSettings.writeLPr();
20170        }
20171        return true;
20172    }
20173
20174    /*
20175     * This method handles package deletion in general
20176     */
20177    private boolean deletePackageLIF(String packageName, UserHandle user,
20178            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
20179            PackageRemovedInfo outInfo, boolean writeSettings,
20180            PackageParser.Package replacingPackage) {
20181        if (packageName == null) {
20182            Slog.w(TAG, "Attempt to delete null packageName.");
20183            return false;
20184        }
20185
20186        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
20187
20188        PackageSetting ps;
20189        synchronized (mPackages) {
20190            ps = mSettings.mPackages.get(packageName);
20191            if (ps == null) {
20192                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20193                return false;
20194            }
20195
20196            if (ps.parentPackageName != null && (!isSystemApp(ps)
20197                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
20198                if (DEBUG_REMOVE) {
20199                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
20200                            + ((user == null) ? UserHandle.USER_ALL : user));
20201                }
20202                final int removedUserId = (user != null) ? user.getIdentifier()
20203                        : UserHandle.USER_ALL;
20204                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
20205                    return false;
20206                }
20207                markPackageUninstalledForUserLPw(ps, user);
20208                scheduleWritePackageRestrictionsLocked(user);
20209                return true;
20210            }
20211        }
20212
20213        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
20214                && user.getIdentifier() != UserHandle.USER_ALL)) {
20215            // The caller is asking that the package only be deleted for a single
20216            // user.  To do this, we just mark its uninstalled state and delete
20217            // its data. If this is a system app, we only allow this to happen if
20218            // they have set the special DELETE_SYSTEM_APP which requests different
20219            // semantics than normal for uninstalling system apps.
20220            markPackageUninstalledForUserLPw(ps, user);
20221
20222            if (!isSystemApp(ps)) {
20223                // Do not uninstall the APK if an app should be cached
20224                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
20225                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
20226                    // Other user still have this package installed, so all
20227                    // we need to do is clear this user's data and save that
20228                    // it is uninstalled.
20229                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
20230                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20231                        return false;
20232                    }
20233                    scheduleWritePackageRestrictionsLocked(user);
20234                    return true;
20235                } else {
20236                    // We need to set it back to 'installed' so the uninstall
20237                    // broadcasts will be sent correctly.
20238                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
20239                    ps.setInstalled(true, user.getIdentifier());
20240                    mSettings.writeKernelMappingLPr(ps);
20241                }
20242            } else {
20243                // This is a system app, so we assume that the
20244                // other users still have this package installed, so all
20245                // we need to do is clear this user's data and save that
20246                // it is uninstalled.
20247                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
20248                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20249                    return false;
20250                }
20251                scheduleWritePackageRestrictionsLocked(user);
20252                return true;
20253            }
20254        }
20255
20256        // If we are deleting a composite package for all users, keep track
20257        // of result for each child.
20258        if (ps.childPackageNames != null && outInfo != null) {
20259            synchronized (mPackages) {
20260                final int childCount = ps.childPackageNames.size();
20261                outInfo.removedChildPackages = new ArrayMap<>(childCount);
20262                for (int i = 0; i < childCount; i++) {
20263                    String childPackageName = ps.childPackageNames.get(i);
20264                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
20265                    childInfo.removedPackage = childPackageName;
20266                    childInfo.installerPackageName = ps.installerPackageName;
20267                    outInfo.removedChildPackages.put(childPackageName, childInfo);
20268                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20269                    if (childPs != null) {
20270                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
20271                    }
20272                }
20273            }
20274        }
20275
20276        boolean ret = false;
20277        if (isSystemApp(ps)) {
20278            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
20279            // When an updated system application is deleted we delete the existing resources
20280            // as well and fall back to existing code in system partition
20281            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
20282        } else {
20283            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
20284            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
20285                    outInfo, writeSettings, replacingPackage);
20286        }
20287
20288        // Take a note whether we deleted the package for all users
20289        if (outInfo != null) {
20290            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
20291            if (outInfo.removedChildPackages != null) {
20292                synchronized (mPackages) {
20293                    final int childCount = outInfo.removedChildPackages.size();
20294                    for (int i = 0; i < childCount; i++) {
20295                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
20296                        if (childInfo != null) {
20297                            childInfo.removedForAllUsers = mPackages.get(
20298                                    childInfo.removedPackage) == null;
20299                        }
20300                    }
20301                }
20302            }
20303            // If we uninstalled an update to a system app there may be some
20304            // child packages that appeared as they are declared in the system
20305            // app but were not declared in the update.
20306            if (isSystemApp(ps)) {
20307                synchronized (mPackages) {
20308                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
20309                    final int childCount = (updatedPs.childPackageNames != null)
20310                            ? updatedPs.childPackageNames.size() : 0;
20311                    for (int i = 0; i < childCount; i++) {
20312                        String childPackageName = updatedPs.childPackageNames.get(i);
20313                        if (outInfo.removedChildPackages == null
20314                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
20315                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20316                            if (childPs == null) {
20317                                continue;
20318                            }
20319                            PackageInstalledInfo installRes = new PackageInstalledInfo();
20320                            installRes.name = childPackageName;
20321                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
20322                            installRes.pkg = mPackages.get(childPackageName);
20323                            installRes.uid = childPs.pkg.applicationInfo.uid;
20324                            if (outInfo.appearedChildPackages == null) {
20325                                outInfo.appearedChildPackages = new ArrayMap<>();
20326                            }
20327                            outInfo.appearedChildPackages.put(childPackageName, installRes);
20328                        }
20329                    }
20330                }
20331            }
20332        }
20333
20334        return ret;
20335    }
20336
20337    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
20338        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
20339                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
20340        for (int nextUserId : userIds) {
20341            if (DEBUG_REMOVE) {
20342                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
20343            }
20344            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
20345                    false /*installed*/,
20346                    true /*stopped*/,
20347                    true /*notLaunched*/,
20348                    false /*hidden*/,
20349                    false /*suspended*/,
20350                    false /*instantApp*/,
20351                    false /*virtualPreload*/,
20352                    null /*lastDisableAppCaller*/,
20353                    null /*enabledComponents*/,
20354                    null /*disabledComponents*/,
20355                    ps.readUserState(nextUserId).domainVerificationStatus,
20356                    0, PackageManager.INSTALL_REASON_UNKNOWN);
20357        }
20358        mSettings.writeKernelMappingLPr(ps);
20359    }
20360
20361    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
20362            PackageRemovedInfo outInfo) {
20363        final PackageParser.Package pkg;
20364        synchronized (mPackages) {
20365            pkg = mPackages.get(ps.name);
20366        }
20367
20368        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
20369                : new int[] {userId};
20370        for (int nextUserId : userIds) {
20371            if (DEBUG_REMOVE) {
20372                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
20373                        + nextUserId);
20374            }
20375
20376            destroyAppDataLIF(pkg, userId,
20377                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20378            destroyAppProfilesLIF(pkg, userId);
20379            clearDefaultBrowserIfNeededForUser(ps.name, userId);
20380            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
20381            schedulePackageCleaning(ps.name, nextUserId, false);
20382            synchronized (mPackages) {
20383                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
20384                    scheduleWritePackageRestrictionsLocked(nextUserId);
20385                }
20386                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
20387            }
20388        }
20389
20390        if (outInfo != null) {
20391            outInfo.removedPackage = ps.name;
20392            outInfo.installerPackageName = ps.installerPackageName;
20393            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
20394            outInfo.removedAppId = ps.appId;
20395            outInfo.removedUsers = userIds;
20396            outInfo.broadcastUsers = userIds;
20397        }
20398
20399        return true;
20400    }
20401
20402    private final class ClearStorageConnection implements ServiceConnection {
20403        IMediaContainerService mContainerService;
20404
20405        @Override
20406        public void onServiceConnected(ComponentName name, IBinder service) {
20407            synchronized (this) {
20408                mContainerService = IMediaContainerService.Stub
20409                        .asInterface(Binder.allowBlocking(service));
20410                notifyAll();
20411            }
20412        }
20413
20414        @Override
20415        public void onServiceDisconnected(ComponentName name) {
20416        }
20417    }
20418
20419    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20420        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20421
20422        final boolean mounted;
20423        if (Environment.isExternalStorageEmulated()) {
20424            mounted = true;
20425        } else {
20426            final String status = Environment.getExternalStorageState();
20427
20428            mounted = status.equals(Environment.MEDIA_MOUNTED)
20429                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20430        }
20431
20432        if (!mounted) {
20433            return;
20434        }
20435
20436        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20437        int[] users;
20438        if (userId == UserHandle.USER_ALL) {
20439            users = sUserManager.getUserIds();
20440        } else {
20441            users = new int[] { userId };
20442        }
20443        final ClearStorageConnection conn = new ClearStorageConnection();
20444        if (mContext.bindServiceAsUser(
20445                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20446            try {
20447                for (int curUser : users) {
20448                    long timeout = SystemClock.uptimeMillis() + 5000;
20449                    synchronized (conn) {
20450                        long now;
20451                        while (conn.mContainerService == null &&
20452                                (now = SystemClock.uptimeMillis()) < timeout) {
20453                            try {
20454                                conn.wait(timeout - now);
20455                            } catch (InterruptedException e) {
20456                            }
20457                        }
20458                    }
20459                    if (conn.mContainerService == null) {
20460                        return;
20461                    }
20462
20463                    final UserEnvironment userEnv = new UserEnvironment(curUser);
20464                    clearDirectory(conn.mContainerService,
20465                            userEnv.buildExternalStorageAppCacheDirs(packageName));
20466                    if (allData) {
20467                        clearDirectory(conn.mContainerService,
20468                                userEnv.buildExternalStorageAppDataDirs(packageName));
20469                        clearDirectory(conn.mContainerService,
20470                                userEnv.buildExternalStorageAppMediaDirs(packageName));
20471                    }
20472                }
20473            } finally {
20474                mContext.unbindService(conn);
20475            }
20476        }
20477    }
20478
20479    @Override
20480    public void clearApplicationProfileData(String packageName) {
20481        enforceSystemOrRoot("Only the system can clear all profile data");
20482
20483        final PackageParser.Package pkg;
20484        synchronized (mPackages) {
20485            pkg = mPackages.get(packageName);
20486        }
20487
20488        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20489            synchronized (mInstallLock) {
20490                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20491            }
20492        }
20493    }
20494
20495    @Override
20496    public void clearApplicationUserData(final String packageName,
20497            final IPackageDataObserver observer, final int userId) {
20498        mContext.enforceCallingOrSelfPermission(
20499                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20500
20501        final int callingUid = Binder.getCallingUid();
20502        enforceCrossUserPermission(callingUid, userId,
20503                true /* requireFullPermission */, false /* checkShell */, "clear application data");
20504
20505        final PackageSetting ps = mSettings.getPackageLPr(packageName);
20506        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
20507        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20508            throw new SecurityException("Cannot clear data for a protected package: "
20509                    + packageName);
20510        }
20511        // Queue up an async operation since the package deletion may take a little while.
20512        mHandler.post(new Runnable() {
20513            public void run() {
20514                mHandler.removeCallbacks(this);
20515                final boolean succeeded;
20516                if (!filterApp) {
20517                    try (PackageFreezer freezer = freezePackage(packageName,
20518                            "clearApplicationUserData")) {
20519                        synchronized (mInstallLock) {
20520                            succeeded = clearApplicationUserDataLIF(packageName, userId);
20521                        }
20522                        clearExternalStorageDataSync(packageName, userId, true);
20523                        synchronized (mPackages) {
20524                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20525                                    packageName, userId);
20526                        }
20527                    }
20528                    if (succeeded) {
20529                        // invoke DeviceStorageMonitor's update method to clear any notifications
20530                        DeviceStorageMonitorInternal dsm = LocalServices
20531                                .getService(DeviceStorageMonitorInternal.class);
20532                        if (dsm != null) {
20533                            dsm.checkMemory();
20534                        }
20535                    }
20536                } else {
20537                    succeeded = false;
20538                }
20539                if (observer != null) {
20540                    try {
20541                        observer.onRemoveCompleted(packageName, succeeded);
20542                    } catch (RemoteException e) {
20543                        Log.i(TAG, "Observer no longer exists.");
20544                    }
20545                } //end if observer
20546            } //end run
20547        });
20548    }
20549
20550    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20551        if (packageName == null) {
20552            Slog.w(TAG, "Attempt to delete null packageName.");
20553            return false;
20554        }
20555
20556        // Try finding details about the requested package
20557        PackageParser.Package pkg;
20558        synchronized (mPackages) {
20559            pkg = mPackages.get(packageName);
20560            if (pkg == null) {
20561                final PackageSetting ps = mSettings.mPackages.get(packageName);
20562                if (ps != null) {
20563                    pkg = ps.pkg;
20564                }
20565            }
20566
20567            if (pkg == null) {
20568                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20569                return false;
20570            }
20571
20572            PackageSetting ps = (PackageSetting) pkg.mExtras;
20573            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20574        }
20575
20576        clearAppDataLIF(pkg, userId,
20577                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20578
20579        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20580        removeKeystoreDataIfNeeded(userId, appId);
20581
20582        UserManagerInternal umInternal = getUserManagerInternal();
20583        final int flags;
20584        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20585            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20586        } else if (umInternal.isUserRunning(userId)) {
20587            flags = StorageManager.FLAG_STORAGE_DE;
20588        } else {
20589            flags = 0;
20590        }
20591        prepareAppDataContentsLIF(pkg, userId, flags);
20592
20593        return true;
20594    }
20595
20596    /**
20597     * Reverts user permission state changes (permissions and flags) in
20598     * all packages for a given user.
20599     *
20600     * @param userId The device user for which to do a reset.
20601     */
20602    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20603        final int packageCount = mPackages.size();
20604        for (int i = 0; i < packageCount; i++) {
20605            PackageParser.Package pkg = mPackages.valueAt(i);
20606            PackageSetting ps = (PackageSetting) pkg.mExtras;
20607            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20608        }
20609    }
20610
20611    private void resetNetworkPolicies(int userId) {
20612        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20613    }
20614
20615    /**
20616     * Reverts user permission state changes (permissions and flags).
20617     *
20618     * @param ps The package for which to reset.
20619     * @param userId The device user for which to do a reset.
20620     */
20621    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20622            final PackageSetting ps, final int userId) {
20623        if (ps.pkg == null) {
20624            return;
20625        }
20626
20627        // These are flags that can change base on user actions.
20628        final int userSettableMask = FLAG_PERMISSION_USER_SET
20629                | FLAG_PERMISSION_USER_FIXED
20630                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20631                | FLAG_PERMISSION_REVIEW_REQUIRED;
20632
20633        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20634                | FLAG_PERMISSION_POLICY_FIXED;
20635
20636        boolean writeInstallPermissions = false;
20637        boolean writeRuntimePermissions = false;
20638
20639        final int permissionCount = ps.pkg.requestedPermissions.size();
20640        for (int i = 0; i < permissionCount; i++) {
20641            String permission = ps.pkg.requestedPermissions.get(i);
20642
20643            BasePermission bp = mSettings.mPermissions.get(permission);
20644            if (bp == null) {
20645                continue;
20646            }
20647
20648            // If shared user we just reset the state to which only this app contributed.
20649            if (ps.sharedUser != null) {
20650                boolean used = false;
20651                final int packageCount = ps.sharedUser.packages.size();
20652                for (int j = 0; j < packageCount; j++) {
20653                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20654                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20655                            && pkg.pkg.requestedPermissions.contains(permission)) {
20656                        used = true;
20657                        break;
20658                    }
20659                }
20660                if (used) {
20661                    continue;
20662                }
20663            }
20664
20665            PermissionsState permissionsState = ps.getPermissionsState();
20666
20667            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20668
20669            // Always clear the user settable flags.
20670            final boolean hasInstallState = permissionsState.getInstallPermissionState(
20671                    bp.name) != null;
20672            // If permission review is enabled and this is a legacy app, mark the
20673            // permission as requiring a review as this is the initial state.
20674            int flags = 0;
20675            if (mPermissionReviewRequired
20676                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20677                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20678            }
20679            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20680                if (hasInstallState) {
20681                    writeInstallPermissions = true;
20682                } else {
20683                    writeRuntimePermissions = true;
20684                }
20685            }
20686
20687            // Below is only runtime permission handling.
20688            if (!bp.isRuntime()) {
20689                continue;
20690            }
20691
20692            // Never clobber system or policy.
20693            if ((oldFlags & policyOrSystemFlags) != 0) {
20694                continue;
20695            }
20696
20697            // If this permission was granted by default, make sure it is.
20698            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20699                if (permissionsState.grantRuntimePermission(bp, userId)
20700                        != PERMISSION_OPERATION_FAILURE) {
20701                    writeRuntimePermissions = true;
20702                }
20703            // If permission review is enabled the permissions for a legacy apps
20704            // are represented as constantly granted runtime ones, so don't revoke.
20705            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20706                // Otherwise, reset the permission.
20707                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20708                switch (revokeResult) {
20709                    case PERMISSION_OPERATION_SUCCESS:
20710                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20711                        writeRuntimePermissions = true;
20712                        final int appId = ps.appId;
20713                        mHandler.post(new Runnable() {
20714                            @Override
20715                            public void run() {
20716                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20717                            }
20718                        });
20719                    } break;
20720                }
20721            }
20722        }
20723
20724        // Synchronously write as we are taking permissions away.
20725        if (writeRuntimePermissions) {
20726            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20727        }
20728
20729        // Synchronously write as we are taking permissions away.
20730        if (writeInstallPermissions) {
20731            mSettings.writeLPr();
20732        }
20733    }
20734
20735    /**
20736     * Remove entries from the keystore daemon. Will only remove it if the
20737     * {@code appId} is valid.
20738     */
20739    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20740        if (appId < 0) {
20741            return;
20742        }
20743
20744        final KeyStore keyStore = KeyStore.getInstance();
20745        if (keyStore != null) {
20746            if (userId == UserHandle.USER_ALL) {
20747                for (final int individual : sUserManager.getUserIds()) {
20748                    keyStore.clearUid(UserHandle.getUid(individual, appId));
20749                }
20750            } else {
20751                keyStore.clearUid(UserHandle.getUid(userId, appId));
20752            }
20753        } else {
20754            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20755        }
20756    }
20757
20758    @Override
20759    public void deleteApplicationCacheFiles(final String packageName,
20760            final IPackageDataObserver observer) {
20761        final int userId = UserHandle.getCallingUserId();
20762        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20763    }
20764
20765    @Override
20766    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20767            final IPackageDataObserver observer) {
20768        final int callingUid = Binder.getCallingUid();
20769        mContext.enforceCallingOrSelfPermission(
20770                android.Manifest.permission.DELETE_CACHE_FILES, null);
20771        enforceCrossUserPermission(callingUid, userId,
20772                /* requireFullPermission= */ true, /* checkShell= */ false,
20773                "delete application cache files");
20774        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20775                android.Manifest.permission.ACCESS_INSTANT_APPS);
20776
20777        final PackageParser.Package pkg;
20778        synchronized (mPackages) {
20779            pkg = mPackages.get(packageName);
20780        }
20781
20782        // Queue up an async operation since the package deletion may take a little while.
20783        mHandler.post(new Runnable() {
20784            public void run() {
20785                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20786                boolean doClearData = true;
20787                if (ps != null) {
20788                    final boolean targetIsInstantApp =
20789                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20790                    doClearData = !targetIsInstantApp
20791                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20792                }
20793                if (doClearData) {
20794                    synchronized (mInstallLock) {
20795                        final int flags = StorageManager.FLAG_STORAGE_DE
20796                                | StorageManager.FLAG_STORAGE_CE;
20797                        // We're only clearing cache files, so we don't care if the
20798                        // app is unfrozen and still able to run
20799                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20800                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20801                    }
20802                    clearExternalStorageDataSync(packageName, userId, false);
20803                }
20804                if (observer != null) {
20805                    try {
20806                        observer.onRemoveCompleted(packageName, true);
20807                    } catch (RemoteException e) {
20808                        Log.i(TAG, "Observer no longer exists.");
20809                    }
20810                }
20811            }
20812        });
20813    }
20814
20815    @Override
20816    public void getPackageSizeInfo(final String packageName, int userHandle,
20817            final IPackageStatsObserver observer) {
20818        throw new UnsupportedOperationException(
20819                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20820    }
20821
20822    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20823        final PackageSetting ps;
20824        synchronized (mPackages) {
20825            ps = mSettings.mPackages.get(packageName);
20826            if (ps == null) {
20827                Slog.w(TAG, "Failed to find settings for " + packageName);
20828                return false;
20829            }
20830        }
20831
20832        final String[] packageNames = { packageName };
20833        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20834        final String[] codePaths = { ps.codePathString };
20835
20836        try {
20837            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20838                    ps.appId, ceDataInodes, codePaths, stats);
20839
20840            // For now, ignore code size of packages on system partition
20841            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20842                stats.codeSize = 0;
20843            }
20844
20845            // External clients expect these to be tracked separately
20846            stats.dataSize -= stats.cacheSize;
20847
20848        } catch (InstallerException e) {
20849            Slog.w(TAG, String.valueOf(e));
20850            return false;
20851        }
20852
20853        return true;
20854    }
20855
20856    private int getUidTargetSdkVersionLockedLPr(int uid) {
20857        Object obj = mSettings.getUserIdLPr(uid);
20858        if (obj instanceof SharedUserSetting) {
20859            final SharedUserSetting sus = (SharedUserSetting) obj;
20860            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20861            final Iterator<PackageSetting> it = sus.packages.iterator();
20862            while (it.hasNext()) {
20863                final PackageSetting ps = it.next();
20864                if (ps.pkg != null) {
20865                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20866                    if (v < vers) vers = v;
20867                }
20868            }
20869            return vers;
20870        } else if (obj instanceof PackageSetting) {
20871            final PackageSetting ps = (PackageSetting) obj;
20872            if (ps.pkg != null) {
20873                return ps.pkg.applicationInfo.targetSdkVersion;
20874            }
20875        }
20876        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20877    }
20878
20879    @Override
20880    public void addPreferredActivity(IntentFilter filter, int match,
20881            ComponentName[] set, ComponentName activity, int userId) {
20882        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20883                "Adding preferred");
20884    }
20885
20886    private void addPreferredActivityInternal(IntentFilter filter, int match,
20887            ComponentName[] set, ComponentName activity, boolean always, int userId,
20888            String opname) {
20889        // writer
20890        int callingUid = Binder.getCallingUid();
20891        enforceCrossUserPermission(callingUid, userId,
20892                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20893        if (filter.countActions() == 0) {
20894            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20895            return;
20896        }
20897        synchronized (mPackages) {
20898            if (mContext.checkCallingOrSelfPermission(
20899                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20900                    != PackageManager.PERMISSION_GRANTED) {
20901                if (getUidTargetSdkVersionLockedLPr(callingUid)
20902                        < Build.VERSION_CODES.FROYO) {
20903                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20904                            + callingUid);
20905                    return;
20906                }
20907                mContext.enforceCallingOrSelfPermission(
20908                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20909            }
20910
20911            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20912            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20913                    + userId + ":");
20914            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20915            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20916            scheduleWritePackageRestrictionsLocked(userId);
20917            postPreferredActivityChangedBroadcast(userId);
20918        }
20919    }
20920
20921    private void postPreferredActivityChangedBroadcast(int userId) {
20922        mHandler.post(() -> {
20923            final IActivityManager am = ActivityManager.getService();
20924            if (am == null) {
20925                return;
20926            }
20927
20928            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20929            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20930            try {
20931                am.broadcastIntent(null, intent, null, null,
20932                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20933                        null, false, false, userId);
20934            } catch (RemoteException e) {
20935            }
20936        });
20937    }
20938
20939    @Override
20940    public void replacePreferredActivity(IntentFilter filter, int match,
20941            ComponentName[] set, ComponentName activity, int userId) {
20942        if (filter.countActions() != 1) {
20943            throw new IllegalArgumentException(
20944                    "replacePreferredActivity expects filter to have only 1 action.");
20945        }
20946        if (filter.countDataAuthorities() != 0
20947                || filter.countDataPaths() != 0
20948                || filter.countDataSchemes() > 1
20949                || filter.countDataTypes() != 0) {
20950            throw new IllegalArgumentException(
20951                    "replacePreferredActivity expects filter to have no data authorities, " +
20952                    "paths, or types; and at most one scheme.");
20953        }
20954
20955        final int callingUid = Binder.getCallingUid();
20956        enforceCrossUserPermission(callingUid, userId,
20957                true /* requireFullPermission */, false /* checkShell */,
20958                "replace preferred activity");
20959        synchronized (mPackages) {
20960            if (mContext.checkCallingOrSelfPermission(
20961                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20962                    != PackageManager.PERMISSION_GRANTED) {
20963                if (getUidTargetSdkVersionLockedLPr(callingUid)
20964                        < Build.VERSION_CODES.FROYO) {
20965                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20966                            + Binder.getCallingUid());
20967                    return;
20968                }
20969                mContext.enforceCallingOrSelfPermission(
20970                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20971            }
20972
20973            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20974            if (pir != null) {
20975                // Get all of the existing entries that exactly match this filter.
20976                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20977                if (existing != null && existing.size() == 1) {
20978                    PreferredActivity cur = existing.get(0);
20979                    if (DEBUG_PREFERRED) {
20980                        Slog.i(TAG, "Checking replace of preferred:");
20981                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20982                        if (!cur.mPref.mAlways) {
20983                            Slog.i(TAG, "  -- CUR; not mAlways!");
20984                        } else {
20985                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20986                            Slog.i(TAG, "  -- CUR: mSet="
20987                                    + Arrays.toString(cur.mPref.mSetComponents));
20988                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20989                            Slog.i(TAG, "  -- NEW: mMatch="
20990                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20991                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20992                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20993                        }
20994                    }
20995                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20996                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20997                            && cur.mPref.sameSet(set)) {
20998                        // Setting the preferred activity to what it happens to be already
20999                        if (DEBUG_PREFERRED) {
21000                            Slog.i(TAG, "Replacing with same preferred activity "
21001                                    + cur.mPref.mShortComponent + " for user "
21002                                    + userId + ":");
21003                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21004                        }
21005                        return;
21006                    }
21007                }
21008
21009                if (existing != null) {
21010                    if (DEBUG_PREFERRED) {
21011                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
21012                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21013                    }
21014                    for (int i = 0; i < existing.size(); i++) {
21015                        PreferredActivity pa = existing.get(i);
21016                        if (DEBUG_PREFERRED) {
21017                            Slog.i(TAG, "Removing existing preferred activity "
21018                                    + pa.mPref.mComponent + ":");
21019                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
21020                        }
21021                        pir.removeFilter(pa);
21022                    }
21023                }
21024            }
21025            addPreferredActivityInternal(filter, match, set, activity, true, userId,
21026                    "Replacing preferred");
21027        }
21028    }
21029
21030    @Override
21031    public void clearPackagePreferredActivities(String packageName) {
21032        final int callingUid = Binder.getCallingUid();
21033        if (getInstantAppPackageName(callingUid) != null) {
21034            return;
21035        }
21036        // writer
21037        synchronized (mPackages) {
21038            PackageParser.Package pkg = mPackages.get(packageName);
21039            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
21040                if (mContext.checkCallingOrSelfPermission(
21041                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
21042                        != PackageManager.PERMISSION_GRANTED) {
21043                    if (getUidTargetSdkVersionLockedLPr(callingUid)
21044                            < Build.VERSION_CODES.FROYO) {
21045                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
21046                                + callingUid);
21047                        return;
21048                    }
21049                    mContext.enforceCallingOrSelfPermission(
21050                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21051                }
21052            }
21053            final PackageSetting ps = mSettings.getPackageLPr(packageName);
21054            if (ps != null
21055                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21056                return;
21057            }
21058            int user = UserHandle.getCallingUserId();
21059            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
21060                scheduleWritePackageRestrictionsLocked(user);
21061            }
21062        }
21063    }
21064
21065    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21066    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
21067        ArrayList<PreferredActivity> removed = null;
21068        boolean changed = false;
21069        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21070            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
21071            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21072            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
21073                continue;
21074            }
21075            Iterator<PreferredActivity> it = pir.filterIterator();
21076            while (it.hasNext()) {
21077                PreferredActivity pa = it.next();
21078                // Mark entry for removal only if it matches the package name
21079                // and the entry is of type "always".
21080                if (packageName == null ||
21081                        (pa.mPref.mComponent.getPackageName().equals(packageName)
21082                                && pa.mPref.mAlways)) {
21083                    if (removed == null) {
21084                        removed = new ArrayList<PreferredActivity>();
21085                    }
21086                    removed.add(pa);
21087                }
21088            }
21089            if (removed != null) {
21090                for (int j=0; j<removed.size(); j++) {
21091                    PreferredActivity pa = removed.get(j);
21092                    pir.removeFilter(pa);
21093                }
21094                changed = true;
21095            }
21096        }
21097        if (changed) {
21098            postPreferredActivityChangedBroadcast(userId);
21099        }
21100        return changed;
21101    }
21102
21103    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21104    private void clearIntentFilterVerificationsLPw(int userId) {
21105        final int packageCount = mPackages.size();
21106        for (int i = 0; i < packageCount; i++) {
21107            PackageParser.Package pkg = mPackages.valueAt(i);
21108            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
21109        }
21110    }
21111
21112    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
21113    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
21114        if (userId == UserHandle.USER_ALL) {
21115            if (mSettings.removeIntentFilterVerificationLPw(packageName,
21116                    sUserManager.getUserIds())) {
21117                for (int oneUserId : sUserManager.getUserIds()) {
21118                    scheduleWritePackageRestrictionsLocked(oneUserId);
21119                }
21120            }
21121        } else {
21122            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
21123                scheduleWritePackageRestrictionsLocked(userId);
21124            }
21125        }
21126    }
21127
21128    /** Clears state for all users, and touches intent filter verification policy */
21129    void clearDefaultBrowserIfNeeded(String packageName) {
21130        for (int oneUserId : sUserManager.getUserIds()) {
21131            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
21132        }
21133    }
21134
21135    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
21136        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
21137        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
21138            if (packageName.equals(defaultBrowserPackageName)) {
21139                setDefaultBrowserPackageName(null, userId);
21140            }
21141        }
21142    }
21143
21144    @Override
21145    public void resetApplicationPreferences(int userId) {
21146        mContext.enforceCallingOrSelfPermission(
21147                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
21148        final long identity = Binder.clearCallingIdentity();
21149        // writer
21150        try {
21151            synchronized (mPackages) {
21152                clearPackagePreferredActivitiesLPw(null, userId);
21153                mSettings.applyDefaultPreferredAppsLPw(this, userId);
21154                // TODO: We have to reset the default SMS and Phone. This requires
21155                // significant refactoring to keep all default apps in the package
21156                // manager (cleaner but more work) or have the services provide
21157                // callbacks to the package manager to request a default app reset.
21158                applyFactoryDefaultBrowserLPw(userId);
21159                clearIntentFilterVerificationsLPw(userId);
21160                primeDomainVerificationsLPw(userId);
21161                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
21162                scheduleWritePackageRestrictionsLocked(userId);
21163            }
21164            resetNetworkPolicies(userId);
21165        } finally {
21166            Binder.restoreCallingIdentity(identity);
21167        }
21168    }
21169
21170    @Override
21171    public int getPreferredActivities(List<IntentFilter> outFilters,
21172            List<ComponentName> outActivities, String packageName) {
21173        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21174            return 0;
21175        }
21176        int num = 0;
21177        final int userId = UserHandle.getCallingUserId();
21178        // reader
21179        synchronized (mPackages) {
21180            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
21181            if (pir != null) {
21182                final Iterator<PreferredActivity> it = pir.filterIterator();
21183                while (it.hasNext()) {
21184                    final PreferredActivity pa = it.next();
21185                    if (packageName == null
21186                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
21187                                    && pa.mPref.mAlways)) {
21188                        if (outFilters != null) {
21189                            outFilters.add(new IntentFilter(pa));
21190                        }
21191                        if (outActivities != null) {
21192                            outActivities.add(pa.mPref.mComponent);
21193                        }
21194                    }
21195                }
21196            }
21197        }
21198
21199        return num;
21200    }
21201
21202    @Override
21203    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
21204            int userId) {
21205        int callingUid = Binder.getCallingUid();
21206        if (callingUid != Process.SYSTEM_UID) {
21207            throw new SecurityException(
21208                    "addPersistentPreferredActivity can only be run by the system");
21209        }
21210        if (filter.countActions() == 0) {
21211            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
21212            return;
21213        }
21214        synchronized (mPackages) {
21215            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
21216                    ":");
21217            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21218            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
21219                    new PersistentPreferredActivity(filter, activity));
21220            scheduleWritePackageRestrictionsLocked(userId);
21221            postPreferredActivityChangedBroadcast(userId);
21222        }
21223    }
21224
21225    @Override
21226    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
21227        int callingUid = Binder.getCallingUid();
21228        if (callingUid != Process.SYSTEM_UID) {
21229            throw new SecurityException(
21230                    "clearPackagePersistentPreferredActivities can only be run by the system");
21231        }
21232        ArrayList<PersistentPreferredActivity> removed = null;
21233        boolean changed = false;
21234        synchronized (mPackages) {
21235            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
21236                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
21237                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
21238                        .valueAt(i);
21239                if (userId != thisUserId) {
21240                    continue;
21241                }
21242                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
21243                while (it.hasNext()) {
21244                    PersistentPreferredActivity ppa = it.next();
21245                    // Mark entry for removal only if it matches the package name.
21246                    if (ppa.mComponent.getPackageName().equals(packageName)) {
21247                        if (removed == null) {
21248                            removed = new ArrayList<PersistentPreferredActivity>();
21249                        }
21250                        removed.add(ppa);
21251                    }
21252                }
21253                if (removed != null) {
21254                    for (int j=0; j<removed.size(); j++) {
21255                        PersistentPreferredActivity ppa = removed.get(j);
21256                        ppir.removeFilter(ppa);
21257                    }
21258                    changed = true;
21259                }
21260            }
21261
21262            if (changed) {
21263                scheduleWritePackageRestrictionsLocked(userId);
21264                postPreferredActivityChangedBroadcast(userId);
21265            }
21266        }
21267    }
21268
21269    /**
21270     * Common machinery for picking apart a restored XML blob and passing
21271     * it to a caller-supplied functor to be applied to the running system.
21272     */
21273    private void restoreFromXml(XmlPullParser parser, int userId,
21274            String expectedStartTag, BlobXmlRestorer functor)
21275            throws IOException, XmlPullParserException {
21276        int type;
21277        while ((type = parser.next()) != XmlPullParser.START_TAG
21278                && type != XmlPullParser.END_DOCUMENT) {
21279        }
21280        if (type != XmlPullParser.START_TAG) {
21281            // oops didn't find a start tag?!
21282            if (DEBUG_BACKUP) {
21283                Slog.e(TAG, "Didn't find start tag during restore");
21284            }
21285            return;
21286        }
21287Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
21288        // this is supposed to be TAG_PREFERRED_BACKUP
21289        if (!expectedStartTag.equals(parser.getName())) {
21290            if (DEBUG_BACKUP) {
21291                Slog.e(TAG, "Found unexpected tag " + parser.getName());
21292            }
21293            return;
21294        }
21295
21296        // skip interfering stuff, then we're aligned with the backing implementation
21297        while ((type = parser.next()) == XmlPullParser.TEXT) { }
21298Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
21299        functor.apply(parser, userId);
21300    }
21301
21302    private interface BlobXmlRestorer {
21303        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
21304    }
21305
21306    /**
21307     * Non-Binder method, support for the backup/restore mechanism: write the
21308     * full set of preferred activities in its canonical XML format.  Returns the
21309     * XML output as a byte array, or null if there is none.
21310     */
21311    @Override
21312    public byte[] getPreferredActivityBackup(int userId) {
21313        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21314            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
21315        }
21316
21317        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21318        try {
21319            final XmlSerializer serializer = new FastXmlSerializer();
21320            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21321            serializer.startDocument(null, true);
21322            serializer.startTag(null, TAG_PREFERRED_BACKUP);
21323
21324            synchronized (mPackages) {
21325                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
21326            }
21327
21328            serializer.endTag(null, TAG_PREFERRED_BACKUP);
21329            serializer.endDocument();
21330            serializer.flush();
21331        } catch (Exception e) {
21332            if (DEBUG_BACKUP) {
21333                Slog.e(TAG, "Unable to write preferred activities for backup", e);
21334            }
21335            return null;
21336        }
21337
21338        return dataStream.toByteArray();
21339    }
21340
21341    @Override
21342    public void restorePreferredActivities(byte[] backup, int userId) {
21343        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21344            throw new SecurityException("Only the system may call restorePreferredActivities()");
21345        }
21346
21347        try {
21348            final XmlPullParser parser = Xml.newPullParser();
21349            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21350            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
21351                    new BlobXmlRestorer() {
21352                        @Override
21353                        public void apply(XmlPullParser parser, int userId)
21354                                throws XmlPullParserException, IOException {
21355                            synchronized (mPackages) {
21356                                mSettings.readPreferredActivitiesLPw(parser, userId);
21357                            }
21358                        }
21359                    } );
21360        } catch (Exception e) {
21361            if (DEBUG_BACKUP) {
21362                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21363            }
21364        }
21365    }
21366
21367    /**
21368     * Non-Binder method, support for the backup/restore mechanism: write the
21369     * default browser (etc) settings in its canonical XML format.  Returns the default
21370     * browser XML representation as a byte array, or null if there is none.
21371     */
21372    @Override
21373    public byte[] getDefaultAppsBackup(int userId) {
21374        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21375            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
21376        }
21377
21378        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21379        try {
21380            final XmlSerializer serializer = new FastXmlSerializer();
21381            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21382            serializer.startDocument(null, true);
21383            serializer.startTag(null, TAG_DEFAULT_APPS);
21384
21385            synchronized (mPackages) {
21386                mSettings.writeDefaultAppsLPr(serializer, userId);
21387            }
21388
21389            serializer.endTag(null, TAG_DEFAULT_APPS);
21390            serializer.endDocument();
21391            serializer.flush();
21392        } catch (Exception e) {
21393            if (DEBUG_BACKUP) {
21394                Slog.e(TAG, "Unable to write default apps for backup", e);
21395            }
21396            return null;
21397        }
21398
21399        return dataStream.toByteArray();
21400    }
21401
21402    @Override
21403    public void restoreDefaultApps(byte[] backup, int userId) {
21404        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21405            throw new SecurityException("Only the system may call restoreDefaultApps()");
21406        }
21407
21408        try {
21409            final XmlPullParser parser = Xml.newPullParser();
21410            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21411            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21412                    new BlobXmlRestorer() {
21413                        @Override
21414                        public void apply(XmlPullParser parser, int userId)
21415                                throws XmlPullParserException, IOException {
21416                            synchronized (mPackages) {
21417                                mSettings.readDefaultAppsLPw(parser, userId);
21418                            }
21419                        }
21420                    } );
21421        } catch (Exception e) {
21422            if (DEBUG_BACKUP) {
21423                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21424            }
21425        }
21426    }
21427
21428    @Override
21429    public byte[] getIntentFilterVerificationBackup(int userId) {
21430        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21431            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21432        }
21433
21434        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21435        try {
21436            final XmlSerializer serializer = new FastXmlSerializer();
21437            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21438            serializer.startDocument(null, true);
21439            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21440
21441            synchronized (mPackages) {
21442                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21443            }
21444
21445            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21446            serializer.endDocument();
21447            serializer.flush();
21448        } catch (Exception e) {
21449            if (DEBUG_BACKUP) {
21450                Slog.e(TAG, "Unable to write default apps for backup", e);
21451            }
21452            return null;
21453        }
21454
21455        return dataStream.toByteArray();
21456    }
21457
21458    @Override
21459    public void restoreIntentFilterVerification(byte[] backup, int userId) {
21460        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21461            throw new SecurityException("Only the system may call restorePreferredActivities()");
21462        }
21463
21464        try {
21465            final XmlPullParser parser = Xml.newPullParser();
21466            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21467            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21468                    new BlobXmlRestorer() {
21469                        @Override
21470                        public void apply(XmlPullParser parser, int userId)
21471                                throws XmlPullParserException, IOException {
21472                            synchronized (mPackages) {
21473                                mSettings.readAllDomainVerificationsLPr(parser, userId);
21474                                mSettings.writeLPr();
21475                            }
21476                        }
21477                    } );
21478        } catch (Exception e) {
21479            if (DEBUG_BACKUP) {
21480                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21481            }
21482        }
21483    }
21484
21485    @Override
21486    public byte[] getPermissionGrantBackup(int userId) {
21487        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21488            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21489        }
21490
21491        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21492        try {
21493            final XmlSerializer serializer = new FastXmlSerializer();
21494            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21495            serializer.startDocument(null, true);
21496            serializer.startTag(null, TAG_PERMISSION_BACKUP);
21497
21498            synchronized (mPackages) {
21499                serializeRuntimePermissionGrantsLPr(serializer, userId);
21500            }
21501
21502            serializer.endTag(null, TAG_PERMISSION_BACKUP);
21503            serializer.endDocument();
21504            serializer.flush();
21505        } catch (Exception e) {
21506            if (DEBUG_BACKUP) {
21507                Slog.e(TAG, "Unable to write default apps for backup", e);
21508            }
21509            return null;
21510        }
21511
21512        return dataStream.toByteArray();
21513    }
21514
21515    @Override
21516    public void restorePermissionGrants(byte[] backup, int userId) {
21517        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21518            throw new SecurityException("Only the system may call restorePermissionGrants()");
21519        }
21520
21521        try {
21522            final XmlPullParser parser = Xml.newPullParser();
21523            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21524            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21525                    new BlobXmlRestorer() {
21526                        @Override
21527                        public void apply(XmlPullParser parser, int userId)
21528                                throws XmlPullParserException, IOException {
21529                            synchronized (mPackages) {
21530                                processRestoredPermissionGrantsLPr(parser, userId);
21531                            }
21532                        }
21533                    } );
21534        } catch (Exception e) {
21535            if (DEBUG_BACKUP) {
21536                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21537            }
21538        }
21539    }
21540
21541    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21542            throws IOException {
21543        serializer.startTag(null, TAG_ALL_GRANTS);
21544
21545        final int N = mSettings.mPackages.size();
21546        for (int i = 0; i < N; i++) {
21547            final PackageSetting ps = mSettings.mPackages.valueAt(i);
21548            boolean pkgGrantsKnown = false;
21549
21550            PermissionsState packagePerms = ps.getPermissionsState();
21551
21552            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21553                final int grantFlags = state.getFlags();
21554                // only look at grants that are not system/policy fixed
21555                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21556                    final boolean isGranted = state.isGranted();
21557                    // And only back up the user-twiddled state bits
21558                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21559                        final String packageName = mSettings.mPackages.keyAt(i);
21560                        if (!pkgGrantsKnown) {
21561                            serializer.startTag(null, TAG_GRANT);
21562                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21563                            pkgGrantsKnown = true;
21564                        }
21565
21566                        final boolean userSet =
21567                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21568                        final boolean userFixed =
21569                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21570                        final boolean revoke =
21571                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21572
21573                        serializer.startTag(null, TAG_PERMISSION);
21574                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21575                        if (isGranted) {
21576                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
21577                        }
21578                        if (userSet) {
21579                            serializer.attribute(null, ATTR_USER_SET, "true");
21580                        }
21581                        if (userFixed) {
21582                            serializer.attribute(null, ATTR_USER_FIXED, "true");
21583                        }
21584                        if (revoke) {
21585                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21586                        }
21587                        serializer.endTag(null, TAG_PERMISSION);
21588                    }
21589                }
21590            }
21591
21592            if (pkgGrantsKnown) {
21593                serializer.endTag(null, TAG_GRANT);
21594            }
21595        }
21596
21597        serializer.endTag(null, TAG_ALL_GRANTS);
21598    }
21599
21600    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21601            throws XmlPullParserException, IOException {
21602        String pkgName = null;
21603        int outerDepth = parser.getDepth();
21604        int type;
21605        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21606                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21607            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21608                continue;
21609            }
21610
21611            final String tagName = parser.getName();
21612            if (tagName.equals(TAG_GRANT)) {
21613                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21614                if (DEBUG_BACKUP) {
21615                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21616                }
21617            } else if (tagName.equals(TAG_PERMISSION)) {
21618
21619                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21620                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21621
21622                int newFlagSet = 0;
21623                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21624                    newFlagSet |= FLAG_PERMISSION_USER_SET;
21625                }
21626                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21627                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21628                }
21629                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21630                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21631                }
21632                if (DEBUG_BACKUP) {
21633                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
21634                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21635                }
21636                final PackageSetting ps = mSettings.mPackages.get(pkgName);
21637                if (ps != null) {
21638                    // Already installed so we apply the grant immediately
21639                    if (DEBUG_BACKUP) {
21640                        Slog.v(TAG, "        + already installed; applying");
21641                    }
21642                    PermissionsState perms = ps.getPermissionsState();
21643                    BasePermission bp = mSettings.mPermissions.get(permName);
21644                    if (bp != null) {
21645                        if (isGranted) {
21646                            perms.grantRuntimePermission(bp, userId);
21647                        }
21648                        if (newFlagSet != 0) {
21649                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21650                        }
21651                    }
21652                } else {
21653                    // Need to wait for post-restore install to apply the grant
21654                    if (DEBUG_BACKUP) {
21655                        Slog.v(TAG, "        - not yet installed; saving for later");
21656                    }
21657                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21658                            isGranted, newFlagSet, userId);
21659                }
21660            } else {
21661                PackageManagerService.reportSettingsProblem(Log.WARN,
21662                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21663                XmlUtils.skipCurrentTag(parser);
21664            }
21665        }
21666
21667        scheduleWriteSettingsLocked();
21668        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21669    }
21670
21671    @Override
21672    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21673            int sourceUserId, int targetUserId, int flags) {
21674        mContext.enforceCallingOrSelfPermission(
21675                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21676        int callingUid = Binder.getCallingUid();
21677        enforceOwnerRights(ownerPackage, callingUid);
21678        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21679        if (intentFilter.countActions() == 0) {
21680            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21681            return;
21682        }
21683        synchronized (mPackages) {
21684            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21685                    ownerPackage, targetUserId, flags);
21686            CrossProfileIntentResolver resolver =
21687                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21688            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21689            // We have all those whose filter is equal. Now checking if the rest is equal as well.
21690            if (existing != null) {
21691                int size = existing.size();
21692                for (int i = 0; i < size; i++) {
21693                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21694                        return;
21695                    }
21696                }
21697            }
21698            resolver.addFilter(newFilter);
21699            scheduleWritePackageRestrictionsLocked(sourceUserId);
21700        }
21701    }
21702
21703    @Override
21704    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21705        mContext.enforceCallingOrSelfPermission(
21706                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21707        final int callingUid = Binder.getCallingUid();
21708        enforceOwnerRights(ownerPackage, callingUid);
21709        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21710        synchronized (mPackages) {
21711            CrossProfileIntentResolver resolver =
21712                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21713            ArraySet<CrossProfileIntentFilter> set =
21714                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21715            for (CrossProfileIntentFilter filter : set) {
21716                if (filter.getOwnerPackage().equals(ownerPackage)) {
21717                    resolver.removeFilter(filter);
21718                }
21719            }
21720            scheduleWritePackageRestrictionsLocked(sourceUserId);
21721        }
21722    }
21723
21724    // Enforcing that callingUid is owning pkg on userId
21725    private void enforceOwnerRights(String pkg, int callingUid) {
21726        // The system owns everything.
21727        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21728            return;
21729        }
21730        final int callingUserId = UserHandle.getUserId(callingUid);
21731        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21732        if (pi == null) {
21733            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21734                    + callingUserId);
21735        }
21736        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21737            throw new SecurityException("Calling uid " + callingUid
21738                    + " does not own package " + pkg);
21739        }
21740    }
21741
21742    @Override
21743    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21744        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21745            return null;
21746        }
21747        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21748    }
21749
21750    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21751        UserManagerService ums = UserManagerService.getInstance();
21752        if (ums != null) {
21753            final UserInfo parent = ums.getProfileParent(userId);
21754            final int launcherUid = (parent != null) ? parent.id : userId;
21755            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21756            if (launcherComponent != null) {
21757                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21758                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21759                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21760                        .setPackage(launcherComponent.getPackageName());
21761                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21762            }
21763        }
21764    }
21765
21766    /**
21767     * Report the 'Home' activity which is currently set as "always use this one". If non is set
21768     * then reports the most likely home activity or null if there are more than one.
21769     */
21770    private ComponentName getDefaultHomeActivity(int userId) {
21771        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21772        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21773        if (cn != null) {
21774            return cn;
21775        }
21776
21777        // Find the launcher with the highest priority and return that component if there are no
21778        // other home activity with the same priority.
21779        int lastPriority = Integer.MIN_VALUE;
21780        ComponentName lastComponent = null;
21781        final int size = allHomeCandidates.size();
21782        for (int i = 0; i < size; i++) {
21783            final ResolveInfo ri = allHomeCandidates.get(i);
21784            if (ri.priority > lastPriority) {
21785                lastComponent = ri.activityInfo.getComponentName();
21786                lastPriority = ri.priority;
21787            } else if (ri.priority == lastPriority) {
21788                // Two components found with same priority.
21789                lastComponent = null;
21790            }
21791        }
21792        return lastComponent;
21793    }
21794
21795    private Intent getHomeIntent() {
21796        Intent intent = new Intent(Intent.ACTION_MAIN);
21797        intent.addCategory(Intent.CATEGORY_HOME);
21798        intent.addCategory(Intent.CATEGORY_DEFAULT);
21799        return intent;
21800    }
21801
21802    private IntentFilter getHomeFilter() {
21803        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21804        filter.addCategory(Intent.CATEGORY_HOME);
21805        filter.addCategory(Intent.CATEGORY_DEFAULT);
21806        return filter;
21807    }
21808
21809    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21810            int userId) {
21811        Intent intent  = getHomeIntent();
21812        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21813                PackageManager.GET_META_DATA, userId);
21814        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21815                true, false, false, userId);
21816
21817        allHomeCandidates.clear();
21818        if (list != null) {
21819            for (ResolveInfo ri : list) {
21820                allHomeCandidates.add(ri);
21821            }
21822        }
21823        return (preferred == null || preferred.activityInfo == null)
21824                ? null
21825                : new ComponentName(preferred.activityInfo.packageName,
21826                        preferred.activityInfo.name);
21827    }
21828
21829    @Override
21830    public void setHomeActivity(ComponentName comp, int userId) {
21831        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21832            return;
21833        }
21834        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21835        getHomeActivitiesAsUser(homeActivities, userId);
21836
21837        boolean found = false;
21838
21839        final int size = homeActivities.size();
21840        final ComponentName[] set = new ComponentName[size];
21841        for (int i = 0; i < size; i++) {
21842            final ResolveInfo candidate = homeActivities.get(i);
21843            final ActivityInfo info = candidate.activityInfo;
21844            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21845            set[i] = activityName;
21846            if (!found && activityName.equals(comp)) {
21847                found = true;
21848            }
21849        }
21850        if (!found) {
21851            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21852                    + userId);
21853        }
21854        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21855                set, comp, userId);
21856    }
21857
21858    private @Nullable String getSetupWizardPackageName() {
21859        final Intent intent = new Intent(Intent.ACTION_MAIN);
21860        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21861
21862        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21863                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21864                        | MATCH_DISABLED_COMPONENTS,
21865                UserHandle.myUserId());
21866        if (matches.size() == 1) {
21867            return matches.get(0).getComponentInfo().packageName;
21868        } else {
21869            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21870                    + ": matches=" + matches);
21871            return null;
21872        }
21873    }
21874
21875    private @Nullable String getStorageManagerPackageName() {
21876        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21877
21878        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21879                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21880                        | MATCH_DISABLED_COMPONENTS,
21881                UserHandle.myUserId());
21882        if (matches.size() == 1) {
21883            return matches.get(0).getComponentInfo().packageName;
21884        } else {
21885            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21886                    + matches.size() + ": matches=" + matches);
21887            return null;
21888        }
21889    }
21890
21891    @Override
21892    public void setApplicationEnabledSetting(String appPackageName,
21893            int newState, int flags, int userId, String callingPackage) {
21894        if (!sUserManager.exists(userId)) return;
21895        if (callingPackage == null) {
21896            callingPackage = Integer.toString(Binder.getCallingUid());
21897        }
21898        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21899    }
21900
21901    @Override
21902    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21903        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21904        synchronized (mPackages) {
21905            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21906            if (pkgSetting != null) {
21907                pkgSetting.setUpdateAvailable(updateAvailable);
21908            }
21909        }
21910    }
21911
21912    @Override
21913    public void setComponentEnabledSetting(ComponentName componentName,
21914            int newState, int flags, int userId) {
21915        if (!sUserManager.exists(userId)) return;
21916        setEnabledSetting(componentName.getPackageName(),
21917                componentName.getClassName(), newState, flags, userId, null);
21918    }
21919
21920    private void setEnabledSetting(final String packageName, String className, int newState,
21921            final int flags, int userId, String callingPackage) {
21922        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21923              || newState == COMPONENT_ENABLED_STATE_ENABLED
21924              || newState == COMPONENT_ENABLED_STATE_DISABLED
21925              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21926              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21927            throw new IllegalArgumentException("Invalid new component state: "
21928                    + newState);
21929        }
21930        PackageSetting pkgSetting;
21931        final int callingUid = Binder.getCallingUid();
21932        final int permission;
21933        if (callingUid == Process.SYSTEM_UID) {
21934            permission = PackageManager.PERMISSION_GRANTED;
21935        } else {
21936            permission = mContext.checkCallingOrSelfPermission(
21937                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21938        }
21939        enforceCrossUserPermission(callingUid, userId,
21940                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21941        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21942        boolean sendNow = false;
21943        boolean isApp = (className == null);
21944        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21945        String componentName = isApp ? packageName : className;
21946        int packageUid = -1;
21947        ArrayList<String> components;
21948
21949        // reader
21950        synchronized (mPackages) {
21951            pkgSetting = mSettings.mPackages.get(packageName);
21952            if (pkgSetting == null) {
21953                if (!isCallerInstantApp) {
21954                    if (className == null) {
21955                        throw new IllegalArgumentException("Unknown package: " + packageName);
21956                    }
21957                    throw new IllegalArgumentException(
21958                            "Unknown component: " + packageName + "/" + className);
21959                } else {
21960                    // throw SecurityException to prevent leaking package information
21961                    throw new SecurityException(
21962                            "Attempt to change component state; "
21963                            + "pid=" + Binder.getCallingPid()
21964                            + ", uid=" + callingUid
21965                            + (className == null
21966                                    ? ", package=" + packageName
21967                                    : ", component=" + packageName + "/" + className));
21968                }
21969            }
21970        }
21971
21972        // Limit who can change which apps
21973        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21974            // Don't allow apps that don't have permission to modify other apps
21975            if (!allowedByPermission
21976                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21977                throw new SecurityException(
21978                        "Attempt to change component state; "
21979                        + "pid=" + Binder.getCallingPid()
21980                        + ", uid=" + callingUid
21981                        + (className == null
21982                                ? ", package=" + packageName
21983                                : ", component=" + packageName + "/" + className));
21984            }
21985            // Don't allow changing protected packages.
21986            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21987                throw new SecurityException("Cannot disable a protected package: " + packageName);
21988            }
21989        }
21990
21991        synchronized (mPackages) {
21992            if (callingUid == Process.SHELL_UID
21993                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21994                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21995                // unless it is a test package.
21996                int oldState = pkgSetting.getEnabled(userId);
21997                if (className == null
21998                        &&
21999                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
22000                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
22001                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
22002                        &&
22003                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
22004                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
22005                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
22006                    // ok
22007                } else {
22008                    throw new SecurityException(
22009                            "Shell cannot change component state for " + packageName + "/"
22010                                    + className + " to " + newState);
22011                }
22012            }
22013        }
22014        if (className == null) {
22015            // We're dealing with an application/package level state change
22016            synchronized (mPackages) {
22017                if (pkgSetting.getEnabled(userId) == newState) {
22018                    // Nothing to do
22019                    return;
22020                }
22021            }
22022            // If we're enabling a system stub, there's a little more work to do.
22023            // Prior to enabling the package, we need to decompress the APK(s) to the
22024            // data partition and then replace the version on the system partition.
22025            final PackageParser.Package deletedPkg = pkgSetting.pkg;
22026            final boolean isSystemStub = deletedPkg.isStub
22027                    && deletedPkg.isSystemApp();
22028            if (isSystemStub
22029                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22030                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
22031                final File codePath = decompressPackage(deletedPkg);
22032                if (codePath == null) {
22033                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
22034                    return;
22035                }
22036                // TODO remove direct parsing of the package object during internal cleanup
22037                // of scan package
22038                // We need to call parse directly here for no other reason than we need
22039                // the new package in order to disable the old one [we use the information
22040                // for some internal optimization to optionally create a new package setting
22041                // object on replace]. However, we can't get the package from the scan
22042                // because the scan modifies live structures and we need to remove the
22043                // old [system] package from the system before a scan can be attempted.
22044                // Once scan is indempotent we can remove this parse and use the package
22045                // object we scanned, prior to adding it to package settings.
22046                final PackageParser pp = new PackageParser();
22047                pp.setSeparateProcesses(mSeparateProcesses);
22048                pp.setDisplayMetrics(mMetrics);
22049                pp.setCallback(mPackageParserCallback);
22050                final PackageParser.Package tmpPkg;
22051                try {
22052                    final int parseFlags = mDefParseFlags
22053                            | PackageParser.PARSE_MUST_BE_APK
22054                            | PackageParser.PARSE_IS_SYSTEM
22055                            | PackageParser.PARSE_IS_SYSTEM_DIR;
22056                    tmpPkg = pp.parsePackage(codePath, parseFlags);
22057                } catch (PackageParserException e) {
22058                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
22059                    return;
22060                }
22061                synchronized (mInstallLock) {
22062                    // Disable the stub and remove any package entries
22063                    removePackageLI(deletedPkg, true);
22064                    synchronized (mPackages) {
22065                        disableSystemPackageLPw(deletedPkg, tmpPkg);
22066                    }
22067                    final PackageParser.Package newPkg;
22068                    try (PackageFreezer freezer =
22069                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22070                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
22071                                | PackageParser.PARSE_ENFORCE_CODE;
22072                        newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
22073                                0 /*currentTime*/, null /*user*/);
22074                        prepareAppDataAfterInstallLIF(newPkg);
22075                        synchronized (mPackages) {
22076                            try {
22077                                updateSharedLibrariesLPr(newPkg, null);
22078                            } catch (PackageManagerException e) {
22079                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
22080                            }
22081                            updatePermissionsLPw(newPkg.packageName, newPkg,
22082                                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
22083                            mSettings.writeLPr();
22084                        }
22085                    } catch (PackageManagerException e) {
22086                        // Whoops! Something went wrong; try to roll back to the stub
22087                        Slog.w(TAG, "Failed to install compressed system package:"
22088                                + pkgSetting.name, e);
22089                        // Remove the failed install
22090                        removeCodePathLI(codePath);
22091
22092                        // Install the system package
22093                        try (PackageFreezer freezer =
22094                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
22095                            synchronized (mPackages) {
22096                                // NOTE: The system package always needs to be enabled; even
22097                                // if it's for a compressed stub. If we don't, installing the
22098                                // system package fails during scan [scanning checks the disabled
22099                                // packages]. We will reverse this later, after we've "installed"
22100                                // the stub.
22101                                // This leaves us in a fragile state; the stub should never be
22102                                // enabled, so, cross your fingers and hope nothing goes wrong
22103                                // until we can disable the package later.
22104                                enableSystemPackageLPw(deletedPkg);
22105                            }
22106                            installPackageFromSystemLIF(new File(deletedPkg.codePath),
22107                                    false /*isPrivileged*/, null /*allUserHandles*/,
22108                                    null /*origUserHandles*/, null /*origPermissionsState*/,
22109                                    true /*writeSettings*/);
22110                        } catch (PackageManagerException pme) {
22111                            Slog.w(TAG, "Failed to restore system package:"
22112                                    + deletedPkg.packageName, pme);
22113                        } finally {
22114                            synchronized (mPackages) {
22115                                mSettings.disableSystemPackageLPw(
22116                                        deletedPkg.packageName, true /*replaced*/);
22117                                mSettings.writeLPr();
22118                            }
22119                        }
22120                        return;
22121                    }
22122                    clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
22123                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22124                    clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
22125                    mDexManager.notifyPackageUpdated(newPkg.packageName,
22126                            newPkg.baseCodePath, newPkg.splitCodePaths);
22127                }
22128            }
22129            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
22130                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
22131                // Don't care about who enables an app.
22132                callingPackage = null;
22133            }
22134            synchronized (mPackages) {
22135                pkgSetting.setEnabled(newState, userId, callingPackage);
22136            }
22137        } else {
22138            synchronized (mPackages) {
22139                // We're dealing with a component level state change
22140                // First, verify that this is a valid class name.
22141                PackageParser.Package pkg = pkgSetting.pkg;
22142                if (pkg == null || !pkg.hasComponentClassName(className)) {
22143                    if (pkg != null &&
22144                            pkg.applicationInfo.targetSdkVersion >=
22145                                    Build.VERSION_CODES.JELLY_BEAN) {
22146                        throw new IllegalArgumentException("Component class " + className
22147                                + " does not exist in " + packageName);
22148                    } else {
22149                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
22150                                + className + " does not exist in " + packageName);
22151                    }
22152                }
22153                switch (newState) {
22154                    case COMPONENT_ENABLED_STATE_ENABLED:
22155                        if (!pkgSetting.enableComponentLPw(className, userId)) {
22156                            return;
22157                        }
22158                        break;
22159                    case COMPONENT_ENABLED_STATE_DISABLED:
22160                        if (!pkgSetting.disableComponentLPw(className, userId)) {
22161                            return;
22162                        }
22163                        break;
22164                    case COMPONENT_ENABLED_STATE_DEFAULT:
22165                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
22166                            return;
22167                        }
22168                        break;
22169                    default:
22170                        Slog.e(TAG, "Invalid new component state: " + newState);
22171                        return;
22172                }
22173            }
22174        }
22175        synchronized (mPackages) {
22176            scheduleWritePackageRestrictionsLocked(userId);
22177            updateSequenceNumberLP(pkgSetting, new int[] { userId });
22178            final long callingId = Binder.clearCallingIdentity();
22179            try {
22180                updateInstantAppInstallerLocked(packageName);
22181            } finally {
22182                Binder.restoreCallingIdentity(callingId);
22183            }
22184            components = mPendingBroadcasts.get(userId, packageName);
22185            final boolean newPackage = components == null;
22186            if (newPackage) {
22187                components = new ArrayList<String>();
22188            }
22189            if (!components.contains(componentName)) {
22190                components.add(componentName);
22191            }
22192            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
22193                sendNow = true;
22194                // Purge entry from pending broadcast list if another one exists already
22195                // since we are sending one right away.
22196                mPendingBroadcasts.remove(userId, packageName);
22197            } else {
22198                if (newPackage) {
22199                    mPendingBroadcasts.put(userId, packageName, components);
22200                }
22201                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
22202                    // Schedule a message
22203                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
22204                }
22205            }
22206        }
22207
22208        long callingId = Binder.clearCallingIdentity();
22209        try {
22210            if (sendNow) {
22211                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
22212                sendPackageChangedBroadcast(packageName,
22213                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
22214            }
22215        } finally {
22216            Binder.restoreCallingIdentity(callingId);
22217        }
22218    }
22219
22220    @Override
22221    public void flushPackageRestrictionsAsUser(int userId) {
22222        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22223            return;
22224        }
22225        if (!sUserManager.exists(userId)) {
22226            return;
22227        }
22228        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
22229                false /* checkShell */, "flushPackageRestrictions");
22230        synchronized (mPackages) {
22231            mSettings.writePackageRestrictionsLPr(userId);
22232            mDirtyUsers.remove(userId);
22233            if (mDirtyUsers.isEmpty()) {
22234                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
22235            }
22236        }
22237    }
22238
22239    private void sendPackageChangedBroadcast(String packageName,
22240            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
22241        if (DEBUG_INSTALL)
22242            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
22243                    + componentNames);
22244        Bundle extras = new Bundle(4);
22245        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
22246        String nameList[] = new String[componentNames.size()];
22247        componentNames.toArray(nameList);
22248        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
22249        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
22250        extras.putInt(Intent.EXTRA_UID, packageUid);
22251        // If this is not reporting a change of the overall package, then only send it
22252        // to registered receivers.  We don't want to launch a swath of apps for every
22253        // little component state change.
22254        final int flags = !componentNames.contains(packageName)
22255                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
22256        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
22257                new int[] {UserHandle.getUserId(packageUid)});
22258    }
22259
22260    @Override
22261    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
22262        if (!sUserManager.exists(userId)) return;
22263        final int callingUid = Binder.getCallingUid();
22264        if (getInstantAppPackageName(callingUid) != null) {
22265            return;
22266        }
22267        final int permission = mContext.checkCallingOrSelfPermission(
22268                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
22269        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
22270        enforceCrossUserPermission(callingUid, userId,
22271                true /* requireFullPermission */, true /* checkShell */, "stop package");
22272        // writer
22273        synchronized (mPackages) {
22274            final PackageSetting ps = mSettings.mPackages.get(packageName);
22275            if (!filterAppAccessLPr(ps, callingUid, userId)
22276                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
22277                            allowedByPermission, callingUid, userId)) {
22278                scheduleWritePackageRestrictionsLocked(userId);
22279            }
22280        }
22281    }
22282
22283    @Override
22284    public String getInstallerPackageName(String packageName) {
22285        final int callingUid = Binder.getCallingUid();
22286        if (getInstantAppPackageName(callingUid) != null) {
22287            return null;
22288        }
22289        // reader
22290        synchronized (mPackages) {
22291            final PackageSetting ps = mSettings.mPackages.get(packageName);
22292            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
22293                return null;
22294            }
22295            return mSettings.getInstallerPackageNameLPr(packageName);
22296        }
22297    }
22298
22299    public boolean isOrphaned(String packageName) {
22300        // reader
22301        synchronized (mPackages) {
22302            return mSettings.isOrphaned(packageName);
22303        }
22304    }
22305
22306    @Override
22307    public int getApplicationEnabledSetting(String packageName, int userId) {
22308        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22309        int callingUid = Binder.getCallingUid();
22310        enforceCrossUserPermission(callingUid, userId,
22311                false /* requireFullPermission */, false /* checkShell */, "get enabled");
22312        // reader
22313        synchronized (mPackages) {
22314            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
22315                return COMPONENT_ENABLED_STATE_DISABLED;
22316            }
22317            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
22318        }
22319    }
22320
22321    @Override
22322    public int getComponentEnabledSetting(ComponentName component, int userId) {
22323        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22324        int callingUid = Binder.getCallingUid();
22325        enforceCrossUserPermission(callingUid, userId,
22326                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
22327        synchronized (mPackages) {
22328            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
22329                    component, TYPE_UNKNOWN, userId)) {
22330                return COMPONENT_ENABLED_STATE_DISABLED;
22331            }
22332            return mSettings.getComponentEnabledSettingLPr(component, userId);
22333        }
22334    }
22335
22336    @Override
22337    public void enterSafeMode() {
22338        enforceSystemOrRoot("Only the system can request entering safe mode");
22339
22340        if (!mSystemReady) {
22341            mSafeMode = true;
22342        }
22343    }
22344
22345    @Override
22346    public void systemReady() {
22347        enforceSystemOrRoot("Only the system can claim the system is ready");
22348
22349        mSystemReady = true;
22350        final ContentResolver resolver = mContext.getContentResolver();
22351        ContentObserver co = new ContentObserver(mHandler) {
22352            @Override
22353            public void onChange(boolean selfChange) {
22354                mEphemeralAppsDisabled =
22355                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
22356                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
22357            }
22358        };
22359        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22360                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
22361                false, co, UserHandle.USER_SYSTEM);
22362        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22363                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
22364        co.onChange(true);
22365
22366        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
22367        // disabled after already being started.
22368        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
22369                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
22370
22371        // Read the compatibilty setting when the system is ready.
22372        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
22373                mContext.getContentResolver(),
22374                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
22375        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
22376        if (DEBUG_SETTINGS) {
22377            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
22378        }
22379
22380        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
22381
22382        synchronized (mPackages) {
22383            // Verify that all of the preferred activity components actually
22384            // exist.  It is possible for applications to be updated and at
22385            // that point remove a previously declared activity component that
22386            // had been set as a preferred activity.  We try to clean this up
22387            // the next time we encounter that preferred activity, but it is
22388            // possible for the user flow to never be able to return to that
22389            // situation so here we do a sanity check to make sure we haven't
22390            // left any junk around.
22391            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
22392            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22393                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22394                removed.clear();
22395                for (PreferredActivity pa : pir.filterSet()) {
22396                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
22397                        removed.add(pa);
22398                    }
22399                }
22400                if (removed.size() > 0) {
22401                    for (int r=0; r<removed.size(); r++) {
22402                        PreferredActivity pa = removed.get(r);
22403                        Slog.w(TAG, "Removing dangling preferred activity: "
22404                                + pa.mPref.mComponent);
22405                        pir.removeFilter(pa);
22406                    }
22407                    mSettings.writePackageRestrictionsLPr(
22408                            mSettings.mPreferredActivities.keyAt(i));
22409                }
22410            }
22411
22412            for (int userId : UserManagerService.getInstance().getUserIds()) {
22413                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
22414                    grantPermissionsUserIds = ArrayUtils.appendInt(
22415                            grantPermissionsUserIds, userId);
22416                }
22417            }
22418        }
22419        sUserManager.systemReady();
22420
22421        // If we upgraded grant all default permissions before kicking off.
22422        for (int userId : grantPermissionsUserIds) {
22423            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22424        }
22425
22426        // If we did not grant default permissions, we preload from this the
22427        // default permission exceptions lazily to ensure we don't hit the
22428        // disk on a new user creation.
22429        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
22430            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
22431        }
22432
22433        // Kick off any messages waiting for system ready
22434        if (mPostSystemReadyMessages != null) {
22435            for (Message msg : mPostSystemReadyMessages) {
22436                msg.sendToTarget();
22437            }
22438            mPostSystemReadyMessages = null;
22439        }
22440
22441        // Watch for external volumes that come and go over time
22442        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22443        storage.registerListener(mStorageListener);
22444
22445        mInstallerService.systemReady();
22446        mPackageDexOptimizer.systemReady();
22447
22448        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
22449                StorageManagerInternal.class);
22450        StorageManagerInternal.addExternalStoragePolicy(
22451                new StorageManagerInternal.ExternalStorageMountPolicy() {
22452            @Override
22453            public int getMountMode(int uid, String packageName) {
22454                if (Process.isIsolated(uid)) {
22455                    return Zygote.MOUNT_EXTERNAL_NONE;
22456                }
22457                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
22458                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
22459                }
22460                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22461                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
22462                }
22463                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22464                    return Zygote.MOUNT_EXTERNAL_READ;
22465                }
22466                return Zygote.MOUNT_EXTERNAL_WRITE;
22467            }
22468
22469            @Override
22470            public boolean hasExternalStorage(int uid, String packageName) {
22471                return true;
22472            }
22473        });
22474
22475        // Now that we're mostly running, clean up stale users and apps
22476        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
22477        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
22478
22479        if (mPrivappPermissionsViolations != null) {
22480            Slog.wtf(TAG,"Signature|privileged permissions not in "
22481                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
22482            mPrivappPermissionsViolations = null;
22483        }
22484    }
22485
22486    public void waitForAppDataPrepared() {
22487        if (mPrepareAppDataFuture == null) {
22488            return;
22489        }
22490        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
22491        mPrepareAppDataFuture = null;
22492    }
22493
22494    @Override
22495    public boolean isSafeMode() {
22496        // allow instant applications
22497        return mSafeMode;
22498    }
22499
22500    @Override
22501    public boolean hasSystemUidErrors() {
22502        // allow instant applications
22503        return mHasSystemUidErrors;
22504    }
22505
22506    static String arrayToString(int[] array) {
22507        StringBuffer buf = new StringBuffer(128);
22508        buf.append('[');
22509        if (array != null) {
22510            for (int i=0; i<array.length; i++) {
22511                if (i > 0) buf.append(", ");
22512                buf.append(array[i]);
22513            }
22514        }
22515        buf.append(']');
22516        return buf.toString();
22517    }
22518
22519    static class DumpState {
22520        public static final int DUMP_LIBS = 1 << 0;
22521        public static final int DUMP_FEATURES = 1 << 1;
22522        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
22523        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
22524        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22525        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22526        public static final int DUMP_PERMISSIONS = 1 << 6;
22527        public static final int DUMP_PACKAGES = 1 << 7;
22528        public static final int DUMP_SHARED_USERS = 1 << 8;
22529        public static final int DUMP_MESSAGES = 1 << 9;
22530        public static final int DUMP_PROVIDERS = 1 << 10;
22531        public static final int DUMP_VERIFIERS = 1 << 11;
22532        public static final int DUMP_PREFERRED = 1 << 12;
22533        public static final int DUMP_PREFERRED_XML = 1 << 13;
22534        public static final int DUMP_KEYSETS = 1 << 14;
22535        public static final int DUMP_VERSION = 1 << 15;
22536        public static final int DUMP_INSTALLS = 1 << 16;
22537        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22538        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22539        public static final int DUMP_FROZEN = 1 << 19;
22540        public static final int DUMP_DEXOPT = 1 << 20;
22541        public static final int DUMP_COMPILER_STATS = 1 << 21;
22542        public static final int DUMP_CHANGES = 1 << 22;
22543        public static final int DUMP_VOLUMES = 1 << 23;
22544
22545        public static final int OPTION_SHOW_FILTERS = 1 << 0;
22546
22547        private int mTypes;
22548
22549        private int mOptions;
22550
22551        private boolean mTitlePrinted;
22552
22553        private SharedUserSetting mSharedUser;
22554
22555        public boolean isDumping(int type) {
22556            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22557                return true;
22558            }
22559
22560            return (mTypes & type) != 0;
22561        }
22562
22563        public void setDump(int type) {
22564            mTypes |= type;
22565        }
22566
22567        public boolean isOptionEnabled(int option) {
22568            return (mOptions & option) != 0;
22569        }
22570
22571        public void setOptionEnabled(int option) {
22572            mOptions |= option;
22573        }
22574
22575        public boolean onTitlePrinted() {
22576            final boolean printed = mTitlePrinted;
22577            mTitlePrinted = true;
22578            return printed;
22579        }
22580
22581        public boolean getTitlePrinted() {
22582            return mTitlePrinted;
22583        }
22584
22585        public void setTitlePrinted(boolean enabled) {
22586            mTitlePrinted = enabled;
22587        }
22588
22589        public SharedUserSetting getSharedUser() {
22590            return mSharedUser;
22591        }
22592
22593        public void setSharedUser(SharedUserSetting user) {
22594            mSharedUser = user;
22595        }
22596    }
22597
22598    @Override
22599    public void onShellCommand(FileDescriptor in, FileDescriptor out,
22600            FileDescriptor err, String[] args, ShellCallback callback,
22601            ResultReceiver resultReceiver) {
22602        (new PackageManagerShellCommand(this)).exec(
22603                this, in, out, err, args, callback, resultReceiver);
22604    }
22605
22606    @Override
22607    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22608        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22609
22610        DumpState dumpState = new DumpState();
22611        boolean fullPreferred = false;
22612        boolean checkin = false;
22613
22614        String packageName = null;
22615        ArraySet<String> permissionNames = null;
22616
22617        int opti = 0;
22618        while (opti < args.length) {
22619            String opt = args[opti];
22620            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22621                break;
22622            }
22623            opti++;
22624
22625            if ("-a".equals(opt)) {
22626                // Right now we only know how to print all.
22627            } else if ("-h".equals(opt)) {
22628                pw.println("Package manager dump options:");
22629                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
22630                pw.println("    --checkin: dump for a checkin");
22631                pw.println("    -f: print details of intent filters");
22632                pw.println("    -h: print this help");
22633                pw.println("  cmd may be one of:");
22634                pw.println("    l[ibraries]: list known shared libraries");
22635                pw.println("    f[eatures]: list device features");
22636                pw.println("    k[eysets]: print known keysets");
22637                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22638                pw.println("    perm[issions]: dump permissions");
22639                pw.println("    permission [name ...]: dump declaration and use of given permission");
22640                pw.println("    pref[erred]: print preferred package settings");
22641                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
22642                pw.println("    prov[iders]: dump content providers");
22643                pw.println("    p[ackages]: dump installed packages");
22644                pw.println("    s[hared-users]: dump shared user IDs");
22645                pw.println("    m[essages]: print collected runtime messages");
22646                pw.println("    v[erifiers]: print package verifier info");
22647                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
22648                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22649                pw.println("    version: print database version info");
22650                pw.println("    write: write current settings now");
22651                pw.println("    installs: details about install sessions");
22652                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
22653                pw.println("    dexopt: dump dexopt state");
22654                pw.println("    compiler-stats: dump compiler statistics");
22655                pw.println("    enabled-overlays: dump list of enabled overlay packages");
22656                pw.println("    <package.name>: info about given package");
22657                return;
22658            } else if ("--checkin".equals(opt)) {
22659                checkin = true;
22660            } else if ("-f".equals(opt)) {
22661                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22662            } else if ("--proto".equals(opt)) {
22663                dumpProto(fd);
22664                return;
22665            } else {
22666                pw.println("Unknown argument: " + opt + "; use -h for help");
22667            }
22668        }
22669
22670        // Is the caller requesting to dump a particular piece of data?
22671        if (opti < args.length) {
22672            String cmd = args[opti];
22673            opti++;
22674            // Is this a package name?
22675            if ("android".equals(cmd) || cmd.contains(".")) {
22676                packageName = cmd;
22677                // When dumping a single package, we always dump all of its
22678                // filter information since the amount of data will be reasonable.
22679                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22680            } else if ("check-permission".equals(cmd)) {
22681                if (opti >= args.length) {
22682                    pw.println("Error: check-permission missing permission argument");
22683                    return;
22684                }
22685                String perm = args[opti];
22686                opti++;
22687                if (opti >= args.length) {
22688                    pw.println("Error: check-permission missing package argument");
22689                    return;
22690                }
22691
22692                String pkg = args[opti];
22693                opti++;
22694                int user = UserHandle.getUserId(Binder.getCallingUid());
22695                if (opti < args.length) {
22696                    try {
22697                        user = Integer.parseInt(args[opti]);
22698                    } catch (NumberFormatException e) {
22699                        pw.println("Error: check-permission user argument is not a number: "
22700                                + args[opti]);
22701                        return;
22702                    }
22703                }
22704
22705                // Normalize package name to handle renamed packages and static libs
22706                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22707
22708                pw.println(checkPermission(perm, pkg, user));
22709                return;
22710            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22711                dumpState.setDump(DumpState.DUMP_LIBS);
22712            } else if ("f".equals(cmd) || "features".equals(cmd)) {
22713                dumpState.setDump(DumpState.DUMP_FEATURES);
22714            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22715                if (opti >= args.length) {
22716                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22717                            | DumpState.DUMP_SERVICE_RESOLVERS
22718                            | DumpState.DUMP_RECEIVER_RESOLVERS
22719                            | DumpState.DUMP_CONTENT_RESOLVERS);
22720                } else {
22721                    while (opti < args.length) {
22722                        String name = args[opti];
22723                        if ("a".equals(name) || "activity".equals(name)) {
22724                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22725                        } else if ("s".equals(name) || "service".equals(name)) {
22726                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22727                        } else if ("r".equals(name) || "receiver".equals(name)) {
22728                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22729                        } else if ("c".equals(name) || "content".equals(name)) {
22730                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22731                        } else {
22732                            pw.println("Error: unknown resolver table type: " + name);
22733                            return;
22734                        }
22735                        opti++;
22736                    }
22737                }
22738            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22739                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22740            } else if ("permission".equals(cmd)) {
22741                if (opti >= args.length) {
22742                    pw.println("Error: permission requires permission name");
22743                    return;
22744                }
22745                permissionNames = new ArraySet<>();
22746                while (opti < args.length) {
22747                    permissionNames.add(args[opti]);
22748                    opti++;
22749                }
22750                dumpState.setDump(DumpState.DUMP_PERMISSIONS
22751                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22752            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22753                dumpState.setDump(DumpState.DUMP_PREFERRED);
22754            } else if ("preferred-xml".equals(cmd)) {
22755                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22756                if (opti < args.length && "--full".equals(args[opti])) {
22757                    fullPreferred = true;
22758                    opti++;
22759                }
22760            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22761                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22762            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22763                dumpState.setDump(DumpState.DUMP_PACKAGES);
22764            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22765                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22766            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22767                dumpState.setDump(DumpState.DUMP_PROVIDERS);
22768            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22769                dumpState.setDump(DumpState.DUMP_MESSAGES);
22770            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22771                dumpState.setDump(DumpState.DUMP_VERIFIERS);
22772            } else if ("i".equals(cmd) || "ifv".equals(cmd)
22773                    || "intent-filter-verifiers".equals(cmd)) {
22774                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22775            } else if ("version".equals(cmd)) {
22776                dumpState.setDump(DumpState.DUMP_VERSION);
22777            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22778                dumpState.setDump(DumpState.DUMP_KEYSETS);
22779            } else if ("installs".equals(cmd)) {
22780                dumpState.setDump(DumpState.DUMP_INSTALLS);
22781            } else if ("frozen".equals(cmd)) {
22782                dumpState.setDump(DumpState.DUMP_FROZEN);
22783            } else if ("volumes".equals(cmd)) {
22784                dumpState.setDump(DumpState.DUMP_VOLUMES);
22785            } else if ("dexopt".equals(cmd)) {
22786                dumpState.setDump(DumpState.DUMP_DEXOPT);
22787            } else if ("compiler-stats".equals(cmd)) {
22788                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22789            } else if ("changes".equals(cmd)) {
22790                dumpState.setDump(DumpState.DUMP_CHANGES);
22791            } else if ("write".equals(cmd)) {
22792                synchronized (mPackages) {
22793                    mSettings.writeLPr();
22794                    pw.println("Settings written.");
22795                    return;
22796                }
22797            }
22798        }
22799
22800        if (checkin) {
22801            pw.println("vers,1");
22802        }
22803
22804        // reader
22805        synchronized (mPackages) {
22806            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22807                if (!checkin) {
22808                    if (dumpState.onTitlePrinted())
22809                        pw.println();
22810                    pw.println("Database versions:");
22811                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22812                }
22813            }
22814
22815            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22816                if (!checkin) {
22817                    if (dumpState.onTitlePrinted())
22818                        pw.println();
22819                    pw.println("Verifiers:");
22820                    pw.print("  Required: ");
22821                    pw.print(mRequiredVerifierPackage);
22822                    pw.print(" (uid=");
22823                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22824                            UserHandle.USER_SYSTEM));
22825                    pw.println(")");
22826                } else if (mRequiredVerifierPackage != null) {
22827                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22828                    pw.print(",");
22829                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22830                            UserHandle.USER_SYSTEM));
22831                }
22832            }
22833
22834            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22835                    packageName == null) {
22836                if (mIntentFilterVerifierComponent != null) {
22837                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22838                    if (!checkin) {
22839                        if (dumpState.onTitlePrinted())
22840                            pw.println();
22841                        pw.println("Intent Filter Verifier:");
22842                        pw.print("  Using: ");
22843                        pw.print(verifierPackageName);
22844                        pw.print(" (uid=");
22845                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22846                                UserHandle.USER_SYSTEM));
22847                        pw.println(")");
22848                    } else if (verifierPackageName != null) {
22849                        pw.print("ifv,"); pw.print(verifierPackageName);
22850                        pw.print(",");
22851                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22852                                UserHandle.USER_SYSTEM));
22853                    }
22854                } else {
22855                    pw.println();
22856                    pw.println("No Intent Filter Verifier available!");
22857                }
22858            }
22859
22860            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22861                boolean printedHeader = false;
22862                final Iterator<String> it = mSharedLibraries.keySet().iterator();
22863                while (it.hasNext()) {
22864                    String libName = it.next();
22865                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22866                    if (versionedLib == null) {
22867                        continue;
22868                    }
22869                    final int versionCount = versionedLib.size();
22870                    for (int i = 0; i < versionCount; i++) {
22871                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22872                        if (!checkin) {
22873                            if (!printedHeader) {
22874                                if (dumpState.onTitlePrinted())
22875                                    pw.println();
22876                                pw.println("Libraries:");
22877                                printedHeader = true;
22878                            }
22879                            pw.print("  ");
22880                        } else {
22881                            pw.print("lib,");
22882                        }
22883                        pw.print(libEntry.info.getName());
22884                        if (libEntry.info.isStatic()) {
22885                            pw.print(" version=" + libEntry.info.getVersion());
22886                        }
22887                        if (!checkin) {
22888                            pw.print(" -> ");
22889                        }
22890                        if (libEntry.path != null) {
22891                            pw.print(" (jar) ");
22892                            pw.print(libEntry.path);
22893                        } else {
22894                            pw.print(" (apk) ");
22895                            pw.print(libEntry.apk);
22896                        }
22897                        pw.println();
22898                    }
22899                }
22900            }
22901
22902            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22903                if (dumpState.onTitlePrinted())
22904                    pw.println();
22905                if (!checkin) {
22906                    pw.println("Features:");
22907                }
22908
22909                synchronized (mAvailableFeatures) {
22910                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22911                        if (checkin) {
22912                            pw.print("feat,");
22913                            pw.print(feat.name);
22914                            pw.print(",");
22915                            pw.println(feat.version);
22916                        } else {
22917                            pw.print("  ");
22918                            pw.print(feat.name);
22919                            if (feat.version > 0) {
22920                                pw.print(" version=");
22921                                pw.print(feat.version);
22922                            }
22923                            pw.println();
22924                        }
22925                    }
22926                }
22927            }
22928
22929            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22930                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22931                        : "Activity Resolver Table:", "  ", packageName,
22932                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22933                    dumpState.setTitlePrinted(true);
22934                }
22935            }
22936            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22937                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22938                        : "Receiver Resolver Table:", "  ", packageName,
22939                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22940                    dumpState.setTitlePrinted(true);
22941                }
22942            }
22943            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22944                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22945                        : "Service Resolver Table:", "  ", packageName,
22946                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22947                    dumpState.setTitlePrinted(true);
22948                }
22949            }
22950            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22951                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22952                        : "Provider Resolver Table:", "  ", packageName,
22953                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22954                    dumpState.setTitlePrinted(true);
22955                }
22956            }
22957
22958            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22959                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22960                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22961                    int user = mSettings.mPreferredActivities.keyAt(i);
22962                    if (pir.dump(pw,
22963                            dumpState.getTitlePrinted()
22964                                ? "\nPreferred Activities User " + user + ":"
22965                                : "Preferred Activities User " + user + ":", "  ",
22966                            packageName, true, false)) {
22967                        dumpState.setTitlePrinted(true);
22968                    }
22969                }
22970            }
22971
22972            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22973                pw.flush();
22974                FileOutputStream fout = new FileOutputStream(fd);
22975                BufferedOutputStream str = new BufferedOutputStream(fout);
22976                XmlSerializer serializer = new FastXmlSerializer();
22977                try {
22978                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22979                    serializer.startDocument(null, true);
22980                    serializer.setFeature(
22981                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22982                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22983                    serializer.endDocument();
22984                    serializer.flush();
22985                } catch (IllegalArgumentException e) {
22986                    pw.println("Failed writing: " + e);
22987                } catch (IllegalStateException e) {
22988                    pw.println("Failed writing: " + e);
22989                } catch (IOException e) {
22990                    pw.println("Failed writing: " + e);
22991                }
22992            }
22993
22994            if (!checkin
22995                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22996                    && packageName == null) {
22997                pw.println();
22998                int count = mSettings.mPackages.size();
22999                if (count == 0) {
23000                    pw.println("No applications!");
23001                    pw.println();
23002                } else {
23003                    final String prefix = "  ";
23004                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
23005                    if (allPackageSettings.size() == 0) {
23006                        pw.println("No domain preferred apps!");
23007                        pw.println();
23008                    } else {
23009                        pw.println("App verification status:");
23010                        pw.println();
23011                        count = 0;
23012                        for (PackageSetting ps : allPackageSettings) {
23013                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
23014                            if (ivi == null || ivi.getPackageName() == null) continue;
23015                            pw.println(prefix + "Package: " + ivi.getPackageName());
23016                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
23017                            pw.println(prefix + "Status:  " + ivi.getStatusString());
23018                            pw.println();
23019                            count++;
23020                        }
23021                        if (count == 0) {
23022                            pw.println(prefix + "No app verification established.");
23023                            pw.println();
23024                        }
23025                        for (int userId : sUserManager.getUserIds()) {
23026                            pw.println("App linkages for user " + userId + ":");
23027                            pw.println();
23028                            count = 0;
23029                            for (PackageSetting ps : allPackageSettings) {
23030                                final long status = ps.getDomainVerificationStatusForUser(userId);
23031                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
23032                                        && !DEBUG_DOMAIN_VERIFICATION) {
23033                                    continue;
23034                                }
23035                                pw.println(prefix + "Package: " + ps.name);
23036                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
23037                                String statusStr = IntentFilterVerificationInfo.
23038                                        getStatusStringFromValue(status);
23039                                pw.println(prefix + "Status:  " + statusStr);
23040                                pw.println();
23041                                count++;
23042                            }
23043                            if (count == 0) {
23044                                pw.println(prefix + "No configured app linkages.");
23045                                pw.println();
23046                            }
23047                        }
23048                    }
23049                }
23050            }
23051
23052            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
23053                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
23054                if (packageName == null && permissionNames == null) {
23055                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
23056                        if (iperm == 0) {
23057                            if (dumpState.onTitlePrinted())
23058                                pw.println();
23059                            pw.println("AppOp Permissions:");
23060                        }
23061                        pw.print("  AppOp Permission ");
23062                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
23063                        pw.println(":");
23064                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
23065                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
23066                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
23067                        }
23068                    }
23069                }
23070            }
23071
23072            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
23073                boolean printedSomething = false;
23074                for (PackageParser.Provider p : mProviders.mProviders.values()) {
23075                    if (packageName != null && !packageName.equals(p.info.packageName)) {
23076                        continue;
23077                    }
23078                    if (!printedSomething) {
23079                        if (dumpState.onTitlePrinted())
23080                            pw.println();
23081                        pw.println("Registered ContentProviders:");
23082                        printedSomething = true;
23083                    }
23084                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
23085                    pw.print("    "); pw.println(p.toString());
23086                }
23087                printedSomething = false;
23088                for (Map.Entry<String, PackageParser.Provider> entry :
23089                        mProvidersByAuthority.entrySet()) {
23090                    PackageParser.Provider p = entry.getValue();
23091                    if (packageName != null && !packageName.equals(p.info.packageName)) {
23092                        continue;
23093                    }
23094                    if (!printedSomething) {
23095                        if (dumpState.onTitlePrinted())
23096                            pw.println();
23097                        pw.println("ContentProvider Authorities:");
23098                        printedSomething = true;
23099                    }
23100                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
23101                    pw.print("    "); pw.println(p.toString());
23102                    if (p.info != null && p.info.applicationInfo != null) {
23103                        final String appInfo = p.info.applicationInfo.toString();
23104                        pw.print("      applicationInfo="); pw.println(appInfo);
23105                    }
23106                }
23107            }
23108
23109            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
23110                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
23111            }
23112
23113            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
23114                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
23115            }
23116
23117            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
23118                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
23119            }
23120
23121            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
23122                if (dumpState.onTitlePrinted()) pw.println();
23123                pw.println("Package Changes:");
23124                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
23125                final int K = mChangedPackages.size();
23126                for (int i = 0; i < K; i++) {
23127                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
23128                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
23129                    final int N = changes.size();
23130                    if (N == 0) {
23131                        pw.print("    "); pw.println("No packages changed");
23132                    } else {
23133                        for (int j = 0; j < N; j++) {
23134                            final String pkgName = changes.valueAt(j);
23135                            final int sequenceNumber = changes.keyAt(j);
23136                            pw.print("    ");
23137                            pw.print("seq=");
23138                            pw.print(sequenceNumber);
23139                            pw.print(", package=");
23140                            pw.println(pkgName);
23141                        }
23142                    }
23143                }
23144            }
23145
23146            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
23147                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
23148            }
23149
23150            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
23151                // XXX should handle packageName != null by dumping only install data that
23152                // the given package is involved with.
23153                if (dumpState.onTitlePrinted()) pw.println();
23154
23155                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23156                ipw.println();
23157                ipw.println("Frozen packages:");
23158                ipw.increaseIndent();
23159                if (mFrozenPackages.size() == 0) {
23160                    ipw.println("(none)");
23161                } else {
23162                    for (int i = 0; i < mFrozenPackages.size(); i++) {
23163                        ipw.println(mFrozenPackages.valueAt(i));
23164                    }
23165                }
23166                ipw.decreaseIndent();
23167            }
23168
23169            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
23170                if (dumpState.onTitlePrinted()) pw.println();
23171
23172                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23173                ipw.println();
23174                ipw.println("Loaded volumes:");
23175                ipw.increaseIndent();
23176                if (mLoadedVolumes.size() == 0) {
23177                    ipw.println("(none)");
23178                } else {
23179                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
23180                        ipw.println(mLoadedVolumes.valueAt(i));
23181                    }
23182                }
23183                ipw.decreaseIndent();
23184            }
23185
23186            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
23187                if (dumpState.onTitlePrinted()) pw.println();
23188                dumpDexoptStateLPr(pw, packageName);
23189            }
23190
23191            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
23192                if (dumpState.onTitlePrinted()) pw.println();
23193                dumpCompilerStatsLPr(pw, packageName);
23194            }
23195
23196            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
23197                if (dumpState.onTitlePrinted()) pw.println();
23198                mSettings.dumpReadMessagesLPr(pw, dumpState);
23199
23200                pw.println();
23201                pw.println("Package warning messages:");
23202                BufferedReader in = null;
23203                String line = null;
23204                try {
23205                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23206                    while ((line = in.readLine()) != null) {
23207                        if (line.contains("ignored: updated version")) continue;
23208                        pw.println(line);
23209                    }
23210                } catch (IOException ignored) {
23211                } finally {
23212                    IoUtils.closeQuietly(in);
23213                }
23214            }
23215
23216            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
23217                BufferedReader in = null;
23218                String line = null;
23219                try {
23220                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23221                    while ((line = in.readLine()) != null) {
23222                        if (line.contains("ignored: updated version")) continue;
23223                        pw.print("msg,");
23224                        pw.println(line);
23225                    }
23226                } catch (IOException ignored) {
23227                } finally {
23228                    IoUtils.closeQuietly(in);
23229                }
23230            }
23231        }
23232
23233        // PackageInstaller should be called outside of mPackages lock
23234        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
23235            // XXX should handle packageName != null by dumping only install data that
23236            // the given package is involved with.
23237            if (dumpState.onTitlePrinted()) pw.println();
23238            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
23239        }
23240    }
23241
23242    private void dumpProto(FileDescriptor fd) {
23243        final ProtoOutputStream proto = new ProtoOutputStream(fd);
23244
23245        synchronized (mPackages) {
23246            final long requiredVerifierPackageToken =
23247                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
23248            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
23249            proto.write(
23250                    PackageServiceDumpProto.PackageShortProto.UID,
23251                    getPackageUid(
23252                            mRequiredVerifierPackage,
23253                            MATCH_DEBUG_TRIAGED_MISSING,
23254                            UserHandle.USER_SYSTEM));
23255            proto.end(requiredVerifierPackageToken);
23256
23257            if (mIntentFilterVerifierComponent != null) {
23258                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
23259                final long verifierPackageToken =
23260                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
23261                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
23262                proto.write(
23263                        PackageServiceDumpProto.PackageShortProto.UID,
23264                        getPackageUid(
23265                                verifierPackageName,
23266                                MATCH_DEBUG_TRIAGED_MISSING,
23267                                UserHandle.USER_SYSTEM));
23268                proto.end(verifierPackageToken);
23269            }
23270
23271            dumpSharedLibrariesProto(proto);
23272            dumpFeaturesProto(proto);
23273            mSettings.dumpPackagesProto(proto);
23274            mSettings.dumpSharedUsersProto(proto);
23275            dumpMessagesProto(proto);
23276        }
23277        proto.flush();
23278    }
23279
23280    private void dumpMessagesProto(ProtoOutputStream proto) {
23281        BufferedReader in = null;
23282        String line = null;
23283        try {
23284            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23285            while ((line = in.readLine()) != null) {
23286                if (line.contains("ignored: updated version")) continue;
23287                proto.write(PackageServiceDumpProto.MESSAGES, line);
23288            }
23289        } catch (IOException ignored) {
23290        } finally {
23291            IoUtils.closeQuietly(in);
23292        }
23293    }
23294
23295    private void dumpFeaturesProto(ProtoOutputStream proto) {
23296        synchronized (mAvailableFeatures) {
23297            final int count = mAvailableFeatures.size();
23298            for (int i = 0; i < count; i++) {
23299                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
23300                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
23301                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
23302                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
23303                proto.end(featureToken);
23304            }
23305        }
23306    }
23307
23308    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
23309        final int count = mSharedLibraries.size();
23310        for (int i = 0; i < count; i++) {
23311            final String libName = mSharedLibraries.keyAt(i);
23312            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
23313            if (versionedLib == null) {
23314                continue;
23315            }
23316            final int versionCount = versionedLib.size();
23317            for (int j = 0; j < versionCount; j++) {
23318                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
23319                final long sharedLibraryToken =
23320                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
23321                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
23322                final boolean isJar = (libEntry.path != null);
23323                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
23324                if (isJar) {
23325                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
23326                } else {
23327                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
23328                }
23329                proto.end(sharedLibraryToken);
23330            }
23331        }
23332    }
23333
23334    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
23335        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23336        ipw.println();
23337        ipw.println("Dexopt state:");
23338        ipw.increaseIndent();
23339        Collection<PackageParser.Package> packages = null;
23340        if (packageName != null) {
23341            PackageParser.Package targetPackage = mPackages.get(packageName);
23342            if (targetPackage != null) {
23343                packages = Collections.singletonList(targetPackage);
23344            } else {
23345                ipw.println("Unable to find package: " + packageName);
23346                return;
23347            }
23348        } else {
23349            packages = mPackages.values();
23350        }
23351
23352        for (PackageParser.Package pkg : packages) {
23353            ipw.println("[" + pkg.packageName + "]");
23354            ipw.increaseIndent();
23355            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
23356                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
23357            ipw.decreaseIndent();
23358        }
23359    }
23360
23361    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
23362        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23363        ipw.println();
23364        ipw.println("Compiler stats:");
23365        ipw.increaseIndent();
23366        Collection<PackageParser.Package> packages = null;
23367        if (packageName != null) {
23368            PackageParser.Package targetPackage = mPackages.get(packageName);
23369            if (targetPackage != null) {
23370                packages = Collections.singletonList(targetPackage);
23371            } else {
23372                ipw.println("Unable to find package: " + packageName);
23373                return;
23374            }
23375        } else {
23376            packages = mPackages.values();
23377        }
23378
23379        for (PackageParser.Package pkg : packages) {
23380            ipw.println("[" + pkg.packageName + "]");
23381            ipw.increaseIndent();
23382
23383            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
23384            if (stats == null) {
23385                ipw.println("(No recorded stats)");
23386            } else {
23387                stats.dump(ipw);
23388            }
23389            ipw.decreaseIndent();
23390        }
23391    }
23392
23393    private String dumpDomainString(String packageName) {
23394        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
23395                .getList();
23396        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
23397
23398        ArraySet<String> result = new ArraySet<>();
23399        if (iviList.size() > 0) {
23400            for (IntentFilterVerificationInfo ivi : iviList) {
23401                for (String host : ivi.getDomains()) {
23402                    result.add(host);
23403                }
23404            }
23405        }
23406        if (filters != null && filters.size() > 0) {
23407            for (IntentFilter filter : filters) {
23408                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
23409                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
23410                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
23411                    result.addAll(filter.getHostsList());
23412                }
23413            }
23414        }
23415
23416        StringBuilder sb = new StringBuilder(result.size() * 16);
23417        for (String domain : result) {
23418            if (sb.length() > 0) sb.append(" ");
23419            sb.append(domain);
23420        }
23421        return sb.toString();
23422    }
23423
23424    // ------- apps on sdcard specific code -------
23425    static final boolean DEBUG_SD_INSTALL = false;
23426
23427    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
23428
23429    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
23430
23431    private boolean mMediaMounted = false;
23432
23433    static String getEncryptKey() {
23434        try {
23435            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
23436                    SD_ENCRYPTION_KEYSTORE_NAME);
23437            if (sdEncKey == null) {
23438                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
23439                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
23440                if (sdEncKey == null) {
23441                    Slog.e(TAG, "Failed to create encryption keys");
23442                    return null;
23443                }
23444            }
23445            return sdEncKey;
23446        } catch (NoSuchAlgorithmException nsae) {
23447            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
23448            return null;
23449        } catch (IOException ioe) {
23450            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
23451            return null;
23452        }
23453    }
23454
23455    /*
23456     * Update media status on PackageManager.
23457     */
23458    @Override
23459    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
23460        enforceSystemOrRoot("Media status can only be updated by the system");
23461        // reader; this apparently protects mMediaMounted, but should probably
23462        // be a different lock in that case.
23463        synchronized (mPackages) {
23464            Log.i(TAG, "Updating external media status from "
23465                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
23466                    + (mediaStatus ? "mounted" : "unmounted"));
23467            if (DEBUG_SD_INSTALL)
23468                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
23469                        + ", mMediaMounted=" + mMediaMounted);
23470            if (mediaStatus == mMediaMounted) {
23471                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
23472                        : 0, -1);
23473                mHandler.sendMessage(msg);
23474                return;
23475            }
23476            mMediaMounted = mediaStatus;
23477        }
23478        // Queue up an async operation since the package installation may take a
23479        // little while.
23480        mHandler.post(new Runnable() {
23481            public void run() {
23482                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
23483            }
23484        });
23485    }
23486
23487    /**
23488     * Called by StorageManagerService when the initial ASECs to scan are available.
23489     * Should block until all the ASEC containers are finished being scanned.
23490     */
23491    public void scanAvailableAsecs() {
23492        updateExternalMediaStatusInner(true, false, false);
23493    }
23494
23495    /*
23496     * Collect information of applications on external media, map them against
23497     * existing containers and update information based on current mount status.
23498     * Please note that we always have to report status if reportStatus has been
23499     * set to true especially when unloading packages.
23500     */
23501    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
23502            boolean externalStorage) {
23503        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
23504        int[] uidArr = EmptyArray.INT;
23505
23506        final String[] list = PackageHelper.getSecureContainerList();
23507        if (ArrayUtils.isEmpty(list)) {
23508            Log.i(TAG, "No secure containers found");
23509        } else {
23510            // Process list of secure containers and categorize them
23511            // as active or stale based on their package internal state.
23512
23513            // reader
23514            synchronized (mPackages) {
23515                for (String cid : list) {
23516                    // Leave stages untouched for now; installer service owns them
23517                    if (PackageInstallerService.isStageName(cid)) continue;
23518
23519                    if (DEBUG_SD_INSTALL)
23520                        Log.i(TAG, "Processing container " + cid);
23521                    String pkgName = getAsecPackageName(cid);
23522                    if (pkgName == null) {
23523                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
23524                        continue;
23525                    }
23526                    if (DEBUG_SD_INSTALL)
23527                        Log.i(TAG, "Looking for pkg : " + pkgName);
23528
23529                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
23530                    if (ps == null) {
23531                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23532                        continue;
23533                    }
23534
23535                    /*
23536                     * Skip packages that are not external if we're unmounting
23537                     * external storage.
23538                     */
23539                    if (externalStorage && !isMounted && !isExternal(ps)) {
23540                        continue;
23541                    }
23542
23543                    final AsecInstallArgs args = new AsecInstallArgs(cid,
23544                            getAppDexInstructionSets(ps), ps.isForwardLocked());
23545                    // The package status is changed only if the code path
23546                    // matches between settings and the container id.
23547                    if (ps.codePathString != null
23548                            && ps.codePathString.startsWith(args.getCodePath())) {
23549                        if (DEBUG_SD_INSTALL) {
23550                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23551                                    + " at code path: " + ps.codePathString);
23552                        }
23553
23554                        // We do have a valid package installed on sdcard
23555                        processCids.put(args, ps.codePathString);
23556                        final int uid = ps.appId;
23557                        if (uid != -1) {
23558                            uidArr = ArrayUtils.appendInt(uidArr, uid);
23559                        }
23560                    } else {
23561                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23562                                + ps.codePathString);
23563                    }
23564                }
23565            }
23566
23567            Arrays.sort(uidArr);
23568        }
23569
23570        // Process packages with valid entries.
23571        if (isMounted) {
23572            if (DEBUG_SD_INSTALL)
23573                Log.i(TAG, "Loading packages");
23574            loadMediaPackages(processCids, uidArr, externalStorage);
23575            startCleaningPackages();
23576            mInstallerService.onSecureContainersAvailable();
23577        } else {
23578            if (DEBUG_SD_INSTALL)
23579                Log.i(TAG, "Unloading packages");
23580            unloadMediaPackages(processCids, uidArr, reportStatus);
23581        }
23582    }
23583
23584    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23585            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23586        final int size = infos.size();
23587        final String[] packageNames = new String[size];
23588        final int[] packageUids = new int[size];
23589        for (int i = 0; i < size; i++) {
23590            final ApplicationInfo info = infos.get(i);
23591            packageNames[i] = info.packageName;
23592            packageUids[i] = info.uid;
23593        }
23594        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23595                finishedReceiver);
23596    }
23597
23598    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23599            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23600        sendResourcesChangedBroadcast(mediaStatus, replacing,
23601                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23602    }
23603
23604    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23605            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23606        int size = pkgList.length;
23607        if (size > 0) {
23608            // Send broadcasts here
23609            Bundle extras = new Bundle();
23610            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23611            if (uidArr != null) {
23612                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23613            }
23614            if (replacing) {
23615                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23616            }
23617            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23618                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23619            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23620        }
23621    }
23622
23623   /*
23624     * Look at potentially valid container ids from processCids If package
23625     * information doesn't match the one on record or package scanning fails,
23626     * the cid is added to list of removeCids. We currently don't delete stale
23627     * containers.
23628     */
23629    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23630            boolean externalStorage) {
23631        ArrayList<String> pkgList = new ArrayList<String>();
23632        Set<AsecInstallArgs> keys = processCids.keySet();
23633
23634        for (AsecInstallArgs args : keys) {
23635            String codePath = processCids.get(args);
23636            if (DEBUG_SD_INSTALL)
23637                Log.i(TAG, "Loading container : " + args.cid);
23638            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23639            try {
23640                // Make sure there are no container errors first.
23641                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23642                    Slog.e(TAG, "Failed to mount cid : " + args.cid
23643                            + " when installing from sdcard");
23644                    continue;
23645                }
23646                // Check code path here.
23647                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23648                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23649                            + " does not match one in settings " + codePath);
23650                    continue;
23651                }
23652                // Parse package
23653                int parseFlags = mDefParseFlags;
23654                if (args.isExternalAsec()) {
23655                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23656                }
23657                if (args.isFwdLocked()) {
23658                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23659                }
23660
23661                synchronized (mInstallLock) {
23662                    PackageParser.Package pkg = null;
23663                    try {
23664                        // Sadly we don't know the package name yet to freeze it
23665                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23666                                SCAN_IGNORE_FROZEN, 0, null);
23667                    } catch (PackageManagerException e) {
23668                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23669                    }
23670                    // Scan the package
23671                    if (pkg != null) {
23672                        /*
23673                         * TODO why is the lock being held? doPostInstall is
23674                         * called in other places without the lock. This needs
23675                         * to be straightened out.
23676                         */
23677                        // writer
23678                        synchronized (mPackages) {
23679                            retCode = PackageManager.INSTALL_SUCCEEDED;
23680                            pkgList.add(pkg.packageName);
23681                            // Post process args
23682                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23683                                    pkg.applicationInfo.uid);
23684                        }
23685                    } else {
23686                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
23687                    }
23688                }
23689
23690            } finally {
23691                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23692                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23693                }
23694            }
23695        }
23696        // writer
23697        synchronized (mPackages) {
23698            // If the platform SDK has changed since the last time we booted,
23699            // we need to re-grant app permission to catch any new ones that
23700            // appear. This is really a hack, and means that apps can in some
23701            // cases get permissions that the user didn't initially explicitly
23702            // allow... it would be nice to have some better way to handle
23703            // this situation.
23704            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23705                    : mSettings.getInternalVersion();
23706            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23707                    : StorageManager.UUID_PRIVATE_INTERNAL;
23708
23709            int updateFlags = UPDATE_PERMISSIONS_ALL;
23710            if (ver.sdkVersion != mSdkVersion) {
23711                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23712                        + mSdkVersion + "; regranting permissions for external");
23713                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23714            }
23715            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23716
23717            // Yay, everything is now upgraded
23718            ver.forceCurrent();
23719
23720            // can downgrade to reader
23721            // Persist settings
23722            mSettings.writeLPr();
23723        }
23724        // Send a broadcast to let everyone know we are done processing
23725        if (pkgList.size() > 0) {
23726            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23727        }
23728    }
23729
23730   /*
23731     * Utility method to unload a list of specified containers
23732     */
23733    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23734        // Just unmount all valid containers.
23735        for (AsecInstallArgs arg : cidArgs) {
23736            synchronized (mInstallLock) {
23737                arg.doPostDeleteLI(false);
23738           }
23739       }
23740   }
23741
23742    /*
23743     * Unload packages mounted on external media. This involves deleting package
23744     * data from internal structures, sending broadcasts about disabled packages,
23745     * gc'ing to free up references, unmounting all secure containers
23746     * corresponding to packages on external media, and posting a
23747     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23748     * that we always have to post this message if status has been requested no
23749     * matter what.
23750     */
23751    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23752            final boolean reportStatus) {
23753        if (DEBUG_SD_INSTALL)
23754            Log.i(TAG, "unloading media packages");
23755        ArrayList<String> pkgList = new ArrayList<String>();
23756        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23757        final Set<AsecInstallArgs> keys = processCids.keySet();
23758        for (AsecInstallArgs args : keys) {
23759            String pkgName = args.getPackageName();
23760            if (DEBUG_SD_INSTALL)
23761                Log.i(TAG, "Trying to unload pkg : " + pkgName);
23762            // Delete package internally
23763            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23764            synchronized (mInstallLock) {
23765                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23766                final boolean res;
23767                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23768                        "unloadMediaPackages")) {
23769                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23770                            null);
23771                }
23772                if (res) {
23773                    pkgList.add(pkgName);
23774                } else {
23775                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23776                    failedList.add(args);
23777                }
23778            }
23779        }
23780
23781        // reader
23782        synchronized (mPackages) {
23783            // We didn't update the settings after removing each package;
23784            // write them now for all packages.
23785            mSettings.writeLPr();
23786        }
23787
23788        // We have to absolutely send UPDATED_MEDIA_STATUS only
23789        // after confirming that all the receivers processed the ordered
23790        // broadcast when packages get disabled, force a gc to clean things up.
23791        // and unload all the containers.
23792        if (pkgList.size() > 0) {
23793            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23794                    new IIntentReceiver.Stub() {
23795                public void performReceive(Intent intent, int resultCode, String data,
23796                        Bundle extras, boolean ordered, boolean sticky,
23797                        int sendingUser) throws RemoteException {
23798                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23799                            reportStatus ? 1 : 0, 1, keys);
23800                    mHandler.sendMessage(msg);
23801                }
23802            });
23803        } else {
23804            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23805                    keys);
23806            mHandler.sendMessage(msg);
23807        }
23808    }
23809
23810    private void loadPrivatePackages(final VolumeInfo vol) {
23811        mHandler.post(new Runnable() {
23812            @Override
23813            public void run() {
23814                loadPrivatePackagesInner(vol);
23815            }
23816        });
23817    }
23818
23819    private void loadPrivatePackagesInner(VolumeInfo vol) {
23820        final String volumeUuid = vol.fsUuid;
23821        if (TextUtils.isEmpty(volumeUuid)) {
23822            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23823            return;
23824        }
23825
23826        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23827        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23828        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23829
23830        final VersionInfo ver;
23831        final List<PackageSetting> packages;
23832        synchronized (mPackages) {
23833            ver = mSettings.findOrCreateVersion(volumeUuid);
23834            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23835        }
23836
23837        for (PackageSetting ps : packages) {
23838            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23839            synchronized (mInstallLock) {
23840                final PackageParser.Package pkg;
23841                try {
23842                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23843                    loaded.add(pkg.applicationInfo);
23844
23845                } catch (PackageManagerException e) {
23846                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23847                }
23848
23849                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23850                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23851                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23852                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23853                }
23854            }
23855        }
23856
23857        // Reconcile app data for all started/unlocked users
23858        final StorageManager sm = mContext.getSystemService(StorageManager.class);
23859        final UserManager um = mContext.getSystemService(UserManager.class);
23860        UserManagerInternal umInternal = getUserManagerInternal();
23861        for (UserInfo user : um.getUsers()) {
23862            final int flags;
23863            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23864                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23865            } else if (umInternal.isUserRunning(user.id)) {
23866                flags = StorageManager.FLAG_STORAGE_DE;
23867            } else {
23868                continue;
23869            }
23870
23871            try {
23872                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23873                synchronized (mInstallLock) {
23874                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23875                }
23876            } catch (IllegalStateException e) {
23877                // Device was probably ejected, and we'll process that event momentarily
23878                Slog.w(TAG, "Failed to prepare storage: " + e);
23879            }
23880        }
23881
23882        synchronized (mPackages) {
23883            int updateFlags = UPDATE_PERMISSIONS_ALL;
23884            if (ver.sdkVersion != mSdkVersion) {
23885                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23886                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
23887                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23888            }
23889            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23890
23891            // Yay, everything is now upgraded
23892            ver.forceCurrent();
23893
23894            mSettings.writeLPr();
23895        }
23896
23897        for (PackageFreezer freezer : freezers) {
23898            freezer.close();
23899        }
23900
23901        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23902        sendResourcesChangedBroadcast(true, false, loaded, null);
23903        mLoadedVolumes.add(vol.getId());
23904    }
23905
23906    private void unloadPrivatePackages(final VolumeInfo vol) {
23907        mHandler.post(new Runnable() {
23908            @Override
23909            public void run() {
23910                unloadPrivatePackagesInner(vol);
23911            }
23912        });
23913    }
23914
23915    private void unloadPrivatePackagesInner(VolumeInfo vol) {
23916        final String volumeUuid = vol.fsUuid;
23917        if (TextUtils.isEmpty(volumeUuid)) {
23918            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23919            return;
23920        }
23921
23922        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23923        synchronized (mInstallLock) {
23924        synchronized (mPackages) {
23925            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23926            for (PackageSetting ps : packages) {
23927                if (ps.pkg == null) continue;
23928
23929                final ApplicationInfo info = ps.pkg.applicationInfo;
23930                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23931                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23932
23933                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23934                        "unloadPrivatePackagesInner")) {
23935                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23936                            false, null)) {
23937                        unloaded.add(info);
23938                    } else {
23939                        Slog.w(TAG, "Failed to unload " + ps.codePath);
23940                    }
23941                }
23942
23943                // Try very hard to release any references to this package
23944                // so we don't risk the system server being killed due to
23945                // open FDs
23946                AttributeCache.instance().removePackage(ps.name);
23947            }
23948
23949            mSettings.writeLPr();
23950        }
23951        }
23952
23953        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23954        sendResourcesChangedBroadcast(false, false, unloaded, null);
23955        mLoadedVolumes.remove(vol.getId());
23956
23957        // Try very hard to release any references to this path so we don't risk
23958        // the system server being killed due to open FDs
23959        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23960
23961        for (int i = 0; i < 3; i++) {
23962            System.gc();
23963            System.runFinalization();
23964        }
23965    }
23966
23967    private void assertPackageKnown(String volumeUuid, String packageName)
23968            throws PackageManagerException {
23969        synchronized (mPackages) {
23970            // Normalize package name to handle renamed packages
23971            packageName = normalizePackageNameLPr(packageName);
23972
23973            final PackageSetting ps = mSettings.mPackages.get(packageName);
23974            if (ps == null) {
23975                throw new PackageManagerException("Package " + packageName + " is unknown");
23976            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23977                throw new PackageManagerException(
23978                        "Package " + packageName + " found on unknown volume " + volumeUuid
23979                                + "; expected volume " + ps.volumeUuid);
23980            }
23981        }
23982    }
23983
23984    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23985            throws PackageManagerException {
23986        synchronized (mPackages) {
23987            // Normalize package name to handle renamed packages
23988            packageName = normalizePackageNameLPr(packageName);
23989
23990            final PackageSetting ps = mSettings.mPackages.get(packageName);
23991            if (ps == null) {
23992                throw new PackageManagerException("Package " + packageName + " is unknown");
23993            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23994                throw new PackageManagerException(
23995                        "Package " + packageName + " found on unknown volume " + volumeUuid
23996                                + "; expected volume " + ps.volumeUuid);
23997            } else if (!ps.getInstalled(userId)) {
23998                throw new PackageManagerException(
23999                        "Package " + packageName + " not installed for user " + userId);
24000            }
24001        }
24002    }
24003
24004    private List<String> collectAbsoluteCodePaths() {
24005        synchronized (mPackages) {
24006            List<String> codePaths = new ArrayList<>();
24007            final int packageCount = mSettings.mPackages.size();
24008            for (int i = 0; i < packageCount; i++) {
24009                final PackageSetting ps = mSettings.mPackages.valueAt(i);
24010                codePaths.add(ps.codePath.getAbsolutePath());
24011            }
24012            return codePaths;
24013        }
24014    }
24015
24016    /**
24017     * Examine all apps present on given mounted volume, and destroy apps that
24018     * aren't expected, either due to uninstallation or reinstallation on
24019     * another volume.
24020     */
24021    private void reconcileApps(String volumeUuid) {
24022        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
24023        List<File> filesToDelete = null;
24024
24025        final File[] files = FileUtils.listFilesOrEmpty(
24026                Environment.getDataAppDirectory(volumeUuid));
24027        for (File file : files) {
24028            final boolean isPackage = (isApkFile(file) || file.isDirectory())
24029                    && !PackageInstallerService.isStageName(file.getName());
24030            if (!isPackage) {
24031                // Ignore entries which are not packages
24032                continue;
24033            }
24034
24035            String absolutePath = file.getAbsolutePath();
24036
24037            boolean pathValid = false;
24038            final int absoluteCodePathCount = absoluteCodePaths.size();
24039            for (int i = 0; i < absoluteCodePathCount; i++) {
24040                String absoluteCodePath = absoluteCodePaths.get(i);
24041                if (absolutePath.startsWith(absoluteCodePath)) {
24042                    pathValid = true;
24043                    break;
24044                }
24045            }
24046
24047            if (!pathValid) {
24048                if (filesToDelete == null) {
24049                    filesToDelete = new ArrayList<>();
24050                }
24051                filesToDelete.add(file);
24052            }
24053        }
24054
24055        if (filesToDelete != null) {
24056            final int fileToDeleteCount = filesToDelete.size();
24057            for (int i = 0; i < fileToDeleteCount; i++) {
24058                File fileToDelete = filesToDelete.get(i);
24059                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
24060                synchronized (mInstallLock) {
24061                    removeCodePathLI(fileToDelete);
24062                }
24063            }
24064        }
24065    }
24066
24067    /**
24068     * Reconcile all app data for the given user.
24069     * <p>
24070     * Verifies that directories exist and that ownership and labeling is
24071     * correct for all installed apps on all mounted volumes.
24072     */
24073    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
24074        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24075        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
24076            final String volumeUuid = vol.getFsUuid();
24077            synchronized (mInstallLock) {
24078                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
24079            }
24080        }
24081    }
24082
24083    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24084            boolean migrateAppData) {
24085        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
24086    }
24087
24088    /**
24089     * Reconcile all app data on given mounted volume.
24090     * <p>
24091     * Destroys app data that isn't expected, either due to uninstallation or
24092     * reinstallation on another volume.
24093     * <p>
24094     * Verifies that directories exist and that ownership and labeling is
24095     * correct for all installed apps.
24096     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
24097     */
24098    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
24099            boolean migrateAppData, boolean onlyCoreApps) {
24100        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
24101                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
24102        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
24103
24104        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
24105        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
24106
24107        // First look for stale data that doesn't belong, and check if things
24108        // have changed since we did our last restorecon
24109        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24110            if (StorageManager.isFileEncryptedNativeOrEmulated()
24111                    && !StorageManager.isUserKeyUnlocked(userId)) {
24112                throw new RuntimeException(
24113                        "Yikes, someone asked us to reconcile CE storage while " + userId
24114                                + " was still locked; this would have caused massive data loss!");
24115            }
24116
24117            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
24118            for (File file : files) {
24119                final String packageName = file.getName();
24120                try {
24121                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24122                } catch (PackageManagerException e) {
24123                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24124                    try {
24125                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
24126                                StorageManager.FLAG_STORAGE_CE, 0);
24127                    } catch (InstallerException e2) {
24128                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24129                    }
24130                }
24131            }
24132        }
24133        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
24134            final File[] files = FileUtils.listFilesOrEmpty(deDir);
24135            for (File file : files) {
24136                final String packageName = file.getName();
24137                try {
24138                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
24139                } catch (PackageManagerException e) {
24140                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
24141                    try {
24142                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
24143                                StorageManager.FLAG_STORAGE_DE, 0);
24144                    } catch (InstallerException e2) {
24145                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
24146                    }
24147                }
24148            }
24149        }
24150
24151        // Ensure that data directories are ready to roll for all packages
24152        // installed for this volume and user
24153        final List<PackageSetting> packages;
24154        synchronized (mPackages) {
24155            packages = mSettings.getVolumePackagesLPr(volumeUuid);
24156        }
24157        int preparedCount = 0;
24158        for (PackageSetting ps : packages) {
24159            final String packageName = ps.name;
24160            if (ps.pkg == null) {
24161                Slog.w(TAG, "Odd, missing scanned package " + packageName);
24162                // TODO: might be due to legacy ASEC apps; we should circle back
24163                // and reconcile again once they're scanned
24164                continue;
24165            }
24166            // Skip non-core apps if requested
24167            if (onlyCoreApps && !ps.pkg.coreApp) {
24168                result.add(packageName);
24169                continue;
24170            }
24171
24172            if (ps.getInstalled(userId)) {
24173                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
24174                preparedCount++;
24175            }
24176        }
24177
24178        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
24179        return result;
24180    }
24181
24182    /**
24183     * Prepare app data for the given app just after it was installed or
24184     * upgraded. This method carefully only touches users that it's installed
24185     * for, and it forces a restorecon to handle any seinfo changes.
24186     * <p>
24187     * Verifies that directories exist and that ownership and labeling is
24188     * correct for all installed apps. If there is an ownership mismatch, it
24189     * will try recovering system apps by wiping data; third-party app data is
24190     * left intact.
24191     * <p>
24192     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
24193     */
24194    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
24195        final PackageSetting ps;
24196        synchronized (mPackages) {
24197            ps = mSettings.mPackages.get(pkg.packageName);
24198            mSettings.writeKernelMappingLPr(ps);
24199        }
24200
24201        final UserManager um = mContext.getSystemService(UserManager.class);
24202        UserManagerInternal umInternal = getUserManagerInternal();
24203        for (UserInfo user : um.getUsers()) {
24204            final int flags;
24205            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
24206                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
24207            } else if (umInternal.isUserRunning(user.id)) {
24208                flags = StorageManager.FLAG_STORAGE_DE;
24209            } else {
24210                continue;
24211            }
24212
24213            if (ps.getInstalled(user.id)) {
24214                // TODO: when user data is locked, mark that we're still dirty
24215                prepareAppDataLIF(pkg, user.id, flags);
24216            }
24217        }
24218    }
24219
24220    /**
24221     * Prepare app data for the given app.
24222     * <p>
24223     * Verifies that directories exist and that ownership and labeling is
24224     * correct for all installed apps. If there is an ownership mismatch, this
24225     * will try recovering system apps by wiping data; third-party app data is
24226     * left intact.
24227     */
24228    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
24229        if (pkg == null) {
24230            Slog.wtf(TAG, "Package was null!", new Throwable());
24231            return;
24232        }
24233        prepareAppDataLeafLIF(pkg, userId, flags);
24234        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24235        for (int i = 0; i < childCount; i++) {
24236            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
24237        }
24238    }
24239
24240    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
24241            boolean maybeMigrateAppData) {
24242        prepareAppDataLIF(pkg, userId, flags);
24243
24244        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
24245            // We may have just shuffled around app data directories, so
24246            // prepare them one more time
24247            prepareAppDataLIF(pkg, userId, flags);
24248        }
24249    }
24250
24251    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24252        if (DEBUG_APP_DATA) {
24253            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
24254                    + Integer.toHexString(flags));
24255        }
24256
24257        final String volumeUuid = pkg.volumeUuid;
24258        final String packageName = pkg.packageName;
24259        final ApplicationInfo app = pkg.applicationInfo;
24260        final int appId = UserHandle.getAppId(app.uid);
24261
24262        Preconditions.checkNotNull(app.seInfo);
24263
24264        long ceDataInode = -1;
24265        try {
24266            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24267                    appId, app.seInfo, app.targetSdkVersion);
24268        } catch (InstallerException e) {
24269            if (app.isSystemApp()) {
24270                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
24271                        + ", but trying to recover: " + e);
24272                destroyAppDataLeafLIF(pkg, userId, flags);
24273                try {
24274                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24275                            appId, app.seInfo, app.targetSdkVersion);
24276                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
24277                } catch (InstallerException e2) {
24278                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
24279                }
24280            } else {
24281                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
24282            }
24283        }
24284
24285        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
24286            // TODO: mark this structure as dirty so we persist it!
24287            synchronized (mPackages) {
24288                final PackageSetting ps = mSettings.mPackages.get(packageName);
24289                if (ps != null) {
24290                    ps.setCeDataInode(ceDataInode, userId);
24291                }
24292            }
24293        }
24294
24295        prepareAppDataContentsLeafLIF(pkg, userId, flags);
24296    }
24297
24298    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
24299        if (pkg == null) {
24300            Slog.wtf(TAG, "Package was null!", new Throwable());
24301            return;
24302        }
24303        prepareAppDataContentsLeafLIF(pkg, userId, flags);
24304        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24305        for (int i = 0; i < childCount; i++) {
24306            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
24307        }
24308    }
24309
24310    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24311        final String volumeUuid = pkg.volumeUuid;
24312        final String packageName = pkg.packageName;
24313        final ApplicationInfo app = pkg.applicationInfo;
24314
24315        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24316            // Create a native library symlink only if we have native libraries
24317            // and if the native libraries are 32 bit libraries. We do not provide
24318            // this symlink for 64 bit libraries.
24319            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
24320                final String nativeLibPath = app.nativeLibraryDir;
24321                try {
24322                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
24323                            nativeLibPath, userId);
24324                } catch (InstallerException e) {
24325                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
24326                }
24327            }
24328        }
24329    }
24330
24331    /**
24332     * For system apps on non-FBE devices, this method migrates any existing
24333     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
24334     * requested by the app.
24335     */
24336    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
24337        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
24338                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
24339            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
24340                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
24341            try {
24342                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
24343                        storageTarget);
24344            } catch (InstallerException e) {
24345                logCriticalInfo(Log.WARN,
24346                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
24347            }
24348            return true;
24349        } else {
24350            return false;
24351        }
24352    }
24353
24354    public PackageFreezer freezePackage(String packageName, String killReason) {
24355        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
24356    }
24357
24358    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
24359        return new PackageFreezer(packageName, userId, killReason);
24360    }
24361
24362    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
24363            String killReason) {
24364        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
24365    }
24366
24367    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
24368            String killReason) {
24369        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
24370            return new PackageFreezer();
24371        } else {
24372            return freezePackage(packageName, userId, killReason);
24373        }
24374    }
24375
24376    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
24377            String killReason) {
24378        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
24379    }
24380
24381    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
24382            String killReason) {
24383        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
24384            return new PackageFreezer();
24385        } else {
24386            return freezePackage(packageName, userId, killReason);
24387        }
24388    }
24389
24390    /**
24391     * Class that freezes and kills the given package upon creation, and
24392     * unfreezes it upon closing. This is typically used when doing surgery on
24393     * app code/data to prevent the app from running while you're working.
24394     */
24395    private class PackageFreezer implements AutoCloseable {
24396        private final String mPackageName;
24397        private final PackageFreezer[] mChildren;
24398
24399        private final boolean mWeFroze;
24400
24401        private final AtomicBoolean mClosed = new AtomicBoolean();
24402        private final CloseGuard mCloseGuard = CloseGuard.get();
24403
24404        /**
24405         * Create and return a stub freezer that doesn't actually do anything,
24406         * typically used when someone requested
24407         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
24408         * {@link PackageManager#DELETE_DONT_KILL_APP}.
24409         */
24410        public PackageFreezer() {
24411            mPackageName = null;
24412            mChildren = null;
24413            mWeFroze = false;
24414            mCloseGuard.open("close");
24415        }
24416
24417        public PackageFreezer(String packageName, int userId, String killReason) {
24418            synchronized (mPackages) {
24419                mPackageName = packageName;
24420                mWeFroze = mFrozenPackages.add(mPackageName);
24421
24422                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
24423                if (ps != null) {
24424                    killApplication(ps.name, ps.appId, userId, killReason);
24425                }
24426
24427                final PackageParser.Package p = mPackages.get(packageName);
24428                if (p != null && p.childPackages != null) {
24429                    final int N = p.childPackages.size();
24430                    mChildren = new PackageFreezer[N];
24431                    for (int i = 0; i < N; i++) {
24432                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
24433                                userId, killReason);
24434                    }
24435                } else {
24436                    mChildren = null;
24437                }
24438            }
24439            mCloseGuard.open("close");
24440        }
24441
24442        @Override
24443        protected void finalize() throws Throwable {
24444            try {
24445                if (mCloseGuard != null) {
24446                    mCloseGuard.warnIfOpen();
24447                }
24448
24449                close();
24450            } finally {
24451                super.finalize();
24452            }
24453        }
24454
24455        @Override
24456        public void close() {
24457            mCloseGuard.close();
24458            if (mClosed.compareAndSet(false, true)) {
24459                synchronized (mPackages) {
24460                    if (mWeFroze) {
24461                        mFrozenPackages.remove(mPackageName);
24462                    }
24463
24464                    if (mChildren != null) {
24465                        for (PackageFreezer freezer : mChildren) {
24466                            freezer.close();
24467                        }
24468                    }
24469                }
24470            }
24471        }
24472    }
24473
24474    /**
24475     * Verify that given package is currently frozen.
24476     */
24477    private void checkPackageFrozen(String packageName) {
24478        synchronized (mPackages) {
24479            if (!mFrozenPackages.contains(packageName)) {
24480                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
24481            }
24482        }
24483    }
24484
24485    @Override
24486    public int movePackage(final String packageName, final String volumeUuid) {
24487        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24488
24489        final int callingUid = Binder.getCallingUid();
24490        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
24491        final int moveId = mNextMoveId.getAndIncrement();
24492        mHandler.post(new Runnable() {
24493            @Override
24494            public void run() {
24495                try {
24496                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
24497                } catch (PackageManagerException e) {
24498                    Slog.w(TAG, "Failed to move " + packageName, e);
24499                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
24500                }
24501            }
24502        });
24503        return moveId;
24504    }
24505
24506    private void movePackageInternal(final String packageName, final String volumeUuid,
24507            final int moveId, final int callingUid, UserHandle user)
24508                    throws PackageManagerException {
24509        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24510        final PackageManager pm = mContext.getPackageManager();
24511
24512        final boolean currentAsec;
24513        final String currentVolumeUuid;
24514        final File codeFile;
24515        final String installerPackageName;
24516        final String packageAbiOverride;
24517        final int appId;
24518        final String seinfo;
24519        final String label;
24520        final int targetSdkVersion;
24521        final PackageFreezer freezer;
24522        final int[] installedUserIds;
24523
24524        // reader
24525        synchronized (mPackages) {
24526            final PackageParser.Package pkg = mPackages.get(packageName);
24527            final PackageSetting ps = mSettings.mPackages.get(packageName);
24528            if (pkg == null
24529                    || ps == null
24530                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24531                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24532            }
24533            if (pkg.applicationInfo.isSystemApp()) {
24534                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24535                        "Cannot move system application");
24536            }
24537
24538            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24539            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24540                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24541            if (isInternalStorage && !allow3rdPartyOnInternal) {
24542                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24543                        "3rd party apps are not allowed on internal storage");
24544            }
24545
24546            if (pkg.applicationInfo.isExternalAsec()) {
24547                currentAsec = true;
24548                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24549            } else if (pkg.applicationInfo.isForwardLocked()) {
24550                currentAsec = true;
24551                currentVolumeUuid = "forward_locked";
24552            } else {
24553                currentAsec = false;
24554                currentVolumeUuid = ps.volumeUuid;
24555
24556                final File probe = new File(pkg.codePath);
24557                final File probeOat = new File(probe, "oat");
24558                if (!probe.isDirectory() || !probeOat.isDirectory()) {
24559                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24560                            "Move only supported for modern cluster style installs");
24561                }
24562            }
24563
24564            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24565                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24566                        "Package already moved to " + volumeUuid);
24567            }
24568            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24569                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24570                        "Device admin cannot be moved");
24571            }
24572
24573            if (mFrozenPackages.contains(packageName)) {
24574                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24575                        "Failed to move already frozen package");
24576            }
24577
24578            codeFile = new File(pkg.codePath);
24579            installerPackageName = ps.installerPackageName;
24580            packageAbiOverride = ps.cpuAbiOverrideString;
24581            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24582            seinfo = pkg.applicationInfo.seInfo;
24583            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24584            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24585            freezer = freezePackage(packageName, "movePackageInternal");
24586            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24587        }
24588
24589        final Bundle extras = new Bundle();
24590        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24591        extras.putString(Intent.EXTRA_TITLE, label);
24592        mMoveCallbacks.notifyCreated(moveId, extras);
24593
24594        int installFlags;
24595        final boolean moveCompleteApp;
24596        final File measurePath;
24597
24598        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24599            installFlags = INSTALL_INTERNAL;
24600            moveCompleteApp = !currentAsec;
24601            measurePath = Environment.getDataAppDirectory(volumeUuid);
24602        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24603            installFlags = INSTALL_EXTERNAL;
24604            moveCompleteApp = false;
24605            measurePath = storage.getPrimaryPhysicalVolume().getPath();
24606        } else {
24607            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24608            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24609                    || !volume.isMountedWritable()) {
24610                freezer.close();
24611                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24612                        "Move location not mounted private volume");
24613            }
24614
24615            Preconditions.checkState(!currentAsec);
24616
24617            installFlags = INSTALL_INTERNAL;
24618            moveCompleteApp = true;
24619            measurePath = Environment.getDataAppDirectory(volumeUuid);
24620        }
24621
24622        // If we're moving app data around, we need all the users unlocked
24623        if (moveCompleteApp) {
24624            for (int userId : installedUserIds) {
24625                if (StorageManager.isFileEncryptedNativeOrEmulated()
24626                        && !StorageManager.isUserKeyUnlocked(userId)) {
24627                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24628                            "User " + userId + " must be unlocked");
24629                }
24630            }
24631        }
24632
24633        final PackageStats stats = new PackageStats(null, -1);
24634        synchronized (mInstaller) {
24635            for (int userId : installedUserIds) {
24636                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24637                    freezer.close();
24638                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24639                            "Failed to measure package size");
24640                }
24641            }
24642        }
24643
24644        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24645                + stats.dataSize);
24646
24647        final long startFreeBytes = measurePath.getUsableSpace();
24648        final long sizeBytes;
24649        if (moveCompleteApp) {
24650            sizeBytes = stats.codeSize + stats.dataSize;
24651        } else {
24652            sizeBytes = stats.codeSize;
24653        }
24654
24655        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24656            freezer.close();
24657            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24658                    "Not enough free space to move");
24659        }
24660
24661        mMoveCallbacks.notifyStatusChanged(moveId, 10);
24662
24663        final CountDownLatch installedLatch = new CountDownLatch(1);
24664        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24665            @Override
24666            public void onUserActionRequired(Intent intent) throws RemoteException {
24667                throw new IllegalStateException();
24668            }
24669
24670            @Override
24671            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24672                    Bundle extras) throws RemoteException {
24673                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24674                        + PackageManager.installStatusToString(returnCode, msg));
24675
24676                installedLatch.countDown();
24677                freezer.close();
24678
24679                final int status = PackageManager.installStatusToPublicStatus(returnCode);
24680                switch (status) {
24681                    case PackageInstaller.STATUS_SUCCESS:
24682                        mMoveCallbacks.notifyStatusChanged(moveId,
24683                                PackageManager.MOVE_SUCCEEDED);
24684                        break;
24685                    case PackageInstaller.STATUS_FAILURE_STORAGE:
24686                        mMoveCallbacks.notifyStatusChanged(moveId,
24687                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24688                        break;
24689                    default:
24690                        mMoveCallbacks.notifyStatusChanged(moveId,
24691                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24692                        break;
24693                }
24694            }
24695        };
24696
24697        final MoveInfo move;
24698        if (moveCompleteApp) {
24699            // Kick off a thread to report progress estimates
24700            new Thread() {
24701                @Override
24702                public void run() {
24703                    while (true) {
24704                        try {
24705                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
24706                                break;
24707                            }
24708                        } catch (InterruptedException ignored) {
24709                        }
24710
24711                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24712                        final int progress = 10 + (int) MathUtils.constrain(
24713                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24714                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
24715                    }
24716                }
24717            }.start();
24718
24719            final String dataAppName = codeFile.getName();
24720            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24721                    dataAppName, appId, seinfo, targetSdkVersion);
24722        } else {
24723            move = null;
24724        }
24725
24726        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24727
24728        final Message msg = mHandler.obtainMessage(INIT_COPY);
24729        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24730        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24731                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24732                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24733                PackageManager.INSTALL_REASON_UNKNOWN);
24734        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24735        msg.obj = params;
24736
24737        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24738                System.identityHashCode(msg.obj));
24739        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24740                System.identityHashCode(msg.obj));
24741
24742        mHandler.sendMessage(msg);
24743    }
24744
24745    @Override
24746    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24747        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24748
24749        final int realMoveId = mNextMoveId.getAndIncrement();
24750        final Bundle extras = new Bundle();
24751        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24752        mMoveCallbacks.notifyCreated(realMoveId, extras);
24753
24754        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24755            @Override
24756            public void onCreated(int moveId, Bundle extras) {
24757                // Ignored
24758            }
24759
24760            @Override
24761            public void onStatusChanged(int moveId, int status, long estMillis) {
24762                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24763            }
24764        };
24765
24766        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24767        storage.setPrimaryStorageUuid(volumeUuid, callback);
24768        return realMoveId;
24769    }
24770
24771    @Override
24772    public int getMoveStatus(int moveId) {
24773        mContext.enforceCallingOrSelfPermission(
24774                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24775        return mMoveCallbacks.mLastStatus.get(moveId);
24776    }
24777
24778    @Override
24779    public void registerMoveCallback(IPackageMoveObserver callback) {
24780        mContext.enforceCallingOrSelfPermission(
24781                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24782        mMoveCallbacks.register(callback);
24783    }
24784
24785    @Override
24786    public void unregisterMoveCallback(IPackageMoveObserver callback) {
24787        mContext.enforceCallingOrSelfPermission(
24788                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24789        mMoveCallbacks.unregister(callback);
24790    }
24791
24792    @Override
24793    public boolean setInstallLocation(int loc) {
24794        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24795                null);
24796        if (getInstallLocation() == loc) {
24797            return true;
24798        }
24799        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24800                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24801            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24802                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24803            return true;
24804        }
24805        return false;
24806   }
24807
24808    @Override
24809    public int getInstallLocation() {
24810        // allow instant app access
24811        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24812                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24813                PackageHelper.APP_INSTALL_AUTO);
24814    }
24815
24816    /** Called by UserManagerService */
24817    void cleanUpUser(UserManagerService userManager, int userHandle) {
24818        synchronized (mPackages) {
24819            mDirtyUsers.remove(userHandle);
24820            mUserNeedsBadging.delete(userHandle);
24821            mSettings.removeUserLPw(userHandle);
24822            mPendingBroadcasts.remove(userHandle);
24823            mInstantAppRegistry.onUserRemovedLPw(userHandle);
24824            removeUnusedPackagesLPw(userManager, userHandle);
24825        }
24826    }
24827
24828    /**
24829     * We're removing userHandle and would like to remove any downloaded packages
24830     * that are no longer in use by any other user.
24831     * @param userHandle the user being removed
24832     */
24833    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24834        final boolean DEBUG_CLEAN_APKS = false;
24835        int [] users = userManager.getUserIds();
24836        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24837        while (psit.hasNext()) {
24838            PackageSetting ps = psit.next();
24839            if (ps.pkg == null) {
24840                continue;
24841            }
24842            final String packageName = ps.pkg.packageName;
24843            // Skip over if system app
24844            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24845                continue;
24846            }
24847            if (DEBUG_CLEAN_APKS) {
24848                Slog.i(TAG, "Checking package " + packageName);
24849            }
24850            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24851            if (keep) {
24852                if (DEBUG_CLEAN_APKS) {
24853                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
24854                }
24855            } else {
24856                for (int i = 0; i < users.length; i++) {
24857                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
24858                        keep = true;
24859                        if (DEBUG_CLEAN_APKS) {
24860                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
24861                                    + users[i]);
24862                        }
24863                        break;
24864                    }
24865                }
24866            }
24867            if (!keep) {
24868                if (DEBUG_CLEAN_APKS) {
24869                    Slog.i(TAG, "  Removing package " + packageName);
24870                }
24871                mHandler.post(new Runnable() {
24872                    public void run() {
24873                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24874                                userHandle, 0);
24875                    } //end run
24876                });
24877            }
24878        }
24879    }
24880
24881    /** Called by UserManagerService */
24882    void createNewUser(int userId, String[] disallowedPackages) {
24883        synchronized (mInstallLock) {
24884            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24885        }
24886        synchronized (mPackages) {
24887            scheduleWritePackageRestrictionsLocked(userId);
24888            scheduleWritePackageListLocked(userId);
24889            applyFactoryDefaultBrowserLPw(userId);
24890            primeDomainVerificationsLPw(userId);
24891        }
24892    }
24893
24894    void onNewUserCreated(final int userId) {
24895        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
24896        // If permission review for legacy apps is required, we represent
24897        // dagerous permissions for such apps as always granted runtime
24898        // permissions to keep per user flag state whether review is needed.
24899        // Hence, if a new user is added we have to propagate dangerous
24900        // permission grants for these legacy apps.
24901        if (mPermissionReviewRequired) {
24902            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
24903                    | UPDATE_PERMISSIONS_REPLACE_ALL);
24904        }
24905    }
24906
24907    @Override
24908    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
24909        mContext.enforceCallingOrSelfPermission(
24910                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24911                "Only package verification agents can read the verifier device identity");
24912
24913        synchronized (mPackages) {
24914            return mSettings.getVerifierDeviceIdentityLPw();
24915        }
24916    }
24917
24918    @Override
24919    public void setPermissionEnforced(String permission, boolean enforced) {
24920        // TODO: Now that we no longer change GID for storage, this should to away.
24921        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24922                "setPermissionEnforced");
24923        if (READ_EXTERNAL_STORAGE.equals(permission)) {
24924            synchronized (mPackages) {
24925                if (mSettings.mReadExternalStorageEnforced == null
24926                        || mSettings.mReadExternalStorageEnforced != enforced) {
24927                    mSettings.mReadExternalStorageEnforced = enforced;
24928                    mSettings.writeLPr();
24929                }
24930            }
24931            // kill any non-foreground processes so we restart them and
24932            // grant/revoke the GID.
24933            final IActivityManager am = ActivityManager.getService();
24934            if (am != null) {
24935                final long token = Binder.clearCallingIdentity();
24936                try {
24937                    am.killProcessesBelowForeground("setPermissionEnforcement");
24938                } catch (RemoteException e) {
24939                } finally {
24940                    Binder.restoreCallingIdentity(token);
24941                }
24942            }
24943        } else {
24944            throw new IllegalArgumentException("No selective enforcement for " + permission);
24945        }
24946    }
24947
24948    @Override
24949    @Deprecated
24950    public boolean isPermissionEnforced(String permission) {
24951        // allow instant applications
24952        return true;
24953    }
24954
24955    @Override
24956    public boolean isStorageLow() {
24957        // allow instant applications
24958        final long token = Binder.clearCallingIdentity();
24959        try {
24960            final DeviceStorageMonitorInternal
24961                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24962            if (dsm != null) {
24963                return dsm.isMemoryLow();
24964            } else {
24965                return false;
24966            }
24967        } finally {
24968            Binder.restoreCallingIdentity(token);
24969        }
24970    }
24971
24972    @Override
24973    public IPackageInstaller getPackageInstaller() {
24974        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24975            return null;
24976        }
24977        return mInstallerService;
24978    }
24979
24980    private boolean userNeedsBadging(int userId) {
24981        int index = mUserNeedsBadging.indexOfKey(userId);
24982        if (index < 0) {
24983            final UserInfo userInfo;
24984            final long token = Binder.clearCallingIdentity();
24985            try {
24986                userInfo = sUserManager.getUserInfo(userId);
24987            } finally {
24988                Binder.restoreCallingIdentity(token);
24989            }
24990            final boolean b;
24991            if (userInfo != null && userInfo.isManagedProfile()) {
24992                b = true;
24993            } else {
24994                b = false;
24995            }
24996            mUserNeedsBadging.put(userId, b);
24997            return b;
24998        }
24999        return mUserNeedsBadging.valueAt(index);
25000    }
25001
25002    @Override
25003    public KeySet getKeySetByAlias(String packageName, String alias) {
25004        if (packageName == null || alias == null) {
25005            return null;
25006        }
25007        synchronized(mPackages) {
25008            final PackageParser.Package pkg = mPackages.get(packageName);
25009            if (pkg == null) {
25010                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25011                throw new IllegalArgumentException("Unknown package: " + packageName);
25012            }
25013            final PackageSetting ps = (PackageSetting) pkg.mExtras;
25014            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
25015                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
25016                throw new IllegalArgumentException("Unknown package: " + packageName);
25017            }
25018            KeySetManagerService ksms = mSettings.mKeySetManagerService;
25019            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
25020        }
25021    }
25022
25023    @Override
25024    public KeySet getSigningKeySet(String packageName) {
25025        if (packageName == null) {
25026            return null;
25027        }
25028        synchronized(mPackages) {
25029            final int callingUid = Binder.getCallingUid();
25030            final int callingUserId = UserHandle.getUserId(callingUid);
25031            final PackageParser.Package pkg = mPackages.get(packageName);
25032            if (pkg == null) {
25033                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25034                throw new IllegalArgumentException("Unknown package: " + packageName);
25035            }
25036            final PackageSetting ps = (PackageSetting) pkg.mExtras;
25037            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
25038                // filter and pretend the package doesn't exist
25039                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
25040                        + ", uid:" + callingUid);
25041                throw new IllegalArgumentException("Unknown package: " + packageName);
25042            }
25043            if (pkg.applicationInfo.uid != callingUid
25044                    && Process.SYSTEM_UID != callingUid) {
25045                throw new SecurityException("May not access signing KeySet of other apps.");
25046            }
25047            KeySetManagerService ksms = mSettings.mKeySetManagerService;
25048            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
25049        }
25050    }
25051
25052    @Override
25053    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
25054        final int callingUid = Binder.getCallingUid();
25055        if (getInstantAppPackageName(callingUid) != null) {
25056            return false;
25057        }
25058        if (packageName == null || ks == null) {
25059            return false;
25060        }
25061        synchronized(mPackages) {
25062            final PackageParser.Package pkg = mPackages.get(packageName);
25063            if (pkg == null
25064                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25065                            UserHandle.getUserId(callingUid))) {
25066                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25067                throw new IllegalArgumentException("Unknown package: " + packageName);
25068            }
25069            IBinder ksh = ks.getToken();
25070            if (ksh instanceof KeySetHandle) {
25071                KeySetManagerService ksms = mSettings.mKeySetManagerService;
25072                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
25073            }
25074            return false;
25075        }
25076    }
25077
25078    @Override
25079    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
25080        final int callingUid = Binder.getCallingUid();
25081        if (getInstantAppPackageName(callingUid) != null) {
25082            return false;
25083        }
25084        if (packageName == null || ks == null) {
25085            return false;
25086        }
25087        synchronized(mPackages) {
25088            final PackageParser.Package pkg = mPackages.get(packageName);
25089            if (pkg == null
25090                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
25091                            UserHandle.getUserId(callingUid))) {
25092                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
25093                throw new IllegalArgumentException("Unknown package: " + packageName);
25094            }
25095            IBinder ksh = ks.getToken();
25096            if (ksh instanceof KeySetHandle) {
25097                KeySetManagerService ksms = mSettings.mKeySetManagerService;
25098                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
25099            }
25100            return false;
25101        }
25102    }
25103
25104    private void deletePackageIfUnusedLPr(final String packageName) {
25105        PackageSetting ps = mSettings.mPackages.get(packageName);
25106        if (ps == null) {
25107            return;
25108        }
25109        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
25110            // TODO Implement atomic delete if package is unused
25111            // It is currently possible that the package will be deleted even if it is installed
25112            // after this method returns.
25113            mHandler.post(new Runnable() {
25114                public void run() {
25115                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
25116                            0, PackageManager.DELETE_ALL_USERS);
25117                }
25118            });
25119        }
25120    }
25121
25122    /**
25123     * Check and throw if the given before/after packages would be considered a
25124     * downgrade.
25125     */
25126    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
25127            throws PackageManagerException {
25128        if (after.versionCode < before.mVersionCode) {
25129            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25130                    "Update version code " + after.versionCode + " is older than current "
25131                    + before.mVersionCode);
25132        } else if (after.versionCode == before.mVersionCode) {
25133            if (after.baseRevisionCode < before.baseRevisionCode) {
25134                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25135                        "Update base revision code " + after.baseRevisionCode
25136                        + " is older than current " + before.baseRevisionCode);
25137            }
25138
25139            if (!ArrayUtils.isEmpty(after.splitNames)) {
25140                for (int i = 0; i < after.splitNames.length; i++) {
25141                    final String splitName = after.splitNames[i];
25142                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
25143                    if (j != -1) {
25144                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
25145                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
25146                                    "Update split " + splitName + " revision code "
25147                                    + after.splitRevisionCodes[i] + " is older than current "
25148                                    + before.splitRevisionCodes[j]);
25149                        }
25150                    }
25151                }
25152            }
25153        }
25154    }
25155
25156    private static class MoveCallbacks extends Handler {
25157        private static final int MSG_CREATED = 1;
25158        private static final int MSG_STATUS_CHANGED = 2;
25159
25160        private final RemoteCallbackList<IPackageMoveObserver>
25161                mCallbacks = new RemoteCallbackList<>();
25162
25163        private final SparseIntArray mLastStatus = new SparseIntArray();
25164
25165        public MoveCallbacks(Looper looper) {
25166            super(looper);
25167        }
25168
25169        public void register(IPackageMoveObserver callback) {
25170            mCallbacks.register(callback);
25171        }
25172
25173        public void unregister(IPackageMoveObserver callback) {
25174            mCallbacks.unregister(callback);
25175        }
25176
25177        @Override
25178        public void handleMessage(Message msg) {
25179            final SomeArgs args = (SomeArgs) msg.obj;
25180            final int n = mCallbacks.beginBroadcast();
25181            for (int i = 0; i < n; i++) {
25182                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
25183                try {
25184                    invokeCallback(callback, msg.what, args);
25185                } catch (RemoteException ignored) {
25186                }
25187            }
25188            mCallbacks.finishBroadcast();
25189            args.recycle();
25190        }
25191
25192        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
25193                throws RemoteException {
25194            switch (what) {
25195                case MSG_CREATED: {
25196                    callback.onCreated(args.argi1, (Bundle) args.arg2);
25197                    break;
25198                }
25199                case MSG_STATUS_CHANGED: {
25200                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
25201                    break;
25202                }
25203            }
25204        }
25205
25206        private void notifyCreated(int moveId, Bundle extras) {
25207            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
25208
25209            final SomeArgs args = SomeArgs.obtain();
25210            args.argi1 = moveId;
25211            args.arg2 = extras;
25212            obtainMessage(MSG_CREATED, args).sendToTarget();
25213        }
25214
25215        private void notifyStatusChanged(int moveId, int status) {
25216            notifyStatusChanged(moveId, status, -1);
25217        }
25218
25219        private void notifyStatusChanged(int moveId, int status, long estMillis) {
25220            Slog.v(TAG, "Move " + moveId + " status " + status);
25221
25222            final SomeArgs args = SomeArgs.obtain();
25223            args.argi1 = moveId;
25224            args.argi2 = status;
25225            args.arg3 = estMillis;
25226            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
25227
25228            synchronized (mLastStatus) {
25229                mLastStatus.put(moveId, status);
25230            }
25231        }
25232    }
25233
25234    private final static class OnPermissionChangeListeners extends Handler {
25235        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
25236
25237        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
25238                new RemoteCallbackList<>();
25239
25240        public OnPermissionChangeListeners(Looper looper) {
25241            super(looper);
25242        }
25243
25244        @Override
25245        public void handleMessage(Message msg) {
25246            switch (msg.what) {
25247                case MSG_ON_PERMISSIONS_CHANGED: {
25248                    final int uid = msg.arg1;
25249                    handleOnPermissionsChanged(uid);
25250                } break;
25251            }
25252        }
25253
25254        public void addListenerLocked(IOnPermissionsChangeListener listener) {
25255            mPermissionListeners.register(listener);
25256
25257        }
25258
25259        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
25260            mPermissionListeners.unregister(listener);
25261        }
25262
25263        public void onPermissionsChanged(int uid) {
25264            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
25265                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
25266            }
25267        }
25268
25269        private void handleOnPermissionsChanged(int uid) {
25270            final int count = mPermissionListeners.beginBroadcast();
25271            try {
25272                for (int i = 0; i < count; i++) {
25273                    IOnPermissionsChangeListener callback = mPermissionListeners
25274                            .getBroadcastItem(i);
25275                    try {
25276                        callback.onPermissionsChanged(uid);
25277                    } catch (RemoteException e) {
25278                        Log.e(TAG, "Permission listener is dead", e);
25279                    }
25280                }
25281            } finally {
25282                mPermissionListeners.finishBroadcast();
25283            }
25284        }
25285    }
25286
25287    private class PackageManagerNative extends IPackageManagerNative.Stub {
25288        @Override
25289        public String[] getNamesForUids(int[] uids) throws RemoteException {
25290            final String[] results = PackageManagerService.this.getNamesForUids(uids);
25291            // massage results so they can be parsed by the native binder
25292            for (int i = results.length - 1; i >= 0; --i) {
25293                if (results[i] == null) {
25294                    results[i] = "";
25295                }
25296            }
25297            return results;
25298        }
25299
25300        // NB: this differentiates between preloads and sideloads
25301        @Override
25302        public String getInstallerForPackage(String packageName) throws RemoteException {
25303            final String installerName = getInstallerPackageName(packageName);
25304            if (!TextUtils.isEmpty(installerName)) {
25305                return installerName;
25306            }
25307            // differentiate between preload and sideload
25308            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25309            ApplicationInfo appInfo = getApplicationInfo(packageName,
25310                                    /*flags*/ 0,
25311                                    /*userId*/ callingUser);
25312            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
25313                return "preload";
25314            }
25315            return "";
25316        }
25317
25318        @Override
25319        public int getVersionCodeForPackage(String packageName) throws RemoteException {
25320            try {
25321                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
25322                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
25323                if (pInfo != null) {
25324                    return pInfo.versionCode;
25325                }
25326            } catch (Exception e) {
25327            }
25328            return 0;
25329        }
25330    }
25331
25332    private class PackageManagerInternalImpl extends PackageManagerInternal {
25333        @Override
25334        public void setLocationPackagesProvider(PackagesProvider provider) {
25335            synchronized (mPackages) {
25336                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
25337            }
25338        }
25339
25340        @Override
25341        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
25342            synchronized (mPackages) {
25343                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
25344            }
25345        }
25346
25347        @Override
25348        public void setSmsAppPackagesProvider(PackagesProvider provider) {
25349            synchronized (mPackages) {
25350                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
25351            }
25352        }
25353
25354        @Override
25355        public void setDialerAppPackagesProvider(PackagesProvider provider) {
25356            synchronized (mPackages) {
25357                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
25358            }
25359        }
25360
25361        @Override
25362        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
25363            synchronized (mPackages) {
25364                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
25365            }
25366        }
25367
25368        @Override
25369        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
25370            synchronized (mPackages) {
25371                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
25372            }
25373        }
25374
25375        @Override
25376        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
25377            synchronized (mPackages) {
25378                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
25379                        packageName, userId);
25380            }
25381        }
25382
25383        @Override
25384        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
25385            synchronized (mPackages) {
25386                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
25387                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
25388                        packageName, userId);
25389            }
25390        }
25391
25392        @Override
25393        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
25394            synchronized (mPackages) {
25395                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
25396                        packageName, userId);
25397            }
25398        }
25399
25400        @Override
25401        public void setKeepUninstalledPackages(final List<String> packageList) {
25402            Preconditions.checkNotNull(packageList);
25403            List<String> removedFromList = null;
25404            synchronized (mPackages) {
25405                if (mKeepUninstalledPackages != null) {
25406                    final int packagesCount = mKeepUninstalledPackages.size();
25407                    for (int i = 0; i < packagesCount; i++) {
25408                        String oldPackage = mKeepUninstalledPackages.get(i);
25409                        if (packageList != null && packageList.contains(oldPackage)) {
25410                            continue;
25411                        }
25412                        if (removedFromList == null) {
25413                            removedFromList = new ArrayList<>();
25414                        }
25415                        removedFromList.add(oldPackage);
25416                    }
25417                }
25418                mKeepUninstalledPackages = new ArrayList<>(packageList);
25419                if (removedFromList != null) {
25420                    final int removedCount = removedFromList.size();
25421                    for (int i = 0; i < removedCount; i++) {
25422                        deletePackageIfUnusedLPr(removedFromList.get(i));
25423                    }
25424                }
25425            }
25426        }
25427
25428        @Override
25429        public boolean isPermissionsReviewRequired(String packageName, int userId) {
25430            synchronized (mPackages) {
25431                // If we do not support permission review, done.
25432                if (!mPermissionReviewRequired) {
25433                    return false;
25434                }
25435
25436                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
25437                if (packageSetting == null) {
25438                    return false;
25439                }
25440
25441                // Permission review applies only to apps not supporting the new permission model.
25442                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
25443                    return false;
25444                }
25445
25446                // Legacy apps have the permission and get user consent on launch.
25447                PermissionsState permissionsState = packageSetting.getPermissionsState();
25448                return permissionsState.isPermissionReviewRequired(userId);
25449            }
25450        }
25451
25452        @Override
25453        public PackageInfo getPackageInfo(
25454                String packageName, int flags, int filterCallingUid, int userId) {
25455            return PackageManagerService.this
25456                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
25457                            flags, filterCallingUid, userId);
25458        }
25459
25460        @Override
25461        public ApplicationInfo getApplicationInfo(
25462                String packageName, int flags, int filterCallingUid, int userId) {
25463            return PackageManagerService.this
25464                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
25465        }
25466
25467        @Override
25468        public ActivityInfo getActivityInfo(
25469                ComponentName component, int flags, int filterCallingUid, int userId) {
25470            return PackageManagerService.this
25471                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
25472        }
25473
25474        @Override
25475        public List<ResolveInfo> queryIntentActivities(
25476                Intent intent, int flags, int filterCallingUid, int userId) {
25477            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
25478            return PackageManagerService.this
25479                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
25480                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
25481        }
25482
25483        @Override
25484        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
25485                int userId) {
25486            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
25487        }
25488
25489        @Override
25490        public void setDeviceAndProfileOwnerPackages(
25491                int deviceOwnerUserId, String deviceOwnerPackage,
25492                SparseArray<String> profileOwnerPackages) {
25493            mProtectedPackages.setDeviceAndProfileOwnerPackages(
25494                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
25495        }
25496
25497        @Override
25498        public boolean isPackageDataProtected(int userId, String packageName) {
25499            return mProtectedPackages.isPackageDataProtected(userId, packageName);
25500        }
25501
25502        @Override
25503        public boolean isPackageEphemeral(int userId, String packageName) {
25504            synchronized (mPackages) {
25505                final PackageSetting ps = mSettings.mPackages.get(packageName);
25506                return ps != null ? ps.getInstantApp(userId) : false;
25507            }
25508        }
25509
25510        @Override
25511        public boolean wasPackageEverLaunched(String packageName, int userId) {
25512            synchronized (mPackages) {
25513                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
25514            }
25515        }
25516
25517        @Override
25518        public void grantRuntimePermission(String packageName, String name, int userId,
25519                boolean overridePolicy) {
25520            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
25521                    overridePolicy);
25522        }
25523
25524        @Override
25525        public void revokeRuntimePermission(String packageName, String name, int userId,
25526                boolean overridePolicy) {
25527            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
25528                    overridePolicy);
25529        }
25530
25531        @Override
25532        public String getNameForUid(int uid) {
25533            return PackageManagerService.this.getNameForUid(uid);
25534        }
25535
25536        @Override
25537        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
25538                Intent origIntent, String resolvedType, String callingPackage,
25539                Bundle verificationBundle, int userId) {
25540            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
25541                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
25542                    userId);
25543        }
25544
25545        @Override
25546        public void grantEphemeralAccess(int userId, Intent intent,
25547                int targetAppId, int ephemeralAppId) {
25548            synchronized (mPackages) {
25549                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
25550                        targetAppId, ephemeralAppId);
25551            }
25552        }
25553
25554        @Override
25555        public boolean isInstantAppInstallerComponent(ComponentName component) {
25556            synchronized (mPackages) {
25557                return mInstantAppInstallerActivity != null
25558                        && mInstantAppInstallerActivity.getComponentName().equals(component);
25559            }
25560        }
25561
25562        @Override
25563        public void pruneInstantApps() {
25564            mInstantAppRegistry.pruneInstantApps();
25565        }
25566
25567        @Override
25568        public String getSetupWizardPackageName() {
25569            return mSetupWizardPackage;
25570        }
25571
25572        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25573            if (policy != null) {
25574                mExternalSourcesPolicy = policy;
25575            }
25576        }
25577
25578        @Override
25579        public boolean isPackagePersistent(String packageName) {
25580            synchronized (mPackages) {
25581                PackageParser.Package pkg = mPackages.get(packageName);
25582                return pkg != null
25583                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25584                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
25585                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25586                        : false;
25587            }
25588        }
25589
25590        @Override
25591        public List<PackageInfo> getOverlayPackages(int userId) {
25592            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25593            synchronized (mPackages) {
25594                for (PackageParser.Package p : mPackages.values()) {
25595                    if (p.mOverlayTarget != null) {
25596                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25597                        if (pkg != null) {
25598                            overlayPackages.add(pkg);
25599                        }
25600                    }
25601                }
25602            }
25603            return overlayPackages;
25604        }
25605
25606        @Override
25607        public List<String> getTargetPackageNames(int userId) {
25608            List<String> targetPackages = new ArrayList<>();
25609            synchronized (mPackages) {
25610                for (PackageParser.Package p : mPackages.values()) {
25611                    if (p.mOverlayTarget == null) {
25612                        targetPackages.add(p.packageName);
25613                    }
25614                }
25615            }
25616            return targetPackages;
25617        }
25618
25619        @Override
25620        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25621                @Nullable List<String> overlayPackageNames) {
25622            synchronized (mPackages) {
25623                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25624                    Slog.e(TAG, "failed to find package " + targetPackageName);
25625                    return false;
25626                }
25627                ArrayList<String> overlayPaths = null;
25628                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25629                    final int N = overlayPackageNames.size();
25630                    overlayPaths = new ArrayList<>(N);
25631                    for (int i = 0; i < N; i++) {
25632                        final String packageName = overlayPackageNames.get(i);
25633                        final PackageParser.Package pkg = mPackages.get(packageName);
25634                        if (pkg == null) {
25635                            Slog.e(TAG, "failed to find package " + packageName);
25636                            return false;
25637                        }
25638                        overlayPaths.add(pkg.baseCodePath);
25639                    }
25640                }
25641
25642                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25643                ps.setOverlayPaths(overlayPaths, userId);
25644                return true;
25645            }
25646        }
25647
25648        @Override
25649        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25650                int flags, int userId) {
25651            return resolveIntentInternal(
25652                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
25653        }
25654
25655        @Override
25656        public ResolveInfo resolveService(Intent intent, String resolvedType,
25657                int flags, int userId, int callingUid) {
25658            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25659        }
25660
25661        @Override
25662        public void addIsolatedUid(int isolatedUid, int ownerUid) {
25663            synchronized (mPackages) {
25664                mIsolatedOwners.put(isolatedUid, ownerUid);
25665            }
25666        }
25667
25668        @Override
25669        public void removeIsolatedUid(int isolatedUid) {
25670            synchronized (mPackages) {
25671                mIsolatedOwners.delete(isolatedUid);
25672            }
25673        }
25674
25675        @Override
25676        public int getUidTargetSdkVersion(int uid) {
25677            synchronized (mPackages) {
25678                return getUidTargetSdkVersionLockedLPr(uid);
25679            }
25680        }
25681
25682        @Override
25683        public boolean canAccessInstantApps(int callingUid, int userId) {
25684            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25685        }
25686
25687        @Override
25688        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
25689            synchronized (mPackages) {
25690                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
25691            }
25692        }
25693
25694        @Override
25695        public void notifyPackageUse(String packageName, int reason) {
25696            synchronized (mPackages) {
25697                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
25698            }
25699        }
25700    }
25701
25702    @Override
25703    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25704        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25705        synchronized (mPackages) {
25706            final long identity = Binder.clearCallingIdentity();
25707            try {
25708                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25709                        packageNames, userId);
25710            } finally {
25711                Binder.restoreCallingIdentity(identity);
25712            }
25713        }
25714    }
25715
25716    @Override
25717    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25718        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25719        synchronized (mPackages) {
25720            final long identity = Binder.clearCallingIdentity();
25721            try {
25722                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25723                        packageNames, userId);
25724            } finally {
25725                Binder.restoreCallingIdentity(identity);
25726            }
25727        }
25728    }
25729
25730    private static void enforceSystemOrPhoneCaller(String tag) {
25731        int callingUid = Binder.getCallingUid();
25732        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25733            throw new SecurityException(
25734                    "Cannot call " + tag + " from UID " + callingUid);
25735        }
25736    }
25737
25738    boolean isHistoricalPackageUsageAvailable() {
25739        return mPackageUsage.isHistoricalPackageUsageAvailable();
25740    }
25741
25742    /**
25743     * Return a <b>copy</b> of the collection of packages known to the package manager.
25744     * @return A copy of the values of mPackages.
25745     */
25746    Collection<PackageParser.Package> getPackages() {
25747        synchronized (mPackages) {
25748            return new ArrayList<>(mPackages.values());
25749        }
25750    }
25751
25752    /**
25753     * Logs process start information (including base APK hash) to the security log.
25754     * @hide
25755     */
25756    @Override
25757    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25758            String apkFile, int pid) {
25759        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25760            return;
25761        }
25762        if (!SecurityLog.isLoggingEnabled()) {
25763            return;
25764        }
25765        Bundle data = new Bundle();
25766        data.putLong("startTimestamp", System.currentTimeMillis());
25767        data.putString("processName", processName);
25768        data.putInt("uid", uid);
25769        data.putString("seinfo", seinfo);
25770        data.putString("apkFile", apkFile);
25771        data.putInt("pid", pid);
25772        Message msg = mProcessLoggingHandler.obtainMessage(
25773                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25774        msg.setData(data);
25775        mProcessLoggingHandler.sendMessage(msg);
25776    }
25777
25778    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25779        return mCompilerStats.getPackageStats(pkgName);
25780    }
25781
25782    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25783        return getOrCreateCompilerPackageStats(pkg.packageName);
25784    }
25785
25786    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25787        return mCompilerStats.getOrCreatePackageStats(pkgName);
25788    }
25789
25790    public void deleteCompilerPackageStats(String pkgName) {
25791        mCompilerStats.deletePackageStats(pkgName);
25792    }
25793
25794    @Override
25795    public int getInstallReason(String packageName, int userId) {
25796        final int callingUid = Binder.getCallingUid();
25797        enforceCrossUserPermission(callingUid, userId,
25798                true /* requireFullPermission */, false /* checkShell */,
25799                "get install reason");
25800        synchronized (mPackages) {
25801            final PackageSetting ps = mSettings.mPackages.get(packageName);
25802            if (filterAppAccessLPr(ps, callingUid, userId)) {
25803                return PackageManager.INSTALL_REASON_UNKNOWN;
25804            }
25805            if (ps != null) {
25806                return ps.getInstallReason(userId);
25807            }
25808        }
25809        return PackageManager.INSTALL_REASON_UNKNOWN;
25810    }
25811
25812    @Override
25813    public boolean canRequestPackageInstalls(String packageName, int userId) {
25814        return canRequestPackageInstallsInternal(packageName, 0, userId,
25815                true /* throwIfPermNotDeclared*/);
25816    }
25817
25818    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25819            boolean throwIfPermNotDeclared) {
25820        int callingUid = Binder.getCallingUid();
25821        int uid = getPackageUid(packageName, 0, userId);
25822        if (callingUid != uid && callingUid != Process.ROOT_UID
25823                && callingUid != Process.SYSTEM_UID) {
25824            throw new SecurityException(
25825                    "Caller uid " + callingUid + " does not own package " + packageName);
25826        }
25827        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25828        if (info == null) {
25829            return false;
25830        }
25831        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25832            return false;
25833        }
25834        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25835        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25836        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25837            if (throwIfPermNotDeclared) {
25838                throw new SecurityException("Need to declare " + appOpPermission
25839                        + " to call this api");
25840            } else {
25841                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25842                return false;
25843            }
25844        }
25845        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25846            return false;
25847        }
25848        if (mExternalSourcesPolicy != null) {
25849            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25850            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
25851                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25852            }
25853        }
25854        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
25855    }
25856
25857    @Override
25858    public ComponentName getInstantAppResolverSettingsComponent() {
25859        return mInstantAppResolverSettingsComponent;
25860    }
25861
25862    @Override
25863    public ComponentName getInstantAppInstallerComponent() {
25864        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25865            return null;
25866        }
25867        return mInstantAppInstallerActivity == null
25868                ? null : mInstantAppInstallerActivity.getComponentName();
25869    }
25870
25871    @Override
25872    public String getInstantAppAndroidId(String packageName, int userId) {
25873        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25874                "getInstantAppAndroidId");
25875        enforceCrossUserPermission(Binder.getCallingUid(), userId,
25876                true /* requireFullPermission */, false /* checkShell */,
25877                "getInstantAppAndroidId");
25878        // Make sure the target is an Instant App.
25879        if (!isInstantApp(packageName, userId)) {
25880            return null;
25881        }
25882        synchronized (mPackages) {
25883            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25884        }
25885    }
25886
25887    boolean canHaveOatDir(String packageName) {
25888        synchronized (mPackages) {
25889            PackageParser.Package p = mPackages.get(packageName);
25890            if (p == null) {
25891                return false;
25892            }
25893            return p.canHaveOatDir();
25894        }
25895    }
25896
25897    private String getOatDir(PackageParser.Package pkg) {
25898        if (!pkg.canHaveOatDir()) {
25899            return null;
25900        }
25901        File codePath = new File(pkg.codePath);
25902        if (codePath.isDirectory()) {
25903            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25904        }
25905        return null;
25906    }
25907
25908    void deleteOatArtifactsOfPackage(String packageName) {
25909        final String[] instructionSets;
25910        final List<String> codePaths;
25911        final String oatDir;
25912        final PackageParser.Package pkg;
25913        synchronized (mPackages) {
25914            pkg = mPackages.get(packageName);
25915        }
25916        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25917        codePaths = pkg.getAllCodePaths();
25918        oatDir = getOatDir(pkg);
25919
25920        for (String codePath : codePaths) {
25921            for (String isa : instructionSets) {
25922                try {
25923                    mInstaller.deleteOdex(codePath, isa, oatDir);
25924                } catch (InstallerException e) {
25925                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25926                }
25927            }
25928        }
25929    }
25930
25931    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25932        Set<String> unusedPackages = new HashSet<>();
25933        long currentTimeInMillis = System.currentTimeMillis();
25934        synchronized (mPackages) {
25935            for (PackageParser.Package pkg : mPackages.values()) {
25936                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
25937                if (ps == null) {
25938                    continue;
25939                }
25940                PackageDexUsage.PackageUseInfo packageUseInfo =
25941                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
25942                if (PackageManagerServiceUtils
25943                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25944                                downgradeTimeThresholdMillis, packageUseInfo,
25945                                pkg.getLatestPackageUseTimeInMills(),
25946                                pkg.getLatestForegroundPackageUseTimeInMills())) {
25947                    unusedPackages.add(pkg.packageName);
25948                }
25949            }
25950        }
25951        return unusedPackages;
25952    }
25953}
25954
25955interface PackageSender {
25956    void sendPackageBroadcast(final String action, final String pkg,
25957        final Bundle extras, final int flags, final String targetPkg,
25958        final IIntentReceiver finishedReceiver, final int[] userIds);
25959    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25960        boolean includeStopped, int appId, int... userIds);
25961}
25962