PackageManagerService.java revision a47ba5f72a57ed58663ccde9c82a6398d6f8e8e4
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
86import static android.content.pm.PackageParser.isApkFile;
87import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88import static android.system.OsConstants.O_CREAT;
89import static android.system.OsConstants.O_RDWR;
90
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
93import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
94import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
95import static com.android.internal.util.ArrayUtils.appendInt;
96import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
99import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
100import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
104import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
105import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
106
107import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
108
109import android.Manifest;
110import android.annotation.IntDef;
111import android.annotation.NonNull;
112import android.annotation.Nullable;
113import android.app.ActivityManager;
114import android.app.AppOpsManager;
115import android.app.IActivityManager;
116import android.app.ResourcesManager;
117import android.app.admin.IDevicePolicyManager;
118import android.app.admin.SecurityLog;
119import android.app.backup.IBackupManager;
120import android.content.BroadcastReceiver;
121import android.content.ComponentName;
122import android.content.ContentResolver;
123import android.content.Context;
124import android.content.IIntentReceiver;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.IntentSender.SendIntentException;
129import android.content.ServiceConnection;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.AppsQueryHelper;
133import android.content.pm.AuxiliaryResolveInfo;
134import android.content.pm.ChangedPackages;
135import android.content.pm.ComponentInfo;
136import android.content.pm.FallbackCategoryProvider;
137import android.content.pm.FeatureInfo;
138import android.content.pm.IDexModuleRegisterCallback;
139import android.content.pm.IOnPermissionsChangeListener;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageDeleteObserver;
142import android.content.pm.IPackageDeleteObserver2;
143import android.content.pm.IPackageInstallObserver2;
144import android.content.pm.IPackageInstaller;
145import android.content.pm.IPackageManager;
146import android.content.pm.IPackageMoveObserver;
147import android.content.pm.IPackageStatsObserver;
148import android.content.pm.InstantAppInfo;
149import android.content.pm.InstantAppRequest;
150import android.content.pm.InstantAppResolveInfo;
151import android.content.pm.InstrumentationInfo;
152import android.content.pm.IntentFilterVerificationInfo;
153import android.content.pm.KeySet;
154import android.content.pm.PackageCleanItem;
155import android.content.pm.PackageInfo;
156import android.content.pm.PackageInfoLite;
157import android.content.pm.PackageInstaller;
158import android.content.pm.PackageManager;
159import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
160import android.content.pm.PackageManagerInternal;
161import android.content.pm.PackageParser;
162import android.content.pm.PackageParser.ActivityIntentInfo;
163import android.content.pm.PackageParser.PackageLite;
164import android.content.pm.PackageParser.PackageParserException;
165import android.content.pm.PackageStats;
166import android.content.pm.PackageUserState;
167import android.content.pm.ParceledListSlice;
168import android.content.pm.PermissionGroupInfo;
169import android.content.pm.PermissionInfo;
170import android.content.pm.ProviderInfo;
171import android.content.pm.ResolveInfo;
172import android.content.pm.ServiceInfo;
173import android.content.pm.SharedLibraryInfo;
174import android.content.pm.Signature;
175import android.content.pm.UserInfo;
176import android.content.pm.VerifierDeviceIdentity;
177import android.content.pm.VerifierInfo;
178import android.content.pm.VersionedPackage;
179import android.content.res.Resources;
180import android.database.ContentObserver;
181import android.graphics.Bitmap;
182import android.hardware.display.DisplayManager;
183import android.net.Uri;
184import android.os.Binder;
185import android.os.Build;
186import android.os.Bundle;
187import android.os.Debug;
188import android.os.Environment;
189import android.os.Environment.UserEnvironment;
190import android.os.FileUtils;
191import android.os.Handler;
192import android.os.IBinder;
193import android.os.Looper;
194import android.os.Message;
195import android.os.Parcel;
196import android.os.ParcelFileDescriptor;
197import android.os.PatternMatcher;
198import android.os.Process;
199import android.os.RemoteCallbackList;
200import android.os.RemoteException;
201import android.os.ResultReceiver;
202import android.os.SELinux;
203import android.os.ServiceManager;
204import android.os.ShellCallback;
205import android.os.SystemClock;
206import android.os.SystemProperties;
207import android.os.Trace;
208import android.os.UserHandle;
209import android.os.UserManager;
210import android.os.UserManagerInternal;
211import android.os.storage.IStorageManager;
212import android.os.storage.StorageEventListener;
213import android.os.storage.StorageManager;
214import android.os.storage.StorageManagerInternal;
215import android.os.storage.VolumeInfo;
216import android.os.storage.VolumeRecord;
217import android.provider.Settings.Global;
218import android.provider.Settings.Secure;
219import android.security.KeyStore;
220import android.security.SystemKeyStore;
221import android.service.pm.PackageServiceDumpProto;
222import android.system.ErrnoException;
223import android.system.Os;
224import android.text.TextUtils;
225import android.text.format.DateUtils;
226import android.util.ArrayMap;
227import android.util.ArraySet;
228import android.util.Base64;
229import android.util.BootTimingsTraceLog;
230import android.util.DisplayMetrics;
231import android.util.EventLog;
232import android.util.ExceptionUtils;
233import android.util.Log;
234import android.util.LogPrinter;
235import android.util.MathUtils;
236import android.util.PackageUtils;
237import android.util.Pair;
238import android.util.PrintStreamPrinter;
239import android.util.Slog;
240import android.util.SparseArray;
241import android.util.SparseBooleanArray;
242import android.util.SparseIntArray;
243import android.util.Xml;
244import android.util.jar.StrictJarFile;
245import android.util.proto.ProtoOutputStream;
246import android.view.Display;
247
248import com.android.internal.R;
249import com.android.internal.annotations.GuardedBy;
250import com.android.internal.app.IMediaContainerService;
251import com.android.internal.app.ResolverActivity;
252import com.android.internal.content.NativeLibraryHelper;
253import com.android.internal.content.PackageHelper;
254import com.android.internal.logging.MetricsLogger;
255import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
256import com.android.internal.os.IParcelFileDescriptorFactory;
257import com.android.internal.os.RoSystemProperties;
258import com.android.internal.os.SomeArgs;
259import com.android.internal.os.Zygote;
260import com.android.internal.telephony.CarrierAppUtils;
261import com.android.internal.util.ArrayUtils;
262import com.android.internal.util.ConcurrentUtils;
263import com.android.internal.util.DumpUtils;
264import com.android.internal.util.FastPrintWriter;
265import com.android.internal.util.FastXmlSerializer;
266import com.android.internal.util.IndentingPrintWriter;
267import com.android.internal.util.Preconditions;
268import com.android.internal.util.XmlUtils;
269import com.android.server.AttributeCache;
270import com.android.server.DeviceIdleController;
271import com.android.server.EventLogTags;
272import com.android.server.FgThread;
273import com.android.server.IntentResolver;
274import com.android.server.LocalServices;
275import com.android.server.LockGuard;
276import com.android.server.ServiceThread;
277import com.android.server.SystemConfig;
278import com.android.server.SystemServerInitThreadPool;
279import com.android.server.Watchdog;
280import com.android.server.net.NetworkPolicyManagerInternal;
281import com.android.server.pm.Installer.InstallerException;
282import com.android.server.pm.PermissionsState.PermissionState;
283import com.android.server.pm.Settings.DatabaseVersion;
284import com.android.server.pm.Settings.VersionInfo;
285import com.android.server.pm.dex.DexManager;
286import com.android.server.pm.dex.DexoptOptions;
287import com.android.server.pm.dex.PackageDexUsage;
288import com.android.server.storage.DeviceStorageMonitorInternal;
289
290import dalvik.system.CloseGuard;
291import dalvik.system.DexFile;
292import dalvik.system.VMRuntime;
293
294import libcore.io.IoUtils;
295import libcore.io.Streams;
296import libcore.util.EmptyArray;
297
298import org.xmlpull.v1.XmlPullParser;
299import org.xmlpull.v1.XmlPullParserException;
300import org.xmlpull.v1.XmlSerializer;
301
302import java.io.BufferedOutputStream;
303import java.io.BufferedReader;
304import java.io.ByteArrayInputStream;
305import java.io.ByteArrayOutputStream;
306import java.io.File;
307import java.io.FileDescriptor;
308import java.io.FileInputStream;
309import java.io.FileOutputStream;
310import java.io.FileReader;
311import java.io.FilenameFilter;
312import java.io.IOException;
313import java.io.InputStream;
314import java.io.OutputStream;
315import java.io.PrintWriter;
316import java.lang.annotation.Retention;
317import java.lang.annotation.RetentionPolicy;
318import java.nio.charset.StandardCharsets;
319import java.security.DigestInputStream;
320import java.security.MessageDigest;
321import java.security.NoSuchAlgorithmException;
322import java.security.PublicKey;
323import java.security.SecureRandom;
324import java.security.cert.Certificate;
325import java.security.cert.CertificateEncodingException;
326import java.security.cert.CertificateException;
327import java.text.SimpleDateFormat;
328import java.util.ArrayList;
329import java.util.Arrays;
330import java.util.Collection;
331import java.util.Collections;
332import java.util.Comparator;
333import java.util.Date;
334import java.util.HashMap;
335import java.util.HashSet;
336import java.util.Iterator;
337import java.util.List;
338import java.util.Map;
339import java.util.Objects;
340import java.util.Set;
341import java.util.concurrent.CountDownLatch;
342import java.util.concurrent.Future;
343import java.util.concurrent.TimeUnit;
344import java.util.concurrent.atomic.AtomicBoolean;
345import java.util.concurrent.atomic.AtomicInteger;
346import java.util.zip.GZIPInputStream;
347
348/**
349 * Keep track of all those APKs everywhere.
350 * <p>
351 * Internally there are two important locks:
352 * <ul>
353 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
354 * and other related state. It is a fine-grained lock that should only be held
355 * momentarily, as it's one of the most contended locks in the system.
356 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
357 * operations typically involve heavy lifting of application data on disk. Since
358 * {@code installd} is single-threaded, and it's operations can often be slow,
359 * this lock should never be acquired while already holding {@link #mPackages}.
360 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
361 * holding {@link #mInstallLock}.
362 * </ul>
363 * Many internal methods rely on the caller to hold the appropriate locks, and
364 * this contract is expressed through method name suffixes:
365 * <ul>
366 * <li>fooLI(): the caller must hold {@link #mInstallLock}
367 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
368 * being modified must be frozen
369 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
370 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
371 * </ul>
372 * <p>
373 * Because this class is very central to the platform's security; please run all
374 * CTS and unit tests whenever making modifications:
375 *
376 * <pre>
377 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
378 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
379 * </pre>
380 */
381public class PackageManagerService extends IPackageManager.Stub
382        implements PackageSender {
383    static final String TAG = "PackageManager";
384    static final boolean DEBUG_SETTINGS = false;
385    static final boolean DEBUG_PREFERRED = false;
386    static final boolean DEBUG_UPGRADE = false;
387    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
388    private static final boolean DEBUG_BACKUP = false;
389    private static final boolean DEBUG_INSTALL = false;
390    private static final boolean DEBUG_REMOVE = false;
391    private static final boolean DEBUG_BROADCASTS = false;
392    private static final boolean DEBUG_SHOW_INFO = false;
393    private static final boolean DEBUG_PACKAGE_INFO = false;
394    private static final boolean DEBUG_INTENT_MATCHING = false;
395    private static final boolean DEBUG_PACKAGE_SCANNING = false;
396    private static final boolean DEBUG_VERIFY = false;
397    private static final boolean DEBUG_FILTERS = false;
398    private static final boolean DEBUG_PERMISSIONS = false;
399    private static final boolean DEBUG_SHARED_LIBRARIES = false;
400    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
401
402    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
403    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
404    // user, but by default initialize to this.
405    public static final boolean DEBUG_DEXOPT = false;
406
407    private static final boolean DEBUG_ABI_SELECTION = false;
408    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
409    private static final boolean DEBUG_TRIAGED_MISSING = false;
410    private static final boolean DEBUG_APP_DATA = false;
411
412    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
413    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
414
415    private static final boolean HIDE_EPHEMERAL_APIS = false;
416
417    private static final boolean ENABLE_FREE_CACHE_V2 =
418            SystemProperties.getBoolean("fw.free_cache_v2", true);
419
420    private static final int RADIO_UID = Process.PHONE_UID;
421    private static final int LOG_UID = Process.LOG_UID;
422    private static final int NFC_UID = Process.NFC_UID;
423    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
424    private static final int SHELL_UID = Process.SHELL_UID;
425
426    // Cap the size of permission trees that 3rd party apps can define
427    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
428
429    // Suffix used during package installation when copying/moving
430    // package apks to install directory.
431    private static final String INSTALL_PACKAGE_SUFFIX = "-";
432
433    static final int SCAN_NO_DEX = 1<<1;
434    static final int SCAN_FORCE_DEX = 1<<2;
435    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
436    static final int SCAN_NEW_INSTALL = 1<<4;
437    static final int SCAN_UPDATE_TIME = 1<<5;
438    static final int SCAN_BOOTING = 1<<6;
439    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
440    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
441    static final int SCAN_REPLACING = 1<<9;
442    static final int SCAN_REQUIRE_KNOWN = 1<<10;
443    static final int SCAN_MOVE = 1<<11;
444    static final int SCAN_INITIAL = 1<<12;
445    static final int SCAN_CHECK_ONLY = 1<<13;
446    static final int SCAN_DONT_KILL_APP = 1<<14;
447    static final int SCAN_IGNORE_FROZEN = 1<<15;
448    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
449    static final int SCAN_AS_INSTANT_APP = 1<<17;
450    static final int SCAN_AS_FULL_APP = 1<<18;
451    /** Should not be with the scan flags */
452    static final int FLAGS_REMOVE_CHATTY = 1<<31;
453
454    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
455    /** Extension of the compressed packages */
456    private final static String COMPRESSED_EXTENSION = ".gz";
457
458    private static final int[] EMPTY_INT_ARRAY = new int[0];
459
460    private static final int TYPE_UNKNOWN = 0;
461    private static final int TYPE_ACTIVITY = 1;
462    private static final int TYPE_RECEIVER = 2;
463    private static final int TYPE_SERVICE = 3;
464    private static final int TYPE_PROVIDER = 4;
465    @IntDef(prefix = { "TYPE_" }, value = {
466            TYPE_UNKNOWN,
467            TYPE_ACTIVITY,
468            TYPE_RECEIVER,
469            TYPE_SERVICE,
470            TYPE_PROVIDER,
471    })
472    @Retention(RetentionPolicy.SOURCE)
473    public @interface ComponentType {}
474
475    /**
476     * Timeout (in milliseconds) after which the watchdog should declare that
477     * our handler thread is wedged.  The usual default for such things is one
478     * minute but we sometimes do very lengthy I/O operations on this thread,
479     * such as installing multi-gigabyte applications, so ours needs to be longer.
480     */
481    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
482
483    /**
484     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
485     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
486     * settings entry if available, otherwise we use the hardcoded default.  If it's been
487     * more than this long since the last fstrim, we force one during the boot sequence.
488     *
489     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
490     * one gets run at the next available charging+idle time.  This final mandatory
491     * no-fstrim check kicks in only of the other scheduling criteria is never met.
492     */
493    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
494
495    /**
496     * Whether verification is enabled by default.
497     */
498    private static final boolean DEFAULT_VERIFY_ENABLE = true;
499
500    /**
501     * The default maximum time to wait for the verification agent to return in
502     * milliseconds.
503     */
504    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
505
506    /**
507     * The default response for package verification timeout.
508     *
509     * This can be either PackageManager.VERIFICATION_ALLOW or
510     * PackageManager.VERIFICATION_REJECT.
511     */
512    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
513
514    static final String PLATFORM_PACKAGE_NAME = "android";
515
516    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
517
518    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
519            DEFAULT_CONTAINER_PACKAGE,
520            "com.android.defcontainer.DefaultContainerService");
521
522    private static final String KILL_APP_REASON_GIDS_CHANGED =
523            "permission grant or revoke changed gids";
524
525    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
526            "permissions revoked";
527
528    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
529
530    private static final String PACKAGE_SCHEME = "package";
531
532    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
533
534    /** Permission grant: not grant the permission. */
535    private static final int GRANT_DENIED = 1;
536
537    /** Permission grant: grant the permission as an install permission. */
538    private static final int GRANT_INSTALL = 2;
539
540    /** Permission grant: grant the permission as a runtime one. */
541    private static final int GRANT_RUNTIME = 3;
542
543    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
544    private static final int GRANT_UPGRADE = 4;
545
546    /** Canonical intent used to identify what counts as a "web browser" app */
547    private static final Intent sBrowserIntent;
548    static {
549        sBrowserIntent = new Intent();
550        sBrowserIntent.setAction(Intent.ACTION_VIEW);
551        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
552        sBrowserIntent.setData(Uri.parse("http:"));
553    }
554
555    /**
556     * The set of all protected actions [i.e. those actions for which a high priority
557     * intent filter is disallowed].
558     */
559    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
560    static {
561        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
562        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
563        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
564        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
565    }
566
567    // Compilation reasons.
568    public static final int REASON_FIRST_BOOT = 0;
569    public static final int REASON_BOOT = 1;
570    public static final int REASON_INSTALL = 2;
571    public static final int REASON_BACKGROUND_DEXOPT = 3;
572    public static final int REASON_AB_OTA = 4;
573    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
574
575    public static final int REASON_LAST = REASON_INACTIVE_PACKAGE_DOWNGRADE;
576
577    /** All dangerous permission names in the same order as the events in MetricsEvent */
578    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
579            Manifest.permission.READ_CALENDAR,
580            Manifest.permission.WRITE_CALENDAR,
581            Manifest.permission.CAMERA,
582            Manifest.permission.READ_CONTACTS,
583            Manifest.permission.WRITE_CONTACTS,
584            Manifest.permission.GET_ACCOUNTS,
585            Manifest.permission.ACCESS_FINE_LOCATION,
586            Manifest.permission.ACCESS_COARSE_LOCATION,
587            Manifest.permission.RECORD_AUDIO,
588            Manifest.permission.READ_PHONE_STATE,
589            Manifest.permission.CALL_PHONE,
590            Manifest.permission.READ_CALL_LOG,
591            Manifest.permission.WRITE_CALL_LOG,
592            Manifest.permission.ADD_VOICEMAIL,
593            Manifest.permission.USE_SIP,
594            Manifest.permission.PROCESS_OUTGOING_CALLS,
595            Manifest.permission.READ_CELL_BROADCASTS,
596            Manifest.permission.BODY_SENSORS,
597            Manifest.permission.SEND_SMS,
598            Manifest.permission.RECEIVE_SMS,
599            Manifest.permission.READ_SMS,
600            Manifest.permission.RECEIVE_WAP_PUSH,
601            Manifest.permission.RECEIVE_MMS,
602            Manifest.permission.READ_EXTERNAL_STORAGE,
603            Manifest.permission.WRITE_EXTERNAL_STORAGE,
604            Manifest.permission.READ_PHONE_NUMBERS,
605            Manifest.permission.ANSWER_PHONE_CALLS);
606
607
608    /**
609     * Version number for the package parser cache. Increment this whenever the format or
610     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
611     */
612    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
613
614    /**
615     * Whether the package parser cache is enabled.
616     */
617    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
618
619    final ServiceThread mHandlerThread;
620
621    final PackageHandler mHandler;
622
623    private final ProcessLoggingHandler mProcessLoggingHandler;
624
625    /**
626     * Messages for {@link #mHandler} that need to wait for system ready before
627     * being dispatched.
628     */
629    private ArrayList<Message> mPostSystemReadyMessages;
630
631    final int mSdkVersion = Build.VERSION.SDK_INT;
632
633    final Context mContext;
634    final boolean mFactoryTest;
635    final boolean mOnlyCore;
636    final DisplayMetrics mMetrics;
637    final int mDefParseFlags;
638    final String[] mSeparateProcesses;
639    final boolean mIsUpgrade;
640    final boolean mIsPreNUpgrade;
641    final boolean mIsPreNMR1Upgrade;
642
643    // Have we told the Activity Manager to whitelist the default container service by uid yet?
644    @GuardedBy("mPackages")
645    boolean mDefaultContainerWhitelisted = false;
646
647    @GuardedBy("mPackages")
648    private boolean mDexOptDialogShown;
649
650    /** The location for ASEC container files on internal storage. */
651    final String mAsecInternalPath;
652
653    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
654    // LOCK HELD.  Can be called with mInstallLock held.
655    @GuardedBy("mInstallLock")
656    final Installer mInstaller;
657
658    /** Directory where installed third-party apps stored */
659    final File mAppInstallDir;
660
661    /**
662     * Directory to which applications installed internally have their
663     * 32 bit native libraries copied.
664     */
665    private File mAppLib32InstallDir;
666
667    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
668    // apps.
669    final File mDrmAppPrivateInstallDir;
670
671    // ----------------------------------------------------------------
672
673    // Lock for state used when installing and doing other long running
674    // operations.  Methods that must be called with this lock held have
675    // the suffix "LI".
676    final Object mInstallLock = new Object();
677
678    // ----------------------------------------------------------------
679
680    // Keys are String (package name), values are Package.  This also serves
681    // as the lock for the global state.  Methods that must be called with
682    // this lock held have the prefix "LP".
683    @GuardedBy("mPackages")
684    final ArrayMap<String, PackageParser.Package> mPackages =
685            new ArrayMap<String, PackageParser.Package>();
686
687    final ArrayMap<String, Set<String>> mKnownCodebase =
688            new ArrayMap<String, Set<String>>();
689
690    // Keys are isolated uids and values are the uid of the application
691    // that created the isolated proccess.
692    @GuardedBy("mPackages")
693    final SparseIntArray mIsolatedOwners = new SparseIntArray();
694
695    /**
696     * Tracks new system packages [received in an OTA] that we expect to
697     * find updated user-installed versions. Keys are package name, values
698     * are package location.
699     */
700    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
701    /**
702     * Tracks high priority intent filters for protected actions. During boot, certain
703     * filter actions are protected and should never be allowed to have a high priority
704     * intent filter for them. However, there is one, and only one exception -- the
705     * setup wizard. It must be able to define a high priority intent filter for these
706     * actions to ensure there are no escapes from the wizard. We need to delay processing
707     * of these during boot as we need to look at all of the system packages in order
708     * to know which component is the setup wizard.
709     */
710    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
711    /**
712     * Whether or not processing protected filters should be deferred.
713     */
714    private boolean mDeferProtectedFilters = true;
715
716    /**
717     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
718     */
719    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
720    /**
721     * Whether or not system app permissions should be promoted from install to runtime.
722     */
723    boolean mPromoteSystemApps;
724
725    @GuardedBy("mPackages")
726    final Settings mSettings;
727
728    /**
729     * Set of package names that are currently "frozen", which means active
730     * surgery is being done on the code/data for that package. The platform
731     * will refuse to launch frozen packages to avoid race conditions.
732     *
733     * @see PackageFreezer
734     */
735    @GuardedBy("mPackages")
736    final ArraySet<String> mFrozenPackages = new ArraySet<>();
737
738    final ProtectedPackages mProtectedPackages;
739
740    @GuardedBy("mLoadedVolumes")
741    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
742
743    boolean mFirstBoot;
744
745    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
746
747    // System configuration read by SystemConfig.
748    final int[] mGlobalGids;
749    final SparseArray<ArraySet<String>> mSystemPermissions;
750    @GuardedBy("mAvailableFeatures")
751    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
752
753    // If mac_permissions.xml was found for seinfo labeling.
754    boolean mFoundPolicyFile;
755
756    private final InstantAppRegistry mInstantAppRegistry;
757
758    @GuardedBy("mPackages")
759    int mChangedPackagesSequenceNumber;
760    /**
761     * List of changed [installed, removed or updated] packages.
762     * mapping from user id -> sequence number -> package name
763     */
764    @GuardedBy("mPackages")
765    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
766    /**
767     * The sequence number of the last change to a package.
768     * mapping from user id -> package name -> sequence number
769     */
770    @GuardedBy("mPackages")
771    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
772
773    class PackageParserCallback implements PackageParser.Callback {
774        @Override public final boolean hasFeature(String feature) {
775            return PackageManagerService.this.hasSystemFeature(feature, 0);
776        }
777
778        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
779                Collection<PackageParser.Package> allPackages, String targetPackageName) {
780            List<PackageParser.Package> overlayPackages = null;
781            for (PackageParser.Package p : allPackages) {
782                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
783                    if (overlayPackages == null) {
784                        overlayPackages = new ArrayList<PackageParser.Package>();
785                    }
786                    overlayPackages.add(p);
787                }
788            }
789            if (overlayPackages != null) {
790                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
791                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
792                        return p1.mOverlayPriority - p2.mOverlayPriority;
793                    }
794                };
795                Collections.sort(overlayPackages, cmp);
796            }
797            return overlayPackages;
798        }
799
800        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
801                String targetPackageName, String targetPath) {
802            if ("android".equals(targetPackageName)) {
803                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
804                // native AssetManager.
805                return null;
806            }
807            List<PackageParser.Package> overlayPackages =
808                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
809            if (overlayPackages == null || overlayPackages.isEmpty()) {
810                return null;
811            }
812            List<String> overlayPathList = null;
813            for (PackageParser.Package overlayPackage : overlayPackages) {
814                if (targetPath == null) {
815                    if (overlayPathList == null) {
816                        overlayPathList = new ArrayList<String>();
817                    }
818                    overlayPathList.add(overlayPackage.baseCodePath);
819                    continue;
820                }
821
822                try {
823                    // Creates idmaps for system to parse correctly the Android manifest of the
824                    // target package.
825                    //
826                    // OverlayManagerService will update each of them with a correct gid from its
827                    // target package app id.
828                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
829                            UserHandle.getSharedAppGid(
830                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
831                    if (overlayPathList == null) {
832                        overlayPathList = new ArrayList<String>();
833                    }
834                    overlayPathList.add(overlayPackage.baseCodePath);
835                } catch (InstallerException e) {
836                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
837                            overlayPackage.baseCodePath);
838                }
839            }
840            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
841        }
842
843        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
844            synchronized (mPackages) {
845                return getStaticOverlayPathsLocked(
846                        mPackages.values(), targetPackageName, targetPath);
847            }
848        }
849
850        @Override public final String[] getOverlayApks(String targetPackageName) {
851            return getStaticOverlayPaths(targetPackageName, null);
852        }
853
854        @Override public final String[] getOverlayPaths(String targetPackageName,
855                String targetPath) {
856            return getStaticOverlayPaths(targetPackageName, targetPath);
857        }
858    };
859
860    class ParallelPackageParserCallback extends PackageParserCallback {
861        List<PackageParser.Package> mOverlayPackages = null;
862
863        void findStaticOverlayPackages() {
864            synchronized (mPackages) {
865                for (PackageParser.Package p : mPackages.values()) {
866                    if (p.mIsStaticOverlay) {
867                        if (mOverlayPackages == null) {
868                            mOverlayPackages = new ArrayList<PackageParser.Package>();
869                        }
870                        mOverlayPackages.add(p);
871                    }
872                }
873            }
874        }
875
876        @Override
877        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
878            // We can trust mOverlayPackages without holding mPackages because package uninstall
879            // can't happen while running parallel parsing.
880            // Moreover holding mPackages on each parsing thread causes dead-lock.
881            return mOverlayPackages == null ? null :
882                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
883        }
884    }
885
886    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
887    final ParallelPackageParserCallback mParallelPackageParserCallback =
888            new ParallelPackageParserCallback();
889
890    public static final class SharedLibraryEntry {
891        public final @Nullable String path;
892        public final @Nullable String apk;
893        public final @NonNull SharedLibraryInfo info;
894
895        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
896                String declaringPackageName, int declaringPackageVersionCode) {
897            path = _path;
898            apk = _apk;
899            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
900                    declaringPackageName, declaringPackageVersionCode), null);
901        }
902    }
903
904    // Currently known shared libraries.
905    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
906    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
907            new ArrayMap<>();
908
909    // All available activities, for your resolving pleasure.
910    final ActivityIntentResolver mActivities =
911            new ActivityIntentResolver();
912
913    // All available receivers, for your resolving pleasure.
914    final ActivityIntentResolver mReceivers =
915            new ActivityIntentResolver();
916
917    // All available services, for your resolving pleasure.
918    final ServiceIntentResolver mServices = new ServiceIntentResolver();
919
920    // All available providers, for your resolving pleasure.
921    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
922
923    // Mapping from provider base names (first directory in content URI codePath)
924    // to the provider information.
925    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
926            new ArrayMap<String, PackageParser.Provider>();
927
928    // Mapping from instrumentation class names to info about them.
929    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
930            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
931
932    // Mapping from permission names to info about them.
933    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
934            new ArrayMap<String, PackageParser.PermissionGroup>();
935
936    // Packages whose data we have transfered into another package, thus
937    // should no longer exist.
938    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
939
940    // Broadcast actions that are only available to the system.
941    @GuardedBy("mProtectedBroadcasts")
942    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
943
944    /** List of packages waiting for verification. */
945    final SparseArray<PackageVerificationState> mPendingVerification
946            = new SparseArray<PackageVerificationState>();
947
948    /** Set of packages associated with each app op permission. */
949    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
950
951    final PackageInstallerService mInstallerService;
952
953    private final PackageDexOptimizer mPackageDexOptimizer;
954    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
955    // is used by other apps).
956    private final DexManager mDexManager;
957
958    private AtomicInteger mNextMoveId = new AtomicInteger();
959    private final MoveCallbacks mMoveCallbacks;
960
961    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
962
963    // Cache of users who need badging.
964    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
965
966    /** Token for keys in mPendingVerification. */
967    private int mPendingVerificationToken = 0;
968
969    volatile boolean mSystemReady;
970    volatile boolean mSafeMode;
971    volatile boolean mHasSystemUidErrors;
972    private volatile boolean mEphemeralAppsDisabled;
973
974    ApplicationInfo mAndroidApplication;
975    final ActivityInfo mResolveActivity = new ActivityInfo();
976    final ResolveInfo mResolveInfo = new ResolveInfo();
977    ComponentName mResolveComponentName;
978    PackageParser.Package mPlatformPackage;
979    ComponentName mCustomResolverComponentName;
980
981    boolean mResolverReplaced = false;
982
983    private final @Nullable ComponentName mIntentFilterVerifierComponent;
984    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
985
986    private int mIntentFilterVerificationToken = 0;
987
988    /** The service connection to the ephemeral resolver */
989    final EphemeralResolverConnection mInstantAppResolverConnection;
990    /** Component used to show resolver settings for Instant Apps */
991    final ComponentName mInstantAppResolverSettingsComponent;
992
993    /** Activity used to install instant applications */
994    ActivityInfo mInstantAppInstallerActivity;
995    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
996
997    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
998            = new SparseArray<IntentFilterVerificationState>();
999
1000    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1001
1002    // List of packages names to keep cached, even if they are uninstalled for all users
1003    private List<String> mKeepUninstalledPackages;
1004
1005    private UserManagerInternal mUserManagerInternal;
1006
1007    private DeviceIdleController.LocalService mDeviceIdleController;
1008
1009    private File mCacheDir;
1010
1011    private ArraySet<String> mPrivappPermissionsViolations;
1012
1013    private Future<?> mPrepareAppDataFuture;
1014
1015    private static class IFVerificationParams {
1016        PackageParser.Package pkg;
1017        boolean replacing;
1018        int userId;
1019        int verifierUid;
1020
1021        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1022                int _userId, int _verifierUid) {
1023            pkg = _pkg;
1024            replacing = _replacing;
1025            userId = _userId;
1026            replacing = _replacing;
1027            verifierUid = _verifierUid;
1028        }
1029    }
1030
1031    private interface IntentFilterVerifier<T extends IntentFilter> {
1032        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1033                                               T filter, String packageName);
1034        void startVerifications(int userId);
1035        void receiveVerificationResponse(int verificationId);
1036    }
1037
1038    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1039        private Context mContext;
1040        private ComponentName mIntentFilterVerifierComponent;
1041        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1042
1043        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1044            mContext = context;
1045            mIntentFilterVerifierComponent = verifierComponent;
1046        }
1047
1048        private String getDefaultScheme() {
1049            return IntentFilter.SCHEME_HTTPS;
1050        }
1051
1052        @Override
1053        public void startVerifications(int userId) {
1054            // Launch verifications requests
1055            int count = mCurrentIntentFilterVerifications.size();
1056            for (int n=0; n<count; n++) {
1057                int verificationId = mCurrentIntentFilterVerifications.get(n);
1058                final IntentFilterVerificationState ivs =
1059                        mIntentFilterVerificationStates.get(verificationId);
1060
1061                String packageName = ivs.getPackageName();
1062
1063                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1064                final int filterCount = filters.size();
1065                ArraySet<String> domainsSet = new ArraySet<>();
1066                for (int m=0; m<filterCount; m++) {
1067                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1068                    domainsSet.addAll(filter.getHostsList());
1069                }
1070                synchronized (mPackages) {
1071                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1072                            packageName, domainsSet) != null) {
1073                        scheduleWriteSettingsLocked();
1074                    }
1075                }
1076                sendVerificationRequest(verificationId, ivs);
1077            }
1078            mCurrentIntentFilterVerifications.clear();
1079        }
1080
1081        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1082            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1083            verificationIntent.putExtra(
1084                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1085                    verificationId);
1086            verificationIntent.putExtra(
1087                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1088                    getDefaultScheme());
1089            verificationIntent.putExtra(
1090                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1091                    ivs.getHostsString());
1092            verificationIntent.putExtra(
1093                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1094                    ivs.getPackageName());
1095            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1096            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1097
1098            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1099            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1100                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1101                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1102
1103            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1104            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1105                    "Sending IntentFilter verification broadcast");
1106        }
1107
1108        public void receiveVerificationResponse(int verificationId) {
1109            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1110
1111            final boolean verified = ivs.isVerified();
1112
1113            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1114            final int count = filters.size();
1115            if (DEBUG_DOMAIN_VERIFICATION) {
1116                Slog.i(TAG, "Received verification response " + verificationId
1117                        + " for " + count + " filters, verified=" + verified);
1118            }
1119            for (int n=0; n<count; n++) {
1120                PackageParser.ActivityIntentInfo filter = filters.get(n);
1121                filter.setVerified(verified);
1122
1123                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1124                        + " verified with result:" + verified + " and hosts:"
1125                        + ivs.getHostsString());
1126            }
1127
1128            mIntentFilterVerificationStates.remove(verificationId);
1129
1130            final String packageName = ivs.getPackageName();
1131            IntentFilterVerificationInfo ivi = null;
1132
1133            synchronized (mPackages) {
1134                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1135            }
1136            if (ivi == null) {
1137                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1138                        + verificationId + " packageName:" + packageName);
1139                return;
1140            }
1141            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1142                    "Updating IntentFilterVerificationInfo for package " + packageName
1143                            +" verificationId:" + verificationId);
1144
1145            synchronized (mPackages) {
1146                if (verified) {
1147                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1148                } else {
1149                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1150                }
1151                scheduleWriteSettingsLocked();
1152
1153                final int userId = ivs.getUserId();
1154                if (userId != UserHandle.USER_ALL) {
1155                    final int userStatus =
1156                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1157
1158                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1159                    boolean needUpdate = false;
1160
1161                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1162                    // already been set by the User thru the Disambiguation dialog
1163                    switch (userStatus) {
1164                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1165                            if (verified) {
1166                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1167                            } else {
1168                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1169                            }
1170                            needUpdate = true;
1171                            break;
1172
1173                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1174                            if (verified) {
1175                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1176                                needUpdate = true;
1177                            }
1178                            break;
1179
1180                        default:
1181                            // Nothing to do
1182                    }
1183
1184                    if (needUpdate) {
1185                        mSettings.updateIntentFilterVerificationStatusLPw(
1186                                packageName, updatedStatus, userId);
1187                        scheduleWritePackageRestrictionsLocked(userId);
1188                    }
1189                }
1190            }
1191        }
1192
1193        @Override
1194        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1195                    ActivityIntentInfo filter, String packageName) {
1196            if (!hasValidDomains(filter)) {
1197                return false;
1198            }
1199            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1200            if (ivs == null) {
1201                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1202                        packageName);
1203            }
1204            if (DEBUG_DOMAIN_VERIFICATION) {
1205                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1206            }
1207            ivs.addFilter(filter);
1208            return true;
1209        }
1210
1211        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1212                int userId, int verificationId, String packageName) {
1213            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1214                    verifierUid, userId, packageName);
1215            ivs.setPendingState();
1216            synchronized (mPackages) {
1217                mIntentFilterVerificationStates.append(verificationId, ivs);
1218                mCurrentIntentFilterVerifications.add(verificationId);
1219            }
1220            return ivs;
1221        }
1222    }
1223
1224    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1225        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1226                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1227                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1228    }
1229
1230    // Set of pending broadcasts for aggregating enable/disable of components.
1231    static class PendingPackageBroadcasts {
1232        // for each user id, a map of <package name -> components within that package>
1233        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1234
1235        public PendingPackageBroadcasts() {
1236            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1237        }
1238
1239        public ArrayList<String> get(int userId, String packageName) {
1240            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1241            return packages.get(packageName);
1242        }
1243
1244        public void put(int userId, String packageName, ArrayList<String> components) {
1245            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1246            packages.put(packageName, components);
1247        }
1248
1249        public void remove(int userId, String packageName) {
1250            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1251            if (packages != null) {
1252                packages.remove(packageName);
1253            }
1254        }
1255
1256        public void remove(int userId) {
1257            mUidMap.remove(userId);
1258        }
1259
1260        public int userIdCount() {
1261            return mUidMap.size();
1262        }
1263
1264        public int userIdAt(int n) {
1265            return mUidMap.keyAt(n);
1266        }
1267
1268        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1269            return mUidMap.get(userId);
1270        }
1271
1272        public int size() {
1273            // total number of pending broadcast entries across all userIds
1274            int num = 0;
1275            for (int i = 0; i< mUidMap.size(); i++) {
1276                num += mUidMap.valueAt(i).size();
1277            }
1278            return num;
1279        }
1280
1281        public void clear() {
1282            mUidMap.clear();
1283        }
1284
1285        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1286            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1287            if (map == null) {
1288                map = new ArrayMap<String, ArrayList<String>>();
1289                mUidMap.put(userId, map);
1290            }
1291            return map;
1292        }
1293    }
1294    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1295
1296    // Service Connection to remote media container service to copy
1297    // package uri's from external media onto secure containers
1298    // or internal storage.
1299    private IMediaContainerService mContainerService = null;
1300
1301    static final int SEND_PENDING_BROADCAST = 1;
1302    static final int MCS_BOUND = 3;
1303    static final int END_COPY = 4;
1304    static final int INIT_COPY = 5;
1305    static final int MCS_UNBIND = 6;
1306    static final int START_CLEANING_PACKAGE = 7;
1307    static final int FIND_INSTALL_LOC = 8;
1308    static final int POST_INSTALL = 9;
1309    static final int MCS_RECONNECT = 10;
1310    static final int MCS_GIVE_UP = 11;
1311    static final int UPDATED_MEDIA_STATUS = 12;
1312    static final int WRITE_SETTINGS = 13;
1313    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1314    static final int PACKAGE_VERIFIED = 15;
1315    static final int CHECK_PENDING_VERIFICATION = 16;
1316    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1317    static final int INTENT_FILTER_VERIFIED = 18;
1318    static final int WRITE_PACKAGE_LIST = 19;
1319    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1320
1321    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1322
1323    // Delay time in millisecs
1324    static final int BROADCAST_DELAY = 10 * 1000;
1325
1326    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1327            2 * 60 * 60 * 1000L; /* two hours */
1328
1329    static UserManagerService sUserManager;
1330
1331    // Stores a list of users whose package restrictions file needs to be updated
1332    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1333
1334    final private DefaultContainerConnection mDefContainerConn =
1335            new DefaultContainerConnection();
1336    class DefaultContainerConnection implements ServiceConnection {
1337        public void onServiceConnected(ComponentName name, IBinder service) {
1338            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1339            final IMediaContainerService imcs = IMediaContainerService.Stub
1340                    .asInterface(Binder.allowBlocking(service));
1341            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1342        }
1343
1344        public void onServiceDisconnected(ComponentName name) {
1345            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1346        }
1347    }
1348
1349    // Recordkeeping of restore-after-install operations that are currently in flight
1350    // between the Package Manager and the Backup Manager
1351    static class PostInstallData {
1352        public InstallArgs args;
1353        public PackageInstalledInfo res;
1354
1355        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1356            args = _a;
1357            res = _r;
1358        }
1359    }
1360
1361    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1362    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1363
1364    // XML tags for backup/restore of various bits of state
1365    private static final String TAG_PREFERRED_BACKUP = "pa";
1366    private static final String TAG_DEFAULT_APPS = "da";
1367    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1368
1369    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1370    private static final String TAG_ALL_GRANTS = "rt-grants";
1371    private static final String TAG_GRANT = "grant";
1372    private static final String ATTR_PACKAGE_NAME = "pkg";
1373
1374    private static final String TAG_PERMISSION = "perm";
1375    private static final String ATTR_PERMISSION_NAME = "name";
1376    private static final String ATTR_IS_GRANTED = "g";
1377    private static final String ATTR_USER_SET = "set";
1378    private static final String ATTR_USER_FIXED = "fixed";
1379    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1380
1381    // System/policy permission grants are not backed up
1382    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1383            FLAG_PERMISSION_POLICY_FIXED
1384            | FLAG_PERMISSION_SYSTEM_FIXED
1385            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1386
1387    // And we back up these user-adjusted states
1388    private static final int USER_RUNTIME_GRANT_MASK =
1389            FLAG_PERMISSION_USER_SET
1390            | FLAG_PERMISSION_USER_FIXED
1391            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1392
1393    final @Nullable String mRequiredVerifierPackage;
1394    final @NonNull String mRequiredInstallerPackage;
1395    final @NonNull String mRequiredUninstallerPackage;
1396    final @Nullable String mSetupWizardPackage;
1397    final @Nullable String mStorageManagerPackage;
1398    final @NonNull String mServicesSystemSharedLibraryPackageName;
1399    final @NonNull String mSharedSystemSharedLibraryPackageName;
1400
1401    final boolean mPermissionReviewRequired;
1402
1403    private final PackageUsage mPackageUsage = new PackageUsage();
1404    private final CompilerStats mCompilerStats = new CompilerStats();
1405
1406    class PackageHandler extends Handler {
1407        private boolean mBound = false;
1408        final ArrayList<HandlerParams> mPendingInstalls =
1409            new ArrayList<HandlerParams>();
1410
1411        private boolean connectToService() {
1412            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1413                    " DefaultContainerService");
1414            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1415            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1416            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1417                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1418                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1419                mBound = true;
1420                return true;
1421            }
1422            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1423            return false;
1424        }
1425
1426        private void disconnectService() {
1427            mContainerService = null;
1428            mBound = false;
1429            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1430            mContext.unbindService(mDefContainerConn);
1431            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1432        }
1433
1434        PackageHandler(Looper looper) {
1435            super(looper);
1436        }
1437
1438        public void handleMessage(Message msg) {
1439            try {
1440                doHandleMessage(msg);
1441            } finally {
1442                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1443            }
1444        }
1445
1446        void doHandleMessage(Message msg) {
1447            switch (msg.what) {
1448                case INIT_COPY: {
1449                    HandlerParams params = (HandlerParams) msg.obj;
1450                    int idx = mPendingInstalls.size();
1451                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1452                    // If a bind was already initiated we dont really
1453                    // need to do anything. The pending install
1454                    // will be processed later on.
1455                    if (!mBound) {
1456                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1457                                System.identityHashCode(mHandler));
1458                        // If this is the only one pending we might
1459                        // have to bind to the service again.
1460                        if (!connectToService()) {
1461                            Slog.e(TAG, "Failed to bind to media container service");
1462                            params.serviceError();
1463                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1464                                    System.identityHashCode(mHandler));
1465                            if (params.traceMethod != null) {
1466                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1467                                        params.traceCookie);
1468                            }
1469                            return;
1470                        } else {
1471                            // Once we bind to the service, the first
1472                            // pending request will be processed.
1473                            mPendingInstalls.add(idx, params);
1474                        }
1475                    } else {
1476                        mPendingInstalls.add(idx, params);
1477                        // Already bound to the service. Just make
1478                        // sure we trigger off processing the first request.
1479                        if (idx == 0) {
1480                            mHandler.sendEmptyMessage(MCS_BOUND);
1481                        }
1482                    }
1483                    break;
1484                }
1485                case MCS_BOUND: {
1486                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1487                    if (msg.obj != null) {
1488                        mContainerService = (IMediaContainerService) msg.obj;
1489                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1490                                System.identityHashCode(mHandler));
1491                    }
1492                    if (mContainerService == null) {
1493                        if (!mBound) {
1494                            // Something seriously wrong since we are not bound and we are not
1495                            // waiting for connection. Bail out.
1496                            Slog.e(TAG, "Cannot bind to media container service");
1497                            for (HandlerParams params : mPendingInstalls) {
1498                                // Indicate service bind error
1499                                params.serviceError();
1500                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1501                                        System.identityHashCode(params));
1502                                if (params.traceMethod != null) {
1503                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1504                                            params.traceMethod, params.traceCookie);
1505                                }
1506                                return;
1507                            }
1508                            mPendingInstalls.clear();
1509                        } else {
1510                            Slog.w(TAG, "Waiting to connect to media container service");
1511                        }
1512                    } else if (mPendingInstalls.size() > 0) {
1513                        HandlerParams params = mPendingInstalls.get(0);
1514                        if (params != null) {
1515                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1516                                    System.identityHashCode(params));
1517                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1518                            if (params.startCopy()) {
1519                                // We are done...  look for more work or to
1520                                // go idle.
1521                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1522                                        "Checking for more work or unbind...");
1523                                // Delete pending install
1524                                if (mPendingInstalls.size() > 0) {
1525                                    mPendingInstalls.remove(0);
1526                                }
1527                                if (mPendingInstalls.size() == 0) {
1528                                    if (mBound) {
1529                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1530                                                "Posting delayed MCS_UNBIND");
1531                                        removeMessages(MCS_UNBIND);
1532                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1533                                        // Unbind after a little delay, to avoid
1534                                        // continual thrashing.
1535                                        sendMessageDelayed(ubmsg, 10000);
1536                                    }
1537                                } else {
1538                                    // There are more pending requests in queue.
1539                                    // Just post MCS_BOUND message to trigger processing
1540                                    // of next pending install.
1541                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1542                                            "Posting MCS_BOUND for next work");
1543                                    mHandler.sendEmptyMessage(MCS_BOUND);
1544                                }
1545                            }
1546                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1547                        }
1548                    } else {
1549                        // Should never happen ideally.
1550                        Slog.w(TAG, "Empty queue");
1551                    }
1552                    break;
1553                }
1554                case MCS_RECONNECT: {
1555                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1556                    if (mPendingInstalls.size() > 0) {
1557                        if (mBound) {
1558                            disconnectService();
1559                        }
1560                        if (!connectToService()) {
1561                            Slog.e(TAG, "Failed to bind to media container service");
1562                            for (HandlerParams params : mPendingInstalls) {
1563                                // Indicate service bind error
1564                                params.serviceError();
1565                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1566                                        System.identityHashCode(params));
1567                            }
1568                            mPendingInstalls.clear();
1569                        }
1570                    }
1571                    break;
1572                }
1573                case MCS_UNBIND: {
1574                    // If there is no actual work left, then time to unbind.
1575                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1576
1577                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1578                        if (mBound) {
1579                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1580
1581                            disconnectService();
1582                        }
1583                    } else if (mPendingInstalls.size() > 0) {
1584                        // There are more pending requests in queue.
1585                        // Just post MCS_BOUND message to trigger processing
1586                        // of next pending install.
1587                        mHandler.sendEmptyMessage(MCS_BOUND);
1588                    }
1589
1590                    break;
1591                }
1592                case MCS_GIVE_UP: {
1593                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1594                    HandlerParams params = mPendingInstalls.remove(0);
1595                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1596                            System.identityHashCode(params));
1597                    break;
1598                }
1599                case SEND_PENDING_BROADCAST: {
1600                    String packages[];
1601                    ArrayList<String> components[];
1602                    int size = 0;
1603                    int uids[];
1604                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1605                    synchronized (mPackages) {
1606                        if (mPendingBroadcasts == null) {
1607                            return;
1608                        }
1609                        size = mPendingBroadcasts.size();
1610                        if (size <= 0) {
1611                            // Nothing to be done. Just return
1612                            return;
1613                        }
1614                        packages = new String[size];
1615                        components = new ArrayList[size];
1616                        uids = new int[size];
1617                        int i = 0;  // filling out the above arrays
1618
1619                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1620                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1621                            Iterator<Map.Entry<String, ArrayList<String>>> it
1622                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1623                                            .entrySet().iterator();
1624                            while (it.hasNext() && i < size) {
1625                                Map.Entry<String, ArrayList<String>> ent = it.next();
1626                                packages[i] = ent.getKey();
1627                                components[i] = ent.getValue();
1628                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1629                                uids[i] = (ps != null)
1630                                        ? UserHandle.getUid(packageUserId, ps.appId)
1631                                        : -1;
1632                                i++;
1633                            }
1634                        }
1635                        size = i;
1636                        mPendingBroadcasts.clear();
1637                    }
1638                    // Send broadcasts
1639                    for (int i = 0; i < size; i++) {
1640                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1641                    }
1642                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1643                    break;
1644                }
1645                case START_CLEANING_PACKAGE: {
1646                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1647                    final String packageName = (String)msg.obj;
1648                    final int userId = msg.arg1;
1649                    final boolean andCode = msg.arg2 != 0;
1650                    synchronized (mPackages) {
1651                        if (userId == UserHandle.USER_ALL) {
1652                            int[] users = sUserManager.getUserIds();
1653                            for (int user : users) {
1654                                mSettings.addPackageToCleanLPw(
1655                                        new PackageCleanItem(user, packageName, andCode));
1656                            }
1657                        } else {
1658                            mSettings.addPackageToCleanLPw(
1659                                    new PackageCleanItem(userId, packageName, andCode));
1660                        }
1661                    }
1662                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1663                    startCleaningPackages();
1664                } break;
1665                case POST_INSTALL: {
1666                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1667
1668                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1669                    final boolean didRestore = (msg.arg2 != 0);
1670                    mRunningInstalls.delete(msg.arg1);
1671
1672                    if (data != null) {
1673                        InstallArgs args = data.args;
1674                        PackageInstalledInfo parentRes = data.res;
1675
1676                        final boolean grantPermissions = (args.installFlags
1677                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1678                        final boolean killApp = (args.installFlags
1679                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1680                        final boolean virtualPreload = ((args.installFlags
1681                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1682                        final String[] grantedPermissions = args.installGrantPermissions;
1683
1684                        // Handle the parent package
1685                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1686                                virtualPreload, grantedPermissions, didRestore,
1687                                args.installerPackageName, args.observer);
1688
1689                        // Handle the child packages
1690                        final int childCount = (parentRes.addedChildPackages != null)
1691                                ? parentRes.addedChildPackages.size() : 0;
1692                        for (int i = 0; i < childCount; i++) {
1693                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1694                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1695                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1696                                    args.installerPackageName, args.observer);
1697                        }
1698
1699                        // Log tracing if needed
1700                        if (args.traceMethod != null) {
1701                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1702                                    args.traceCookie);
1703                        }
1704                    } else {
1705                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1706                    }
1707
1708                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1709                } break;
1710                case UPDATED_MEDIA_STATUS: {
1711                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1712                    boolean reportStatus = msg.arg1 == 1;
1713                    boolean doGc = msg.arg2 == 1;
1714                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1715                    if (doGc) {
1716                        // Force a gc to clear up stale containers.
1717                        Runtime.getRuntime().gc();
1718                    }
1719                    if (msg.obj != null) {
1720                        @SuppressWarnings("unchecked")
1721                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1722                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1723                        // Unload containers
1724                        unloadAllContainers(args);
1725                    }
1726                    if (reportStatus) {
1727                        try {
1728                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1729                                    "Invoking StorageManagerService call back");
1730                            PackageHelper.getStorageManager().finishMediaUpdate();
1731                        } catch (RemoteException e) {
1732                            Log.e(TAG, "StorageManagerService not running?");
1733                        }
1734                    }
1735                } break;
1736                case WRITE_SETTINGS: {
1737                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1738                    synchronized (mPackages) {
1739                        removeMessages(WRITE_SETTINGS);
1740                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1741                        mSettings.writeLPr();
1742                        mDirtyUsers.clear();
1743                    }
1744                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1745                } break;
1746                case WRITE_PACKAGE_RESTRICTIONS: {
1747                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1748                    synchronized (mPackages) {
1749                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1750                        for (int userId : mDirtyUsers) {
1751                            mSettings.writePackageRestrictionsLPr(userId);
1752                        }
1753                        mDirtyUsers.clear();
1754                    }
1755                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1756                } break;
1757                case WRITE_PACKAGE_LIST: {
1758                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1759                    synchronized (mPackages) {
1760                        removeMessages(WRITE_PACKAGE_LIST);
1761                        mSettings.writePackageListLPr(msg.arg1);
1762                    }
1763                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1764                } break;
1765                case CHECK_PENDING_VERIFICATION: {
1766                    final int verificationId = msg.arg1;
1767                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1768
1769                    if ((state != null) && !state.timeoutExtended()) {
1770                        final InstallArgs args = state.getInstallArgs();
1771                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1772
1773                        Slog.i(TAG, "Verification timed out for " + originUri);
1774                        mPendingVerification.remove(verificationId);
1775
1776                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1777
1778                        final UserHandle user = args.getUser();
1779                        if (getDefaultVerificationResponse(user)
1780                                == PackageManager.VERIFICATION_ALLOW) {
1781                            Slog.i(TAG, "Continuing with installation of " + originUri);
1782                            state.setVerifierResponse(Binder.getCallingUid(),
1783                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1784                            broadcastPackageVerified(verificationId, originUri,
1785                                    PackageManager.VERIFICATION_ALLOW, user);
1786                            try {
1787                                ret = args.copyApk(mContainerService, true);
1788                            } catch (RemoteException e) {
1789                                Slog.e(TAG, "Could not contact the ContainerService");
1790                            }
1791                        } else {
1792                            broadcastPackageVerified(verificationId, originUri,
1793                                    PackageManager.VERIFICATION_REJECT, user);
1794                        }
1795
1796                        Trace.asyncTraceEnd(
1797                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1798
1799                        processPendingInstall(args, ret);
1800                        mHandler.sendEmptyMessage(MCS_UNBIND);
1801                    }
1802                    break;
1803                }
1804                case PACKAGE_VERIFIED: {
1805                    final int verificationId = msg.arg1;
1806
1807                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1808                    if (state == null) {
1809                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1810                        break;
1811                    }
1812
1813                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1814
1815                    state.setVerifierResponse(response.callerUid, response.code);
1816
1817                    if (state.isVerificationComplete()) {
1818                        mPendingVerification.remove(verificationId);
1819
1820                        final InstallArgs args = state.getInstallArgs();
1821                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1822
1823                        int ret;
1824                        if (state.isInstallAllowed()) {
1825                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1826                            broadcastPackageVerified(verificationId, originUri,
1827                                    response.code, state.getInstallArgs().getUser());
1828                            try {
1829                                ret = args.copyApk(mContainerService, true);
1830                            } catch (RemoteException e) {
1831                                Slog.e(TAG, "Could not contact the ContainerService");
1832                            }
1833                        } else {
1834                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1835                        }
1836
1837                        Trace.asyncTraceEnd(
1838                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1839
1840                        processPendingInstall(args, ret);
1841                        mHandler.sendEmptyMessage(MCS_UNBIND);
1842                    }
1843
1844                    break;
1845                }
1846                case START_INTENT_FILTER_VERIFICATIONS: {
1847                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1848                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1849                            params.replacing, params.pkg);
1850                    break;
1851                }
1852                case INTENT_FILTER_VERIFIED: {
1853                    final int verificationId = msg.arg1;
1854
1855                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1856                            verificationId);
1857                    if (state == null) {
1858                        Slog.w(TAG, "Invalid IntentFilter verification token "
1859                                + verificationId + " received");
1860                        break;
1861                    }
1862
1863                    final int userId = state.getUserId();
1864
1865                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1866                            "Processing IntentFilter verification with token:"
1867                            + verificationId + " and userId:" + userId);
1868
1869                    final IntentFilterVerificationResponse response =
1870                            (IntentFilterVerificationResponse) msg.obj;
1871
1872                    state.setVerifierResponse(response.callerUid, response.code);
1873
1874                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1875                            "IntentFilter verification with token:" + verificationId
1876                            + " and userId:" + userId
1877                            + " is settings verifier response with response code:"
1878                            + response.code);
1879
1880                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1881                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1882                                + response.getFailedDomainsString());
1883                    }
1884
1885                    if (state.isVerificationComplete()) {
1886                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1887                    } else {
1888                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1889                                "IntentFilter verification with token:" + verificationId
1890                                + " was not said to be complete");
1891                    }
1892
1893                    break;
1894                }
1895                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1896                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1897                            mInstantAppResolverConnection,
1898                            (InstantAppRequest) msg.obj,
1899                            mInstantAppInstallerActivity,
1900                            mHandler);
1901                }
1902            }
1903        }
1904    }
1905
1906    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1907            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1908            boolean launchedForRestore, String installerPackage,
1909            IPackageInstallObserver2 installObserver) {
1910        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1911            // Send the removed broadcasts
1912            if (res.removedInfo != null) {
1913                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1914            }
1915
1916            // Now that we successfully installed the package, grant runtime
1917            // permissions if requested before broadcasting the install. Also
1918            // for legacy apps in permission review mode we clear the permission
1919            // review flag which is used to emulate runtime permissions for
1920            // legacy apps.
1921            if (grantPermissions) {
1922                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1923            }
1924
1925            final boolean update = res.removedInfo != null
1926                    && res.removedInfo.removedPackage != null;
1927            final String origInstallerPackageName = res.removedInfo != null
1928                    ? res.removedInfo.installerPackageName : null;
1929
1930            // If this is the first time we have child packages for a disabled privileged
1931            // app that had no children, we grant requested runtime permissions to the new
1932            // children if the parent on the system image had them already granted.
1933            if (res.pkg.parentPackage != null) {
1934                synchronized (mPackages) {
1935                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1936                }
1937            }
1938
1939            synchronized (mPackages) {
1940                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1941            }
1942
1943            final String packageName = res.pkg.applicationInfo.packageName;
1944
1945            // Determine the set of users who are adding this package for
1946            // the first time vs. those who are seeing an update.
1947            int[] firstUsers = EMPTY_INT_ARRAY;
1948            int[] updateUsers = EMPTY_INT_ARRAY;
1949            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1950            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1951            for (int newUser : res.newUsers) {
1952                if (ps.getInstantApp(newUser)) {
1953                    continue;
1954                }
1955                if (allNewUsers) {
1956                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1957                    continue;
1958                }
1959                boolean isNew = true;
1960                for (int origUser : res.origUsers) {
1961                    if (origUser == newUser) {
1962                        isNew = false;
1963                        break;
1964                    }
1965                }
1966                if (isNew) {
1967                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1968                } else {
1969                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1970                }
1971            }
1972
1973            // Send installed broadcasts if the package is not a static shared lib.
1974            if (res.pkg.staticSharedLibName == null) {
1975                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1976
1977                // Send added for users that see the package for the first time
1978                // sendPackageAddedForNewUsers also deals with system apps
1979                int appId = UserHandle.getAppId(res.uid);
1980                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1981                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1982                        virtualPreload /*startReceiver*/, appId, firstUsers);
1983
1984                // Send added for users that don't see the package for the first time
1985                Bundle extras = new Bundle(1);
1986                extras.putInt(Intent.EXTRA_UID, res.uid);
1987                if (update) {
1988                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1989                }
1990                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1991                        extras, 0 /*flags*/,
1992                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1993                if (origInstallerPackageName != null) {
1994                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1995                            extras, 0 /*flags*/,
1996                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1997                }
1998
1999                // Send replaced for users that don't see the package for the first time
2000                if (update) {
2001                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2002                            packageName, extras, 0 /*flags*/,
2003                            null /*targetPackage*/, null /*finishedReceiver*/,
2004                            updateUsers);
2005                    if (origInstallerPackageName != null) {
2006                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2007                                extras, 0 /*flags*/,
2008                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
2009                    }
2010                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2011                            null /*package*/, null /*extras*/, 0 /*flags*/,
2012                            packageName /*targetPackage*/,
2013                            null /*finishedReceiver*/, updateUsers);
2014                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2015                    // First-install and we did a restore, so we're responsible for the
2016                    // first-launch broadcast.
2017                    if (DEBUG_BACKUP) {
2018                        Slog.i(TAG, "Post-restore of " + packageName
2019                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2020                    }
2021                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2022                }
2023
2024                // Send broadcast package appeared if forward locked/external for all users
2025                // treat asec-hosted packages like removable media on upgrade
2026                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2027                    if (DEBUG_INSTALL) {
2028                        Slog.i(TAG, "upgrading pkg " + res.pkg
2029                                + " is ASEC-hosted -> AVAILABLE");
2030                    }
2031                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2032                    ArrayList<String> pkgList = new ArrayList<>(1);
2033                    pkgList.add(packageName);
2034                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2035                }
2036            }
2037
2038            // Work that needs to happen on first install within each user
2039            if (firstUsers != null && firstUsers.length > 0) {
2040                synchronized (mPackages) {
2041                    for (int userId : firstUsers) {
2042                        // If this app is a browser and it's newly-installed for some
2043                        // users, clear any default-browser state in those users. The
2044                        // app's nature doesn't depend on the user, so we can just check
2045                        // its browser nature in any user and generalize.
2046                        if (packageIsBrowser(packageName, userId)) {
2047                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2048                        }
2049
2050                        // We may also need to apply pending (restored) runtime
2051                        // permission grants within these users.
2052                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2053                    }
2054                }
2055            }
2056
2057            // Log current value of "unknown sources" setting
2058            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2059                    getUnknownSourcesSettings());
2060
2061            // Remove the replaced package's older resources safely now
2062            // We delete after a gc for applications  on sdcard.
2063            if (res.removedInfo != null && res.removedInfo.args != null) {
2064                Runtime.getRuntime().gc();
2065                synchronized (mInstallLock) {
2066                    res.removedInfo.args.doPostDeleteLI(true);
2067                }
2068            } else {
2069                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2070                // and not block here.
2071                VMRuntime.getRuntime().requestConcurrentGC();
2072            }
2073
2074            // Notify DexManager that the package was installed for new users.
2075            // The updated users should already be indexed and the package code paths
2076            // should not change.
2077            // Don't notify the manager for ephemeral apps as they are not expected to
2078            // survive long enough to benefit of background optimizations.
2079            for (int userId : firstUsers) {
2080                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2081                // There's a race currently where some install events may interleave with an uninstall.
2082                // This can lead to package info being null (b/36642664).
2083                if (info != null) {
2084                    mDexManager.notifyPackageInstalled(info, userId);
2085                }
2086            }
2087        }
2088
2089        // If someone is watching installs - notify them
2090        if (installObserver != null) {
2091            try {
2092                Bundle extras = extrasForInstallResult(res);
2093                installObserver.onPackageInstalled(res.name, res.returnCode,
2094                        res.returnMsg, extras);
2095            } catch (RemoteException e) {
2096                Slog.i(TAG, "Observer no longer exists.");
2097            }
2098        }
2099    }
2100
2101    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2102            PackageParser.Package pkg) {
2103        if (pkg.parentPackage == null) {
2104            return;
2105        }
2106        if (pkg.requestedPermissions == null) {
2107            return;
2108        }
2109        final PackageSetting disabledSysParentPs = mSettings
2110                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2111        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2112                || !disabledSysParentPs.isPrivileged()
2113                || (disabledSysParentPs.childPackageNames != null
2114                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2115            return;
2116        }
2117        final int[] allUserIds = sUserManager.getUserIds();
2118        final int permCount = pkg.requestedPermissions.size();
2119        for (int i = 0; i < permCount; i++) {
2120            String permission = pkg.requestedPermissions.get(i);
2121            BasePermission bp = mSettings.mPermissions.get(permission);
2122            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2123                continue;
2124            }
2125            for (int userId : allUserIds) {
2126                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2127                        permission, userId)) {
2128                    grantRuntimePermission(pkg.packageName, permission, userId);
2129                }
2130            }
2131        }
2132    }
2133
2134    private StorageEventListener mStorageListener = new StorageEventListener() {
2135        @Override
2136        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2137            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2138                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2139                    final String volumeUuid = vol.getFsUuid();
2140
2141                    // Clean up any users or apps that were removed or recreated
2142                    // while this volume was missing
2143                    sUserManager.reconcileUsers(volumeUuid);
2144                    reconcileApps(volumeUuid);
2145
2146                    // Clean up any install sessions that expired or were
2147                    // cancelled while this volume was missing
2148                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2149
2150                    loadPrivatePackages(vol);
2151
2152                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2153                    unloadPrivatePackages(vol);
2154                }
2155            }
2156
2157            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2158                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2159                    updateExternalMediaStatus(true, false);
2160                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2161                    updateExternalMediaStatus(false, false);
2162                }
2163            }
2164        }
2165
2166        @Override
2167        public void onVolumeForgotten(String fsUuid) {
2168            if (TextUtils.isEmpty(fsUuid)) {
2169                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2170                return;
2171            }
2172
2173            // Remove any apps installed on the forgotten volume
2174            synchronized (mPackages) {
2175                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2176                for (PackageSetting ps : packages) {
2177                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2178                    deletePackageVersioned(new VersionedPackage(ps.name,
2179                            PackageManager.VERSION_CODE_HIGHEST),
2180                            new LegacyPackageDeleteObserver(null).getBinder(),
2181                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2182                    // Try very hard to release any references to this package
2183                    // so we don't risk the system server being killed due to
2184                    // open FDs
2185                    AttributeCache.instance().removePackage(ps.name);
2186                }
2187
2188                mSettings.onVolumeForgotten(fsUuid);
2189                mSettings.writeLPr();
2190            }
2191        }
2192    };
2193
2194    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2195            String[] grantedPermissions) {
2196        for (int userId : userIds) {
2197            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2198        }
2199    }
2200
2201    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2202            String[] grantedPermissions) {
2203        PackageSetting ps = (PackageSetting) pkg.mExtras;
2204        if (ps == null) {
2205            return;
2206        }
2207
2208        PermissionsState permissionsState = ps.getPermissionsState();
2209
2210        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2211                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2212
2213        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2214                >= Build.VERSION_CODES.M;
2215
2216        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2217
2218        for (String permission : pkg.requestedPermissions) {
2219            final BasePermission bp;
2220            synchronized (mPackages) {
2221                bp = mSettings.mPermissions.get(permission);
2222            }
2223            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2224                    && (!instantApp || bp.isInstant())
2225                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2226                    && (grantedPermissions == null
2227                           || ArrayUtils.contains(grantedPermissions, permission))) {
2228                final int flags = permissionsState.getPermissionFlags(permission, userId);
2229                if (supportsRuntimePermissions) {
2230                    // Installer cannot change immutable permissions.
2231                    if ((flags & immutableFlags) == 0) {
2232                        grantRuntimePermission(pkg.packageName, permission, userId);
2233                    }
2234                } else if (mPermissionReviewRequired) {
2235                    // In permission review mode we clear the review flag when we
2236                    // are asked to install the app with all permissions granted.
2237                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2238                        updatePermissionFlags(permission, pkg.packageName,
2239                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2240                    }
2241                }
2242            }
2243        }
2244    }
2245
2246    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2247        Bundle extras = null;
2248        switch (res.returnCode) {
2249            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2250                extras = new Bundle();
2251                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2252                        res.origPermission);
2253                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2254                        res.origPackage);
2255                break;
2256            }
2257            case PackageManager.INSTALL_SUCCEEDED: {
2258                extras = new Bundle();
2259                extras.putBoolean(Intent.EXTRA_REPLACING,
2260                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2261                break;
2262            }
2263        }
2264        return extras;
2265    }
2266
2267    void scheduleWriteSettingsLocked() {
2268        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2269            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2270        }
2271    }
2272
2273    void scheduleWritePackageListLocked(int userId) {
2274        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2275            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2276            msg.arg1 = userId;
2277            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2278        }
2279    }
2280
2281    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2282        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2283        scheduleWritePackageRestrictionsLocked(userId);
2284    }
2285
2286    void scheduleWritePackageRestrictionsLocked(int userId) {
2287        final int[] userIds = (userId == UserHandle.USER_ALL)
2288                ? sUserManager.getUserIds() : new int[]{userId};
2289        for (int nextUserId : userIds) {
2290            if (!sUserManager.exists(nextUserId)) return;
2291            mDirtyUsers.add(nextUserId);
2292            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2293                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2294            }
2295        }
2296    }
2297
2298    public static PackageManagerService main(Context context, Installer installer,
2299            boolean factoryTest, boolean onlyCore) {
2300        // Self-check for initial settings.
2301        PackageManagerServiceCompilerMapping.checkProperties();
2302
2303        PackageManagerService m = new PackageManagerService(context, installer,
2304                factoryTest, onlyCore);
2305        m.enableSystemUserPackages();
2306        ServiceManager.addService("package", m);
2307        return m;
2308    }
2309
2310    private void enableSystemUserPackages() {
2311        if (!UserManager.isSplitSystemUser()) {
2312            return;
2313        }
2314        // For system user, enable apps based on the following conditions:
2315        // - app is whitelisted or belong to one of these groups:
2316        //   -- system app which has no launcher icons
2317        //   -- system app which has INTERACT_ACROSS_USERS permission
2318        //   -- system IME app
2319        // - app is not in the blacklist
2320        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2321        Set<String> enableApps = new ArraySet<>();
2322        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2323                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2324                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2325        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2326        enableApps.addAll(wlApps);
2327        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2328                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2329        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2330        enableApps.removeAll(blApps);
2331        Log.i(TAG, "Applications installed for system user: " + enableApps);
2332        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2333                UserHandle.SYSTEM);
2334        final int allAppsSize = allAps.size();
2335        synchronized (mPackages) {
2336            for (int i = 0; i < allAppsSize; i++) {
2337                String pName = allAps.get(i);
2338                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2339                // Should not happen, but we shouldn't be failing if it does
2340                if (pkgSetting == null) {
2341                    continue;
2342                }
2343                boolean install = enableApps.contains(pName);
2344                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2345                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2346                            + " for system user");
2347                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2348                }
2349            }
2350            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2351        }
2352    }
2353
2354    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2355        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2356                Context.DISPLAY_SERVICE);
2357        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2358    }
2359
2360    /**
2361     * Requests that files preopted on a secondary system partition be copied to the data partition
2362     * if possible.  Note that the actual copying of the files is accomplished by init for security
2363     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2364     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2365     */
2366    private static void requestCopyPreoptedFiles() {
2367        final int WAIT_TIME_MS = 100;
2368        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2369        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2370            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2371            // We will wait for up to 100 seconds.
2372            final long timeStart = SystemClock.uptimeMillis();
2373            final long timeEnd = timeStart + 100 * 1000;
2374            long timeNow = timeStart;
2375            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2376                try {
2377                    Thread.sleep(WAIT_TIME_MS);
2378                } catch (InterruptedException e) {
2379                    // Do nothing
2380                }
2381                timeNow = SystemClock.uptimeMillis();
2382                if (timeNow > timeEnd) {
2383                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2384                    Slog.wtf(TAG, "cppreopt did not finish!");
2385                    break;
2386                }
2387            }
2388
2389            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2390        }
2391    }
2392
2393    public PackageManagerService(Context context, Installer installer,
2394            boolean factoryTest, boolean onlyCore) {
2395        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2396        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2397        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2398                SystemClock.uptimeMillis());
2399
2400        if (mSdkVersion <= 0) {
2401            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2402        }
2403
2404        mContext = context;
2405
2406        mPermissionReviewRequired = context.getResources().getBoolean(
2407                R.bool.config_permissionReviewRequired);
2408
2409        mFactoryTest = factoryTest;
2410        mOnlyCore = onlyCore;
2411        mMetrics = new DisplayMetrics();
2412        mSettings = new Settings(mPackages);
2413        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2414                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2415        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2416                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2417        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2418                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2419        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2420                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2421        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2422                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2423        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2424                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2425
2426        String separateProcesses = SystemProperties.get("debug.separate_processes");
2427        if (separateProcesses != null && separateProcesses.length() > 0) {
2428            if ("*".equals(separateProcesses)) {
2429                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2430                mSeparateProcesses = null;
2431                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2432            } else {
2433                mDefParseFlags = 0;
2434                mSeparateProcesses = separateProcesses.split(",");
2435                Slog.w(TAG, "Running with debug.separate_processes: "
2436                        + separateProcesses);
2437            }
2438        } else {
2439            mDefParseFlags = 0;
2440            mSeparateProcesses = null;
2441        }
2442
2443        mInstaller = installer;
2444        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2445                "*dexopt*");
2446        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2447        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2448
2449        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2450                FgThread.get().getLooper());
2451
2452        getDefaultDisplayMetrics(context, mMetrics);
2453
2454        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2455        SystemConfig systemConfig = SystemConfig.getInstance();
2456        mGlobalGids = systemConfig.getGlobalGids();
2457        mSystemPermissions = systemConfig.getSystemPermissions();
2458        mAvailableFeatures = systemConfig.getAvailableFeatures();
2459        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2460
2461        mProtectedPackages = new ProtectedPackages(mContext);
2462
2463        synchronized (mInstallLock) {
2464        // writer
2465        synchronized (mPackages) {
2466            mHandlerThread = new ServiceThread(TAG,
2467                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2468            mHandlerThread.start();
2469            mHandler = new PackageHandler(mHandlerThread.getLooper());
2470            mProcessLoggingHandler = new ProcessLoggingHandler();
2471            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2472
2473            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2474            mInstantAppRegistry = new InstantAppRegistry(this);
2475
2476            File dataDir = Environment.getDataDirectory();
2477            mAppInstallDir = new File(dataDir, "app");
2478            mAppLib32InstallDir = new File(dataDir, "app-lib");
2479            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2480            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2481            sUserManager = new UserManagerService(context, this,
2482                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2483
2484            // Propagate permission configuration in to package manager.
2485            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2486                    = systemConfig.getPermissions();
2487            for (int i=0; i<permConfig.size(); i++) {
2488                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2489                BasePermission bp = mSettings.mPermissions.get(perm.name);
2490                if (bp == null) {
2491                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2492                    mSettings.mPermissions.put(perm.name, bp);
2493                }
2494                if (perm.gids != null) {
2495                    bp.setGids(perm.gids, perm.perUser);
2496                }
2497            }
2498
2499            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2500            final int builtInLibCount = libConfig.size();
2501            for (int i = 0; i < builtInLibCount; i++) {
2502                String name = libConfig.keyAt(i);
2503                String path = libConfig.valueAt(i);
2504                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2505                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2506            }
2507
2508            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2509
2510            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2511            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2512            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2513
2514            // Clean up orphaned packages for which the code path doesn't exist
2515            // and they are an update to a system app - caused by bug/32321269
2516            final int packageSettingCount = mSettings.mPackages.size();
2517            for (int i = packageSettingCount - 1; i >= 0; i--) {
2518                PackageSetting ps = mSettings.mPackages.valueAt(i);
2519                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2520                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2521                    mSettings.mPackages.removeAt(i);
2522                    mSettings.enableSystemPackageLPw(ps.name);
2523                }
2524            }
2525
2526            if (mFirstBoot) {
2527                requestCopyPreoptedFiles();
2528            }
2529
2530            String customResolverActivity = Resources.getSystem().getString(
2531                    R.string.config_customResolverActivity);
2532            if (TextUtils.isEmpty(customResolverActivity)) {
2533                customResolverActivity = null;
2534            } else {
2535                mCustomResolverComponentName = ComponentName.unflattenFromString(
2536                        customResolverActivity);
2537            }
2538
2539            long startTime = SystemClock.uptimeMillis();
2540
2541            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2542                    startTime);
2543
2544            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2545            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2546
2547            if (bootClassPath == null) {
2548                Slog.w(TAG, "No BOOTCLASSPATH found!");
2549            }
2550
2551            if (systemServerClassPath == null) {
2552                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2553            }
2554
2555            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2556
2557            final VersionInfo ver = mSettings.getInternalVersion();
2558            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2559            if (mIsUpgrade) {
2560                logCriticalInfo(Log.INFO,
2561                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2562            }
2563
2564            // when upgrading from pre-M, promote system app permissions from install to runtime
2565            mPromoteSystemApps =
2566                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2567
2568            // When upgrading from pre-N, we need to handle package extraction like first boot,
2569            // as there is no profiling data available.
2570            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2571
2572            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2573
2574            // save off the names of pre-existing system packages prior to scanning; we don't
2575            // want to automatically grant runtime permissions for new system apps
2576            if (mPromoteSystemApps) {
2577                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2578                while (pkgSettingIter.hasNext()) {
2579                    PackageSetting ps = pkgSettingIter.next();
2580                    if (isSystemApp(ps)) {
2581                        mExistingSystemPackages.add(ps.name);
2582                    }
2583                }
2584            }
2585
2586            mCacheDir = preparePackageParserCache(mIsUpgrade);
2587
2588            // Set flag to monitor and not change apk file paths when
2589            // scanning install directories.
2590            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2591
2592            if (mIsUpgrade || mFirstBoot) {
2593                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2594            }
2595
2596            // Collect vendor overlay packages. (Do this before scanning any apps.)
2597            // For security and version matching reason, only consider
2598            // overlay packages if they reside in the right directory.
2599            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2600                    | PackageParser.PARSE_IS_SYSTEM
2601                    | PackageParser.PARSE_IS_SYSTEM_DIR
2602                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2603
2604            mParallelPackageParserCallback.findStaticOverlayPackages();
2605
2606            // Find base frameworks (resource packages without code).
2607            scanDirTracedLI(frameworkDir, mDefParseFlags
2608                    | PackageParser.PARSE_IS_SYSTEM
2609                    | PackageParser.PARSE_IS_SYSTEM_DIR
2610                    | PackageParser.PARSE_IS_PRIVILEGED,
2611                    scanFlags | SCAN_NO_DEX, 0);
2612
2613            // Collected privileged system packages.
2614            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2615            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2616                    | PackageParser.PARSE_IS_SYSTEM
2617                    | PackageParser.PARSE_IS_SYSTEM_DIR
2618                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2619
2620            // Collect ordinary system packages.
2621            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2622            scanDirTracedLI(systemAppDir, mDefParseFlags
2623                    | PackageParser.PARSE_IS_SYSTEM
2624                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2625
2626            // Collect all vendor packages.
2627            File vendorAppDir = new File("/vendor/app");
2628            try {
2629                vendorAppDir = vendorAppDir.getCanonicalFile();
2630            } catch (IOException e) {
2631                // failed to look up canonical path, continue with original one
2632            }
2633            scanDirTracedLI(vendorAppDir, mDefParseFlags
2634                    | PackageParser.PARSE_IS_SYSTEM
2635                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2636
2637            // Collect all OEM packages.
2638            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2639            scanDirTracedLI(oemAppDir, mDefParseFlags
2640                    | PackageParser.PARSE_IS_SYSTEM
2641                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2642
2643            // Prune any system packages that no longer exist.
2644            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2645            // Stub packages must either be replaced with full versions in the /data
2646            // partition or be disabled.
2647            final List<String> stubSystemApps = new ArrayList<>();
2648            if (!mOnlyCore) {
2649                // do this first before mucking with mPackages for the "expecting better" case
2650                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2651                while (pkgIterator.hasNext()) {
2652                    final PackageParser.Package pkg = pkgIterator.next();
2653                    if (pkg.isStub) {
2654                        stubSystemApps.add(pkg.packageName);
2655                    }
2656                }
2657
2658                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2659                while (psit.hasNext()) {
2660                    PackageSetting ps = psit.next();
2661
2662                    /*
2663                     * If this is not a system app, it can't be a
2664                     * disable system app.
2665                     */
2666                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2667                        continue;
2668                    }
2669
2670                    /*
2671                     * If the package is scanned, it's not erased.
2672                     */
2673                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2674                    if (scannedPkg != null) {
2675                        /*
2676                         * If the system app is both scanned and in the
2677                         * disabled packages list, then it must have been
2678                         * added via OTA. Remove it from the currently
2679                         * scanned package so the previously user-installed
2680                         * application can be scanned.
2681                         */
2682                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2683                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2684                                    + ps.name + "; removing system app.  Last known codePath="
2685                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2686                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2687                                    + scannedPkg.mVersionCode);
2688                            removePackageLI(scannedPkg, true);
2689                            mExpectingBetter.put(ps.name, ps.codePath);
2690                        }
2691
2692                        continue;
2693                    }
2694
2695                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2696                        psit.remove();
2697                        logCriticalInfo(Log.WARN, "System package " + ps.name
2698                                + " no longer exists; it's data will be wiped");
2699                        // Actual deletion of code and data will be handled by later
2700                        // reconciliation step
2701                    } else {
2702                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2703                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2704                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2705                        }
2706                    }
2707                }
2708            }
2709
2710            //look for any incomplete package installations
2711            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2712            for (int i = 0; i < deletePkgsList.size(); i++) {
2713                // Actual deletion of code and data will be handled by later
2714                // reconciliation step
2715                final String packageName = deletePkgsList.get(i).name;
2716                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2717                synchronized (mPackages) {
2718                    mSettings.removePackageLPw(packageName);
2719                }
2720            }
2721
2722            //delete tmp files
2723            deleteTempPackageFiles();
2724
2725            // Remove any shared userIDs that have no associated packages
2726            mSettings.pruneSharedUsersLPw();
2727            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2728            final int systemPackagesCount = mPackages.size();
2729            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2730                    + " ms, packageCount: " + systemPackagesCount
2731                    + " ms, timePerPackage: "
2732                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount));
2733            if (mIsUpgrade && systemPackagesCount > 0) {
2734                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2735                        ((int) systemScanTime) / systemPackagesCount);
2736            }
2737            if (!mOnlyCore) {
2738                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2739                        SystemClock.uptimeMillis());
2740                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2741
2742                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2743                        | PackageParser.PARSE_FORWARD_LOCK,
2744                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2745
2746                // Remove disable package settings for updated system apps that were
2747                // removed via an OTA. If the update is no longer present, remove the
2748                // app completely. Otherwise, revoke their system privileges.
2749                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2750                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2751                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2752
2753                    final String msg;
2754                    if (deletedPkg == null) {
2755                        // should have found an update, but, we didn't; remove everything
2756                        msg = "Updated system package " + deletedAppName
2757                                + " no longer exists; removing its data";
2758                        // Actual deletion of code and data will be handled by later
2759                        // reconciliation step
2760                    } else {
2761                        // found an update; revoke system privileges
2762                        msg = "Updated system package + " + deletedAppName
2763                                + " no longer exists; revoking system privileges";
2764
2765                        // Don't do anything if a stub is removed from the system image. If
2766                        // we were to remove the uncompressed version from the /data partition,
2767                        // this is where it'd be done.
2768
2769                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2770                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2771                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2772                    }
2773                    logCriticalInfo(Log.WARN, msg);
2774                }
2775
2776                /*
2777                 * Make sure all system apps that we expected to appear on
2778                 * the userdata partition actually showed up. If they never
2779                 * appeared, crawl back and revive the system version.
2780                 */
2781                for (int i = 0; i < mExpectingBetter.size(); i++) {
2782                    final String packageName = mExpectingBetter.keyAt(i);
2783                    if (!mPackages.containsKey(packageName)) {
2784                        final File scanFile = mExpectingBetter.valueAt(i);
2785
2786                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2787                                + " but never showed up; reverting to system");
2788
2789                        int reparseFlags = mDefParseFlags;
2790                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2791                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2792                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2793                                    | PackageParser.PARSE_IS_PRIVILEGED;
2794                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2795                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2796                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2797                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2798                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2799                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2800                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2801                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2802                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2803                        } else {
2804                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2805                            continue;
2806                        }
2807
2808                        mSettings.enableSystemPackageLPw(packageName);
2809
2810                        try {
2811                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2812                        } catch (PackageManagerException e) {
2813                            Slog.e(TAG, "Failed to parse original system package: "
2814                                    + e.getMessage());
2815                        }
2816                    }
2817                }
2818
2819                // Uncompress and install any stubbed system applications.
2820                // This must be done last to ensure all stubs are replaced or disabled.
2821                decompressSystemApplications(stubSystemApps, scanFlags);
2822
2823                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2824                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2825                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2826                        + " ms, packageCount: " + dataPackagesCount
2827                        + " ms, timePerPackage: "
2828                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount));
2829                if (mIsUpgrade && dataPackagesCount > 0) {
2830                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2831                            ((int) dataScanTime) / dataPackagesCount);
2832                }
2833            }
2834            mExpectingBetter.clear();
2835
2836            // Resolve the storage manager.
2837            mStorageManagerPackage = getStorageManagerPackageName();
2838
2839            // Resolve protected action filters. Only the setup wizard is allowed to
2840            // have a high priority filter for these actions.
2841            mSetupWizardPackage = getSetupWizardPackageName();
2842            if (mProtectedFilters.size() > 0) {
2843                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2844                    Slog.i(TAG, "No setup wizard;"
2845                        + " All protected intents capped to priority 0");
2846                }
2847                for (ActivityIntentInfo filter : mProtectedFilters) {
2848                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2849                        if (DEBUG_FILTERS) {
2850                            Slog.i(TAG, "Found setup wizard;"
2851                                + " allow priority " + filter.getPriority() + ";"
2852                                + " package: " + filter.activity.info.packageName
2853                                + " activity: " + filter.activity.className
2854                                + " priority: " + filter.getPriority());
2855                        }
2856                        // skip setup wizard; allow it to keep the high priority filter
2857                        continue;
2858                    }
2859                    if (DEBUG_FILTERS) {
2860                        Slog.i(TAG, "Protected action; cap priority to 0;"
2861                                + " package: " + filter.activity.info.packageName
2862                                + " activity: " + filter.activity.className
2863                                + " origPrio: " + filter.getPriority());
2864                    }
2865                    filter.setPriority(0);
2866                }
2867            }
2868            mDeferProtectedFilters = false;
2869            mProtectedFilters.clear();
2870
2871            // Now that we know all of the shared libraries, update all clients to have
2872            // the correct library paths.
2873            updateAllSharedLibrariesLPw(null);
2874
2875            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2876                // NOTE: We ignore potential failures here during a system scan (like
2877                // the rest of the commands above) because there's precious little we
2878                // can do about it. A settings error is reported, though.
2879                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2880            }
2881
2882            // Now that we know all the packages we are keeping,
2883            // read and update their last usage times.
2884            mPackageUsage.read(mPackages);
2885            mCompilerStats.read();
2886
2887            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2888                    SystemClock.uptimeMillis());
2889            Slog.i(TAG, "Time to scan packages: "
2890                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2891                    + " seconds");
2892
2893            // If the platform SDK has changed since the last time we booted,
2894            // we need to re-grant app permission to catch any new ones that
2895            // appear.  This is really a hack, and means that apps can in some
2896            // cases get permissions that the user didn't initially explicitly
2897            // allow...  it would be nice to have some better way to handle
2898            // this situation.
2899            int updateFlags = UPDATE_PERMISSIONS_ALL;
2900            if (ver.sdkVersion != mSdkVersion) {
2901                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2902                        + mSdkVersion + "; regranting permissions for internal storage");
2903                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2904            }
2905            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2906            ver.sdkVersion = mSdkVersion;
2907
2908            // If this is the first boot or an update from pre-M, and it is a normal
2909            // boot, then we need to initialize the default preferred apps across
2910            // all defined users.
2911            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2912                for (UserInfo user : sUserManager.getUsers(true)) {
2913                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2914                    applyFactoryDefaultBrowserLPw(user.id);
2915                    primeDomainVerificationsLPw(user.id);
2916                }
2917            }
2918
2919            // Prepare storage for system user really early during boot,
2920            // since core system apps like SettingsProvider and SystemUI
2921            // can't wait for user to start
2922            final int storageFlags;
2923            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2924                storageFlags = StorageManager.FLAG_STORAGE_DE;
2925            } else {
2926                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2927            }
2928            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2929                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2930                    true /* onlyCoreApps */);
2931            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2932                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2933                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2934                traceLog.traceBegin("AppDataFixup");
2935                try {
2936                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2937                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2938                } catch (InstallerException e) {
2939                    Slog.w(TAG, "Trouble fixing GIDs", e);
2940                }
2941                traceLog.traceEnd();
2942
2943                traceLog.traceBegin("AppDataPrepare");
2944                if (deferPackages == null || deferPackages.isEmpty()) {
2945                    return;
2946                }
2947                int count = 0;
2948                for (String pkgName : deferPackages) {
2949                    PackageParser.Package pkg = null;
2950                    synchronized (mPackages) {
2951                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2952                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2953                            pkg = ps.pkg;
2954                        }
2955                    }
2956                    if (pkg != null) {
2957                        synchronized (mInstallLock) {
2958                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2959                                    true /* maybeMigrateAppData */);
2960                        }
2961                        count++;
2962                    }
2963                }
2964                traceLog.traceEnd();
2965                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2966            }, "prepareAppData");
2967
2968            // If this is first boot after an OTA, and a normal boot, then
2969            // we need to clear code cache directories.
2970            // Note that we do *not* clear the application profiles. These remain valid
2971            // across OTAs and are used to drive profile verification (post OTA) and
2972            // profile compilation (without waiting to collect a fresh set of profiles).
2973            if (mIsUpgrade && !onlyCore) {
2974                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2975                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2976                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2977                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2978                        // No apps are running this early, so no need to freeze
2979                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2980                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2981                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2982                    }
2983                }
2984                ver.fingerprint = Build.FINGERPRINT;
2985            }
2986
2987            checkDefaultBrowser();
2988
2989            // clear only after permissions and other defaults have been updated
2990            mExistingSystemPackages.clear();
2991            mPromoteSystemApps = false;
2992
2993            // All the changes are done during package scanning.
2994            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2995
2996            // can downgrade to reader
2997            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2998            mSettings.writeLPr();
2999            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3000            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3001                    SystemClock.uptimeMillis());
3002
3003            if (!mOnlyCore) {
3004                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3005                mRequiredInstallerPackage = getRequiredInstallerLPr();
3006                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3007                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3008                if (mIntentFilterVerifierComponent != null) {
3009                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3010                            mIntentFilterVerifierComponent);
3011                } else {
3012                    mIntentFilterVerifier = null;
3013                }
3014                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3015                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3016                        SharedLibraryInfo.VERSION_UNDEFINED);
3017                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3018                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3019                        SharedLibraryInfo.VERSION_UNDEFINED);
3020            } else {
3021                mRequiredVerifierPackage = null;
3022                mRequiredInstallerPackage = null;
3023                mRequiredUninstallerPackage = null;
3024                mIntentFilterVerifierComponent = null;
3025                mIntentFilterVerifier = null;
3026                mServicesSystemSharedLibraryPackageName = null;
3027                mSharedSystemSharedLibraryPackageName = null;
3028            }
3029
3030            mInstallerService = new PackageInstallerService(context, this);
3031            final Pair<ComponentName, String> instantAppResolverComponent =
3032                    getInstantAppResolverLPr();
3033            if (instantAppResolverComponent != null) {
3034                if (DEBUG_EPHEMERAL) {
3035                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3036                }
3037                mInstantAppResolverConnection = new EphemeralResolverConnection(
3038                        mContext, instantAppResolverComponent.first,
3039                        instantAppResolverComponent.second);
3040                mInstantAppResolverSettingsComponent =
3041                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3042            } else {
3043                mInstantAppResolverConnection = null;
3044                mInstantAppResolverSettingsComponent = null;
3045            }
3046            updateInstantAppInstallerLocked(null);
3047
3048            // Read and update the usage of dex files.
3049            // Do this at the end of PM init so that all the packages have their
3050            // data directory reconciled.
3051            // At this point we know the code paths of the packages, so we can validate
3052            // the disk file and build the internal cache.
3053            // The usage file is expected to be small so loading and verifying it
3054            // should take a fairly small time compare to the other activities (e.g. package
3055            // scanning).
3056            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3057            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3058            for (int userId : currentUserIds) {
3059                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3060            }
3061            mDexManager.load(userPackages);
3062            if (mIsUpgrade) {
3063                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3064                        (int) (SystemClock.uptimeMillis() - startTime));
3065            }
3066        } // synchronized (mPackages)
3067        } // synchronized (mInstallLock)
3068
3069        // Now after opening every single application zip, make sure they
3070        // are all flushed.  Not really needed, but keeps things nice and
3071        // tidy.
3072        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3073        Runtime.getRuntime().gc();
3074        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3075
3076        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3077        FallbackCategoryProvider.loadFallbacks();
3078        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3079
3080        // The initial scanning above does many calls into installd while
3081        // holding the mPackages lock, but we're mostly interested in yelling
3082        // once we have a booted system.
3083        mInstaller.setWarnIfHeld(mPackages);
3084
3085        // Expose private service for system components to use.
3086        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3087        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3088    }
3089
3090    /**
3091     * Uncompress and install stub applications.
3092     * <p>In order to save space on the system partition, some applications are shipped in a
3093     * compressed form. In addition the compressed bits for the full application, the
3094     * system image contains a tiny stub comprised of only the Android manifest.
3095     * <p>During the first boot, attempt to uncompress and install the full application. If
3096     * the application can't be installed for any reason, disable the stub and prevent
3097     * uncompressing the full application during future boots.
3098     * <p>In order to forcefully attempt an installation of a full application, go to app
3099     * settings and enable the application.
3100     */
3101    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3102        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3103            final String pkgName = stubSystemApps.get(i);
3104            // skip if the system package is already disabled
3105            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3106                stubSystemApps.remove(i);
3107                continue;
3108            }
3109            // skip if the package isn't installed (?!); this should never happen
3110            final PackageParser.Package pkg = mPackages.get(pkgName);
3111            if (pkg == null) {
3112                stubSystemApps.remove(i);
3113                continue;
3114            }
3115            // skip if the package has been disabled by the user
3116            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3117            if (ps != null) {
3118                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3119                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3120                    stubSystemApps.remove(i);
3121                    continue;
3122                }
3123            }
3124
3125            if (DEBUG_COMPRESSION) {
3126                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3127            }
3128
3129            // uncompress the binary to its eventual destination on /data
3130            final File scanFile = decompressPackage(pkg);
3131            if (scanFile == null) {
3132                continue;
3133            }
3134
3135            // install the package to replace the stub on /system
3136            try {
3137                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3138                removePackageLI(pkg, true /*chatty*/);
3139                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3140                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3141                        UserHandle.USER_SYSTEM, "android");
3142                stubSystemApps.remove(i);
3143                continue;
3144            } catch (PackageManagerException e) {
3145                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3146            }
3147
3148            // any failed attempt to install the package will be cleaned up later
3149        }
3150
3151        // disable any stub still left; these failed to install the full application
3152        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3153            final String pkgName = stubSystemApps.get(i);
3154            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3155            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3156                    UserHandle.USER_SYSTEM, "android");
3157            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3158        }
3159    }
3160
3161    private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3162        if (DEBUG_COMPRESSION) {
3163            Slog.i(TAG, "Decompress file"
3164                    + "; src: " + srcFile.getAbsolutePath()
3165                    + ", dst: " + dstFile.getAbsolutePath());
3166        }
3167        try (
3168                InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3169                OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3170        ) {
3171            Streams.copy(fileIn, fileOut);
3172            Os.chmod(dstFile.getAbsolutePath(), 0644);
3173            return PackageManager.INSTALL_SUCCEEDED;
3174        } catch (IOException e) {
3175            logCriticalInfo(Log.ERROR, "Failed to decompress file"
3176                    + "; src: " + srcFile.getAbsolutePath()
3177                    + ", dst: " + dstFile.getAbsolutePath());
3178        }
3179        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3180    }
3181
3182    private File[] getCompressedFiles(String codePath) {
3183        return new File(codePath).listFiles(new FilenameFilter() {
3184            @Override
3185            public boolean accept(File dir, String name) {
3186                return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3187            }
3188        });
3189    }
3190
3191    private boolean compressedFileExists(String codePath) {
3192        final File[] compressedFiles = getCompressedFiles(codePath);
3193        return compressedFiles != null && compressedFiles.length > 0;
3194    }
3195
3196    /**
3197     * Decompresses the given package on the system image onto
3198     * the /data partition.
3199     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3200     */
3201    private File decompressPackage(PackageParser.Package pkg) {
3202        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3203        if (compressedFiles == null || compressedFiles.length == 0) {
3204            if (DEBUG_COMPRESSION) {
3205                Slog.i(TAG, "No files to decompress");
3206            }
3207            return null;
3208        }
3209        final File dstCodePath =
3210                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3211        int ret = PackageManager.INSTALL_SUCCEEDED;
3212        try {
3213            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3214            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3215            for (File srcFile : compressedFiles) {
3216                final String srcFileName = srcFile.getName();
3217                final String dstFileName = srcFileName.substring(
3218                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3219                final File dstFile = new File(dstCodePath, dstFileName);
3220                ret = decompressFile(srcFile, dstFile);
3221                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3222                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3223                            + "; pkg: " + pkg.packageName
3224                            + ", file: " + dstFileName);
3225                    break;
3226                }
3227            }
3228        } catch (ErrnoException e) {
3229            logCriticalInfo(Log.ERROR, "Failed to decompress"
3230                    + "; pkg: " + pkg.packageName
3231                    + ", err: " + e.errno);
3232        }
3233        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3234            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3235            NativeLibraryHelper.Handle handle = null;
3236            try {
3237                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3238                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3239                        null /*abiOverride*/);
3240            } catch (IOException e) {
3241                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3242                        + "; pkg: " + pkg.packageName);
3243                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3244            } finally {
3245                IoUtils.closeQuietly(handle);
3246            }
3247        }
3248        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3249            if (dstCodePath == null || !dstCodePath.exists()) {
3250                return null;
3251            }
3252            removeCodePathLI(dstCodePath);
3253            return null;
3254        }
3255        return dstCodePath;
3256    }
3257
3258    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3259        // we're only interested in updating the installer appliction when 1) it's not
3260        // already set or 2) the modified package is the installer
3261        if (mInstantAppInstallerActivity != null
3262                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3263                        .equals(modifiedPackage)) {
3264            return;
3265        }
3266        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3267    }
3268
3269    private static File preparePackageParserCache(boolean isUpgrade) {
3270        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3271            return null;
3272        }
3273
3274        // Disable package parsing on eng builds to allow for faster incremental development.
3275        if (Build.IS_ENG) {
3276            return null;
3277        }
3278
3279        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3280            Slog.i(TAG, "Disabling package parser cache due to system property.");
3281            return null;
3282        }
3283
3284        // The base directory for the package parser cache lives under /data/system/.
3285        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3286                "package_cache");
3287        if (cacheBaseDir == null) {
3288            return null;
3289        }
3290
3291        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3292        // This also serves to "GC" unused entries when the package cache version changes (which
3293        // can only happen during upgrades).
3294        if (isUpgrade) {
3295            FileUtils.deleteContents(cacheBaseDir);
3296        }
3297
3298
3299        // Return the versioned package cache directory. This is something like
3300        // "/data/system/package_cache/1"
3301        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3302
3303        // The following is a workaround to aid development on non-numbered userdebug
3304        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3305        // the system partition is newer.
3306        //
3307        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3308        // that starts with "eng." to signify that this is an engineering build and not
3309        // destined for release.
3310        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3311            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3312
3313            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3314            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3315            // in general and should not be used for production changes. In this specific case,
3316            // we know that they will work.
3317            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3318            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3319                FileUtils.deleteContents(cacheBaseDir);
3320                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3321            }
3322        }
3323
3324        return cacheDir;
3325    }
3326
3327    @Override
3328    public boolean isFirstBoot() {
3329        // allow instant applications
3330        return mFirstBoot;
3331    }
3332
3333    @Override
3334    public boolean isOnlyCoreApps() {
3335        // allow instant applications
3336        return mOnlyCore;
3337    }
3338
3339    @Override
3340    public boolean isUpgrade() {
3341        // allow instant applications
3342        return mIsUpgrade;
3343    }
3344
3345    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3346        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3347
3348        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3349                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3350                UserHandle.USER_SYSTEM);
3351        if (matches.size() == 1) {
3352            return matches.get(0).getComponentInfo().packageName;
3353        } else if (matches.size() == 0) {
3354            Log.e(TAG, "There should probably be a verifier, but, none were found");
3355            return null;
3356        }
3357        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3358    }
3359
3360    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3361        synchronized (mPackages) {
3362            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3363            if (libraryEntry == null) {
3364                throw new IllegalStateException("Missing required shared library:" + name);
3365            }
3366            return libraryEntry.apk;
3367        }
3368    }
3369
3370    private @NonNull String getRequiredInstallerLPr() {
3371        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3372        intent.addCategory(Intent.CATEGORY_DEFAULT);
3373        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3374
3375        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3376                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3377                UserHandle.USER_SYSTEM);
3378        if (matches.size() == 1) {
3379            ResolveInfo resolveInfo = matches.get(0);
3380            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3381                throw new RuntimeException("The installer must be a privileged app");
3382            }
3383            return matches.get(0).getComponentInfo().packageName;
3384        } else {
3385            throw new RuntimeException("There must be exactly one installer; found " + matches);
3386        }
3387    }
3388
3389    private @NonNull String getRequiredUninstallerLPr() {
3390        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3391        intent.addCategory(Intent.CATEGORY_DEFAULT);
3392        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3393
3394        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3395                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3396                UserHandle.USER_SYSTEM);
3397        if (resolveInfo == null ||
3398                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3399            throw new RuntimeException("There must be exactly one uninstaller; found "
3400                    + resolveInfo);
3401        }
3402        return resolveInfo.getComponentInfo().packageName;
3403    }
3404
3405    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3406        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3407
3408        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3409                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3410                UserHandle.USER_SYSTEM);
3411        ResolveInfo best = null;
3412        final int N = matches.size();
3413        for (int i = 0; i < N; i++) {
3414            final ResolveInfo cur = matches.get(i);
3415            final String packageName = cur.getComponentInfo().packageName;
3416            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3417                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3418                continue;
3419            }
3420
3421            if (best == null || cur.priority > best.priority) {
3422                best = cur;
3423            }
3424        }
3425
3426        if (best != null) {
3427            return best.getComponentInfo().getComponentName();
3428        }
3429        Slog.w(TAG, "Intent filter verifier not found");
3430        return null;
3431    }
3432
3433    @Override
3434    public @Nullable ComponentName getInstantAppResolverComponent() {
3435        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3436            return null;
3437        }
3438        synchronized (mPackages) {
3439            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3440            if (instantAppResolver == null) {
3441                return null;
3442            }
3443            return instantAppResolver.first;
3444        }
3445    }
3446
3447    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3448        final String[] packageArray =
3449                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3450        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3451            if (DEBUG_EPHEMERAL) {
3452                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3453            }
3454            return null;
3455        }
3456
3457        final int callingUid = Binder.getCallingUid();
3458        final int resolveFlags =
3459                MATCH_DIRECT_BOOT_AWARE
3460                | MATCH_DIRECT_BOOT_UNAWARE
3461                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3462        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3463        final Intent resolverIntent = new Intent(actionName);
3464        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3465                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3466        // temporarily look for the old action
3467        if (resolvers.size() == 0) {
3468            if (DEBUG_EPHEMERAL) {
3469                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3470            }
3471            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3472            resolverIntent.setAction(actionName);
3473            resolvers = queryIntentServicesInternal(resolverIntent, null,
3474                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3475        }
3476        final int N = resolvers.size();
3477        if (N == 0) {
3478            if (DEBUG_EPHEMERAL) {
3479                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3480            }
3481            return null;
3482        }
3483
3484        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3485        for (int i = 0; i < N; i++) {
3486            final ResolveInfo info = resolvers.get(i);
3487
3488            if (info.serviceInfo == null) {
3489                continue;
3490            }
3491
3492            final String packageName = info.serviceInfo.packageName;
3493            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3494                if (DEBUG_EPHEMERAL) {
3495                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3496                            + " pkg: " + packageName + ", info:" + info);
3497                }
3498                continue;
3499            }
3500
3501            if (DEBUG_EPHEMERAL) {
3502                Slog.v(TAG, "Ephemeral resolver found;"
3503                        + " pkg: " + packageName + ", info:" + info);
3504            }
3505            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3506        }
3507        if (DEBUG_EPHEMERAL) {
3508            Slog.v(TAG, "Ephemeral resolver NOT found");
3509        }
3510        return null;
3511    }
3512
3513    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3514        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3515        intent.addCategory(Intent.CATEGORY_DEFAULT);
3516        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3517
3518        final int resolveFlags =
3519                MATCH_DIRECT_BOOT_AWARE
3520                | MATCH_DIRECT_BOOT_UNAWARE
3521                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3522        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3523                resolveFlags, UserHandle.USER_SYSTEM);
3524        // temporarily look for the old action
3525        if (matches.isEmpty()) {
3526            if (DEBUG_EPHEMERAL) {
3527                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3528            }
3529            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3530            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3531                    resolveFlags, UserHandle.USER_SYSTEM);
3532        }
3533        Iterator<ResolveInfo> iter = matches.iterator();
3534        while (iter.hasNext()) {
3535            final ResolveInfo rInfo = iter.next();
3536            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3537            if (ps != null) {
3538                final PermissionsState permissionsState = ps.getPermissionsState();
3539                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3540                    continue;
3541                }
3542            }
3543            iter.remove();
3544        }
3545        if (matches.size() == 0) {
3546            return null;
3547        } else if (matches.size() == 1) {
3548            return (ActivityInfo) matches.get(0).getComponentInfo();
3549        } else {
3550            throw new RuntimeException(
3551                    "There must be at most one ephemeral installer; found " + matches);
3552        }
3553    }
3554
3555    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3556            @NonNull ComponentName resolver) {
3557        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3558                .addCategory(Intent.CATEGORY_DEFAULT)
3559                .setPackage(resolver.getPackageName());
3560        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3561        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3562                UserHandle.USER_SYSTEM);
3563        // temporarily look for the old action
3564        if (matches.isEmpty()) {
3565            if (DEBUG_EPHEMERAL) {
3566                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3567            }
3568            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3569            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3570                    UserHandle.USER_SYSTEM);
3571        }
3572        if (matches.isEmpty()) {
3573            return null;
3574        }
3575        return matches.get(0).getComponentInfo().getComponentName();
3576    }
3577
3578    private void primeDomainVerificationsLPw(int userId) {
3579        if (DEBUG_DOMAIN_VERIFICATION) {
3580            Slog.d(TAG, "Priming domain verifications in user " + userId);
3581        }
3582
3583        SystemConfig systemConfig = SystemConfig.getInstance();
3584        ArraySet<String> packages = systemConfig.getLinkedApps();
3585
3586        for (String packageName : packages) {
3587            PackageParser.Package pkg = mPackages.get(packageName);
3588            if (pkg != null) {
3589                if (!pkg.isSystemApp()) {
3590                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3591                    continue;
3592                }
3593
3594                ArraySet<String> domains = null;
3595                for (PackageParser.Activity a : pkg.activities) {
3596                    for (ActivityIntentInfo filter : a.intents) {
3597                        if (hasValidDomains(filter)) {
3598                            if (domains == null) {
3599                                domains = new ArraySet<String>();
3600                            }
3601                            domains.addAll(filter.getHostsList());
3602                        }
3603                    }
3604                }
3605
3606                if (domains != null && domains.size() > 0) {
3607                    if (DEBUG_DOMAIN_VERIFICATION) {
3608                        Slog.v(TAG, "      + " + packageName);
3609                    }
3610                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3611                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3612                    // and then 'always' in the per-user state actually used for intent resolution.
3613                    final IntentFilterVerificationInfo ivi;
3614                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3615                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3616                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3617                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3618                } else {
3619                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3620                            + "' does not handle web links");
3621                }
3622            } else {
3623                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3624            }
3625        }
3626
3627        scheduleWritePackageRestrictionsLocked(userId);
3628        scheduleWriteSettingsLocked();
3629    }
3630
3631    private void applyFactoryDefaultBrowserLPw(int userId) {
3632        // The default browser app's package name is stored in a string resource,
3633        // with a product-specific overlay used for vendor customization.
3634        String browserPkg = mContext.getResources().getString(
3635                com.android.internal.R.string.default_browser);
3636        if (!TextUtils.isEmpty(browserPkg)) {
3637            // non-empty string => required to be a known package
3638            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3639            if (ps == null) {
3640                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3641                browserPkg = null;
3642            } else {
3643                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3644            }
3645        }
3646
3647        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3648        // default.  If there's more than one, just leave everything alone.
3649        if (browserPkg == null) {
3650            calculateDefaultBrowserLPw(userId);
3651        }
3652    }
3653
3654    private void calculateDefaultBrowserLPw(int userId) {
3655        List<String> allBrowsers = resolveAllBrowserApps(userId);
3656        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3657        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3658    }
3659
3660    private List<String> resolveAllBrowserApps(int userId) {
3661        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3662        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3663                PackageManager.MATCH_ALL, userId);
3664
3665        final int count = list.size();
3666        List<String> result = new ArrayList<String>(count);
3667        for (int i=0; i<count; i++) {
3668            ResolveInfo info = list.get(i);
3669            if (info.activityInfo == null
3670                    || !info.handleAllWebDataURI
3671                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3672                    || result.contains(info.activityInfo.packageName)) {
3673                continue;
3674            }
3675            result.add(info.activityInfo.packageName);
3676        }
3677
3678        return result;
3679    }
3680
3681    private boolean packageIsBrowser(String packageName, int userId) {
3682        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3683                PackageManager.MATCH_ALL, userId);
3684        final int N = list.size();
3685        for (int i = 0; i < N; i++) {
3686            ResolveInfo info = list.get(i);
3687            if (packageName.equals(info.activityInfo.packageName)) {
3688                return true;
3689            }
3690        }
3691        return false;
3692    }
3693
3694    private void checkDefaultBrowser() {
3695        final int myUserId = UserHandle.myUserId();
3696        final String packageName = getDefaultBrowserPackageName(myUserId);
3697        if (packageName != null) {
3698            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3699            if (info == null) {
3700                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3701                synchronized (mPackages) {
3702                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3703                }
3704            }
3705        }
3706    }
3707
3708    @Override
3709    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3710            throws RemoteException {
3711        try {
3712            return super.onTransact(code, data, reply, flags);
3713        } catch (RuntimeException e) {
3714            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3715                Slog.wtf(TAG, "Package Manager Crash", e);
3716            }
3717            throw e;
3718        }
3719    }
3720
3721    static int[] appendInts(int[] cur, int[] add) {
3722        if (add == null) return cur;
3723        if (cur == null) return add;
3724        final int N = add.length;
3725        for (int i=0; i<N; i++) {
3726            cur = appendInt(cur, add[i]);
3727        }
3728        return cur;
3729    }
3730
3731    /**
3732     * Returns whether or not a full application can see an instant application.
3733     * <p>
3734     * Currently, there are three cases in which this can occur:
3735     * <ol>
3736     * <li>The calling application is a "special" process. The special
3737     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3738     *     and {@code 0}</li>
3739     * <li>The calling application has the permission
3740     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3741     * <li>The calling application is the default launcher on the
3742     *     system partition.</li>
3743     * </ol>
3744     */
3745    private boolean canViewInstantApps(int callingUid, int userId) {
3746        if (callingUid == Process.SYSTEM_UID
3747                || callingUid == Process.SHELL_UID
3748                || callingUid == Process.ROOT_UID) {
3749            return true;
3750        }
3751        if (mContext.checkCallingOrSelfPermission(
3752                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3753            return true;
3754        }
3755        if (mContext.checkCallingOrSelfPermission(
3756                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3757            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3758            if (homeComponent != null
3759                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3760                return true;
3761            }
3762        }
3763        return false;
3764    }
3765
3766    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3767        if (!sUserManager.exists(userId)) return null;
3768        if (ps == null) {
3769            return null;
3770        }
3771        PackageParser.Package p = ps.pkg;
3772        if (p == null) {
3773            return null;
3774        }
3775        final int callingUid = Binder.getCallingUid();
3776        // Filter out ephemeral app metadata:
3777        //   * The system/shell/root can see metadata for any app
3778        //   * An installed app can see metadata for 1) other installed apps
3779        //     and 2) ephemeral apps that have explicitly interacted with it
3780        //   * Ephemeral apps can only see their own data and exposed installed apps
3781        //   * Holding a signature permission allows seeing instant apps
3782        if (filterAppAccessLPr(ps, callingUid, userId)) {
3783            return null;
3784        }
3785
3786        final PermissionsState permissionsState = ps.getPermissionsState();
3787
3788        // Compute GIDs only if requested
3789        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3790                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3791        // Compute granted permissions only if package has requested permissions
3792        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3793                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3794        final PackageUserState state = ps.readUserState(userId);
3795
3796        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3797                && ps.isSystem()) {
3798            flags |= MATCH_ANY_USER;
3799        }
3800
3801        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3802                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3803
3804        if (packageInfo == null) {
3805            return null;
3806        }
3807
3808        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3809                resolveExternalPackageNameLPr(p);
3810
3811        return packageInfo;
3812    }
3813
3814    @Override
3815    public void checkPackageStartable(String packageName, int userId) {
3816        final int callingUid = Binder.getCallingUid();
3817        if (getInstantAppPackageName(callingUid) != null) {
3818            throw new SecurityException("Instant applications don't have access to this method");
3819        }
3820        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3821        synchronized (mPackages) {
3822            final PackageSetting ps = mSettings.mPackages.get(packageName);
3823            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3824                throw new SecurityException("Package " + packageName + " was not found!");
3825            }
3826
3827            if (!ps.getInstalled(userId)) {
3828                throw new SecurityException(
3829                        "Package " + packageName + " was not installed for user " + userId + "!");
3830            }
3831
3832            if (mSafeMode && !ps.isSystem()) {
3833                throw new SecurityException("Package " + packageName + " not a system app!");
3834            }
3835
3836            if (mFrozenPackages.contains(packageName)) {
3837                throw new SecurityException("Package " + packageName + " is currently frozen!");
3838            }
3839
3840            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3841                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3842                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3843            }
3844        }
3845    }
3846
3847    @Override
3848    public boolean isPackageAvailable(String packageName, int userId) {
3849        if (!sUserManager.exists(userId)) return false;
3850        final int callingUid = Binder.getCallingUid();
3851        enforceCrossUserPermission(callingUid, userId,
3852                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3853        synchronized (mPackages) {
3854            PackageParser.Package p = mPackages.get(packageName);
3855            if (p != null) {
3856                final PackageSetting ps = (PackageSetting) p.mExtras;
3857                if (filterAppAccessLPr(ps, callingUid, userId)) {
3858                    return false;
3859                }
3860                if (ps != null) {
3861                    final PackageUserState state = ps.readUserState(userId);
3862                    if (state != null) {
3863                        return PackageParser.isAvailable(state);
3864                    }
3865                }
3866            }
3867        }
3868        return false;
3869    }
3870
3871    @Override
3872    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3873        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3874                flags, Binder.getCallingUid(), userId);
3875    }
3876
3877    @Override
3878    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3879            int flags, int userId) {
3880        return getPackageInfoInternal(versionedPackage.getPackageName(),
3881                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3882    }
3883
3884    /**
3885     * Important: The provided filterCallingUid is used exclusively to filter out packages
3886     * that can be seen based on user state. It's typically the original caller uid prior
3887     * to clearing. Because it can only be provided by trusted code, it's value can be
3888     * trusted and will be used as-is; unlike userId which will be validated by this method.
3889     */
3890    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3891            int flags, int filterCallingUid, int userId) {
3892        if (!sUserManager.exists(userId)) return null;
3893        flags = updateFlagsForPackage(flags, userId, packageName);
3894        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3895                false /* requireFullPermission */, false /* checkShell */, "get package info");
3896
3897        // reader
3898        synchronized (mPackages) {
3899            // Normalize package name to handle renamed packages and static libs
3900            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3901
3902            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3903            if (matchFactoryOnly) {
3904                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3905                if (ps != null) {
3906                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3907                        return null;
3908                    }
3909                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3910                        return null;
3911                    }
3912                    return generatePackageInfo(ps, flags, userId);
3913                }
3914            }
3915
3916            PackageParser.Package p = mPackages.get(packageName);
3917            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3918                return null;
3919            }
3920            if (DEBUG_PACKAGE_INFO)
3921                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3922            if (p != null) {
3923                final PackageSetting ps = (PackageSetting) p.mExtras;
3924                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3925                    return null;
3926                }
3927                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3928                    return null;
3929                }
3930                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3931            }
3932            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3933                final PackageSetting ps = mSettings.mPackages.get(packageName);
3934                if (ps == null) return null;
3935                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3936                    return null;
3937                }
3938                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3939                    return null;
3940                }
3941                return generatePackageInfo(ps, flags, userId);
3942            }
3943        }
3944        return null;
3945    }
3946
3947    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3948        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3949            return true;
3950        }
3951        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3952            return true;
3953        }
3954        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3955            return true;
3956        }
3957        return false;
3958    }
3959
3960    private boolean isComponentVisibleToInstantApp(
3961            @Nullable ComponentName component, @ComponentType int type) {
3962        if (type == TYPE_ACTIVITY) {
3963            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3964            return activity != null
3965                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3966                    : false;
3967        } else if (type == TYPE_RECEIVER) {
3968            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3969            return activity != null
3970                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3971                    : false;
3972        } else if (type == TYPE_SERVICE) {
3973            final PackageParser.Service service = mServices.mServices.get(component);
3974            return service != null
3975                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3976                    : false;
3977        } else if (type == TYPE_PROVIDER) {
3978            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3979            return provider != null
3980                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3981                    : false;
3982        } else if (type == TYPE_UNKNOWN) {
3983            return isComponentVisibleToInstantApp(component);
3984        }
3985        return false;
3986    }
3987
3988    /**
3989     * Returns whether or not access to the application should be filtered.
3990     * <p>
3991     * Access may be limited based upon whether the calling or target applications
3992     * are instant applications.
3993     *
3994     * @see #canAccessInstantApps(int)
3995     */
3996    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3997            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3998        // if we're in an isolated process, get the real calling UID
3999        if (Process.isIsolated(callingUid)) {
4000            callingUid = mIsolatedOwners.get(callingUid);
4001        }
4002        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4003        final boolean callerIsInstantApp = instantAppPkgName != null;
4004        if (ps == null) {
4005            if (callerIsInstantApp) {
4006                // pretend the application exists, but, needs to be filtered
4007                return true;
4008            }
4009            return false;
4010        }
4011        // if the target and caller are the same application, don't filter
4012        if (isCallerSameApp(ps.name, callingUid)) {
4013            return false;
4014        }
4015        if (callerIsInstantApp) {
4016            // request for a specific component; if it hasn't been explicitly exposed, filter
4017            if (component != null) {
4018                return !isComponentVisibleToInstantApp(component, componentType);
4019            }
4020            // request for application; if no components have been explicitly exposed, filter
4021            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4022        }
4023        if (ps.getInstantApp(userId)) {
4024            // caller can see all components of all instant applications, don't filter
4025            if (canViewInstantApps(callingUid, userId)) {
4026                return false;
4027            }
4028            // request for a specific instant application component, filter
4029            if (component != null) {
4030                return true;
4031            }
4032            // request for an instant application; if the caller hasn't been granted access, filter
4033            return !mInstantAppRegistry.isInstantAccessGranted(
4034                    userId, UserHandle.getAppId(callingUid), ps.appId);
4035        }
4036        return false;
4037    }
4038
4039    /**
4040     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4041     */
4042    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4043        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4044    }
4045
4046    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4047            int flags) {
4048        // Callers can access only the libs they depend on, otherwise they need to explicitly
4049        // ask for the shared libraries given the caller is allowed to access all static libs.
4050        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4051            // System/shell/root get to see all static libs
4052            final int appId = UserHandle.getAppId(uid);
4053            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4054                    || appId == Process.ROOT_UID) {
4055                return false;
4056            }
4057        }
4058
4059        // No package means no static lib as it is always on internal storage
4060        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4061            return false;
4062        }
4063
4064        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4065                ps.pkg.staticSharedLibVersion);
4066        if (libEntry == null) {
4067            return false;
4068        }
4069
4070        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4071        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4072        if (uidPackageNames == null) {
4073            return true;
4074        }
4075
4076        for (String uidPackageName : uidPackageNames) {
4077            if (ps.name.equals(uidPackageName)) {
4078                return false;
4079            }
4080            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4081            if (uidPs != null) {
4082                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4083                        libEntry.info.getName());
4084                if (index < 0) {
4085                    continue;
4086                }
4087                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4088                    return false;
4089                }
4090            }
4091        }
4092        return true;
4093    }
4094
4095    @Override
4096    public String[] currentToCanonicalPackageNames(String[] names) {
4097        final int callingUid = Binder.getCallingUid();
4098        if (getInstantAppPackageName(callingUid) != null) {
4099            return names;
4100        }
4101        final String[] out = new String[names.length];
4102        // reader
4103        synchronized (mPackages) {
4104            final int callingUserId = UserHandle.getUserId(callingUid);
4105            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4106            for (int i=names.length-1; i>=0; i--) {
4107                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4108                boolean translateName = false;
4109                if (ps != null && ps.realName != null) {
4110                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4111                    translateName = !targetIsInstantApp
4112                            || canViewInstantApps
4113                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4114                                    UserHandle.getAppId(callingUid), ps.appId);
4115                }
4116                out[i] = translateName ? ps.realName : names[i];
4117            }
4118        }
4119        return out;
4120    }
4121
4122    @Override
4123    public String[] canonicalToCurrentPackageNames(String[] names) {
4124        final int callingUid = Binder.getCallingUid();
4125        if (getInstantAppPackageName(callingUid) != null) {
4126            return names;
4127        }
4128        final String[] out = new String[names.length];
4129        // reader
4130        synchronized (mPackages) {
4131            final int callingUserId = UserHandle.getUserId(callingUid);
4132            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4133            for (int i=names.length-1; i>=0; i--) {
4134                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4135                boolean translateName = false;
4136                if (cur != null) {
4137                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4138                    final boolean targetIsInstantApp =
4139                            ps != null && ps.getInstantApp(callingUserId);
4140                    translateName = !targetIsInstantApp
4141                            || canViewInstantApps
4142                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4143                                    UserHandle.getAppId(callingUid), ps.appId);
4144                }
4145                out[i] = translateName ? cur : names[i];
4146            }
4147        }
4148        return out;
4149    }
4150
4151    @Override
4152    public int getPackageUid(String packageName, int flags, int userId) {
4153        if (!sUserManager.exists(userId)) return -1;
4154        final int callingUid = Binder.getCallingUid();
4155        flags = updateFlagsForPackage(flags, userId, packageName);
4156        enforceCrossUserPermission(callingUid, userId,
4157                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4158
4159        // reader
4160        synchronized (mPackages) {
4161            final PackageParser.Package p = mPackages.get(packageName);
4162            if (p != null && p.isMatch(flags)) {
4163                PackageSetting ps = (PackageSetting) p.mExtras;
4164                if (filterAppAccessLPr(ps, callingUid, userId)) {
4165                    return -1;
4166                }
4167                return UserHandle.getUid(userId, p.applicationInfo.uid);
4168            }
4169            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4170                final PackageSetting ps = mSettings.mPackages.get(packageName);
4171                if (ps != null && ps.isMatch(flags)
4172                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4173                    return UserHandle.getUid(userId, ps.appId);
4174                }
4175            }
4176        }
4177
4178        return -1;
4179    }
4180
4181    @Override
4182    public int[] getPackageGids(String packageName, int flags, int userId) {
4183        if (!sUserManager.exists(userId)) return null;
4184        final int callingUid = Binder.getCallingUid();
4185        flags = updateFlagsForPackage(flags, userId, packageName);
4186        enforceCrossUserPermission(callingUid, userId,
4187                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4188
4189        // reader
4190        synchronized (mPackages) {
4191            final PackageParser.Package p = mPackages.get(packageName);
4192            if (p != null && p.isMatch(flags)) {
4193                PackageSetting ps = (PackageSetting) p.mExtras;
4194                if (filterAppAccessLPr(ps, callingUid, userId)) {
4195                    return null;
4196                }
4197                // TODO: Shouldn't this be checking for package installed state for userId and
4198                // return null?
4199                return ps.getPermissionsState().computeGids(userId);
4200            }
4201            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4202                final PackageSetting ps = mSettings.mPackages.get(packageName);
4203                if (ps != null && ps.isMatch(flags)
4204                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4205                    return ps.getPermissionsState().computeGids(userId);
4206                }
4207            }
4208        }
4209
4210        return null;
4211    }
4212
4213    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4214        if (bp.perm != null) {
4215            return PackageParser.generatePermissionInfo(bp.perm, flags);
4216        }
4217        PermissionInfo pi = new PermissionInfo();
4218        pi.name = bp.name;
4219        pi.packageName = bp.sourcePackage;
4220        pi.nonLocalizedLabel = bp.name;
4221        pi.protectionLevel = bp.protectionLevel;
4222        return pi;
4223    }
4224
4225    @Override
4226    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4227        final int callingUid = Binder.getCallingUid();
4228        if (getInstantAppPackageName(callingUid) != null) {
4229            return null;
4230        }
4231        // reader
4232        synchronized (mPackages) {
4233            final BasePermission p = mSettings.mPermissions.get(name);
4234            if (p == null) {
4235                return null;
4236            }
4237            // If the caller is an app that targets pre 26 SDK drop protection flags.
4238            final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4239            if (permissionInfo != null) {
4240                permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
4241                        permissionInfo.protectionLevel, packageName, callingUid);
4242            }
4243            return permissionInfo;
4244        }
4245    }
4246
4247    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4248            String packageName, int uid) {
4249        // Signature permission flags area always reported
4250        final int protectionLevelMasked = protectionLevel
4251                & (PermissionInfo.PROTECTION_NORMAL
4252                | PermissionInfo.PROTECTION_DANGEROUS
4253                | PermissionInfo.PROTECTION_SIGNATURE);
4254        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4255            return protectionLevel;
4256        }
4257
4258        // System sees all flags.
4259        final int appId = UserHandle.getAppId(uid);
4260        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4261                || appId == Process.SHELL_UID) {
4262            return protectionLevel;
4263        }
4264
4265        // Normalize package name to handle renamed packages and static libs
4266        packageName = resolveInternalPackageNameLPr(packageName,
4267                PackageManager.VERSION_CODE_HIGHEST);
4268
4269        // Apps that target O see flags for all protection levels.
4270        final PackageSetting ps = mSettings.mPackages.get(packageName);
4271        if (ps == null) {
4272            return protectionLevel;
4273        }
4274        if (ps.appId != appId) {
4275            return protectionLevel;
4276        }
4277
4278        final PackageParser.Package pkg = mPackages.get(packageName);
4279        if (pkg == null) {
4280            return protectionLevel;
4281        }
4282        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4283            return protectionLevelMasked;
4284        }
4285
4286        return protectionLevel;
4287    }
4288
4289    @Override
4290    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4291            int flags) {
4292        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4293            return null;
4294        }
4295        // reader
4296        synchronized (mPackages) {
4297            if (group != null && !mPermissionGroups.containsKey(group)) {
4298                // This is thrown as NameNotFoundException
4299                return null;
4300            }
4301
4302            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4303            for (BasePermission p : mSettings.mPermissions.values()) {
4304                if (group == null) {
4305                    if (p.perm == null || p.perm.info.group == null) {
4306                        out.add(generatePermissionInfo(p, flags));
4307                    }
4308                } else {
4309                    if (p.perm != null && group.equals(p.perm.info.group)) {
4310                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4311                    }
4312                }
4313            }
4314            return new ParceledListSlice<>(out);
4315        }
4316    }
4317
4318    @Override
4319    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4320        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4321            return null;
4322        }
4323        // reader
4324        synchronized (mPackages) {
4325            return PackageParser.generatePermissionGroupInfo(
4326                    mPermissionGroups.get(name), flags);
4327        }
4328    }
4329
4330    @Override
4331    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4332        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4333            return ParceledListSlice.emptyList();
4334        }
4335        // reader
4336        synchronized (mPackages) {
4337            final int N = mPermissionGroups.size();
4338            ArrayList<PermissionGroupInfo> out
4339                    = new ArrayList<PermissionGroupInfo>(N);
4340            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4341                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4342            }
4343            return new ParceledListSlice<>(out);
4344        }
4345    }
4346
4347    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4348            int filterCallingUid, int userId) {
4349        if (!sUserManager.exists(userId)) return null;
4350        PackageSetting ps = mSettings.mPackages.get(packageName);
4351        if (ps != null) {
4352            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4353                return null;
4354            }
4355            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4356                return null;
4357            }
4358            if (ps.pkg == null) {
4359                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4360                if (pInfo != null) {
4361                    return pInfo.applicationInfo;
4362                }
4363                return null;
4364            }
4365            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4366                    ps.readUserState(userId), userId);
4367            if (ai != null) {
4368                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4369            }
4370            return ai;
4371        }
4372        return null;
4373    }
4374
4375    @Override
4376    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4377        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4378    }
4379
4380    /**
4381     * Important: The provided filterCallingUid is used exclusively to filter out applications
4382     * that can be seen based on user state. It's typically the original caller uid prior
4383     * to clearing. Because it can only be provided by trusted code, it's value can be
4384     * trusted and will be used as-is; unlike userId which will be validated by this method.
4385     */
4386    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4387            int filterCallingUid, int userId) {
4388        if (!sUserManager.exists(userId)) return null;
4389        flags = updateFlagsForApplication(flags, userId, packageName);
4390        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4391                false /* requireFullPermission */, false /* checkShell */, "get application info");
4392
4393        // writer
4394        synchronized (mPackages) {
4395            // Normalize package name to handle renamed packages and static libs
4396            packageName = resolveInternalPackageNameLPr(packageName,
4397                    PackageManager.VERSION_CODE_HIGHEST);
4398
4399            PackageParser.Package p = mPackages.get(packageName);
4400            if (DEBUG_PACKAGE_INFO) Log.v(
4401                    TAG, "getApplicationInfo " + packageName
4402                    + ": " + p);
4403            if (p != null) {
4404                PackageSetting ps = mSettings.mPackages.get(packageName);
4405                if (ps == null) return null;
4406                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4407                    return null;
4408                }
4409                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4410                    return null;
4411                }
4412                // Note: isEnabledLP() does not apply here - always return info
4413                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4414                        p, flags, ps.readUserState(userId), userId);
4415                if (ai != null) {
4416                    ai.packageName = resolveExternalPackageNameLPr(p);
4417                }
4418                return ai;
4419            }
4420            if ("android".equals(packageName)||"system".equals(packageName)) {
4421                return mAndroidApplication;
4422            }
4423            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4424                // Already generates the external package name
4425                return generateApplicationInfoFromSettingsLPw(packageName,
4426                        flags, filterCallingUid, userId);
4427            }
4428        }
4429        return null;
4430    }
4431
4432    private String normalizePackageNameLPr(String packageName) {
4433        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4434        return normalizedPackageName != null ? normalizedPackageName : packageName;
4435    }
4436
4437    @Override
4438    public void deletePreloadsFileCache() {
4439        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4440            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4441        }
4442        File dir = Environment.getDataPreloadsFileCacheDirectory();
4443        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4444        FileUtils.deleteContents(dir);
4445    }
4446
4447    @Override
4448    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4449            final int storageFlags, final IPackageDataObserver observer) {
4450        mContext.enforceCallingOrSelfPermission(
4451                android.Manifest.permission.CLEAR_APP_CACHE, null);
4452        mHandler.post(() -> {
4453            boolean success = false;
4454            try {
4455                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4456                success = true;
4457            } catch (IOException e) {
4458                Slog.w(TAG, e);
4459            }
4460            if (observer != null) {
4461                try {
4462                    observer.onRemoveCompleted(null, success);
4463                } catch (RemoteException e) {
4464                    Slog.w(TAG, e);
4465                }
4466            }
4467        });
4468    }
4469
4470    @Override
4471    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4472            final int storageFlags, final IntentSender pi) {
4473        mContext.enforceCallingOrSelfPermission(
4474                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4475        mHandler.post(() -> {
4476            boolean success = false;
4477            try {
4478                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4479                success = true;
4480            } catch (IOException e) {
4481                Slog.w(TAG, e);
4482            }
4483            if (pi != null) {
4484                try {
4485                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4486                } catch (SendIntentException e) {
4487                    Slog.w(TAG, e);
4488                }
4489            }
4490        });
4491    }
4492
4493    /**
4494     * Blocking call to clear various types of cached data across the system
4495     * until the requested bytes are available.
4496     */
4497    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4498        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4499        final File file = storage.findPathForUuid(volumeUuid);
4500        if (file.getUsableSpace() >= bytes) return;
4501
4502        if (ENABLE_FREE_CACHE_V2) {
4503            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4504                    volumeUuid);
4505            final boolean aggressive = (storageFlags
4506                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4507            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4508
4509            // 1. Pre-flight to determine if we have any chance to succeed
4510            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4511            if (internalVolume && (aggressive || SystemProperties
4512                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4513                deletePreloadsFileCache();
4514                if (file.getUsableSpace() >= bytes) return;
4515            }
4516
4517            // 3. Consider parsed APK data (aggressive only)
4518            if (internalVolume && aggressive) {
4519                FileUtils.deleteContents(mCacheDir);
4520                if (file.getUsableSpace() >= bytes) return;
4521            }
4522
4523            // 4. Consider cached app data (above quotas)
4524            try {
4525                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4526                        Installer.FLAG_FREE_CACHE_V2);
4527            } catch (InstallerException ignored) {
4528            }
4529            if (file.getUsableSpace() >= bytes) return;
4530
4531            // 5. Consider shared libraries with refcount=0 and age>min cache period
4532            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4533                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4534                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4535                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4536                return;
4537            }
4538
4539            // 6. Consider dexopt output (aggressive only)
4540            // TODO: Implement
4541
4542            // 7. Consider installed instant apps unused longer than min cache period
4543            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4544                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4545                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4546                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4547                return;
4548            }
4549
4550            // 8. Consider cached app data (below quotas)
4551            try {
4552                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4553                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4554            } catch (InstallerException ignored) {
4555            }
4556            if (file.getUsableSpace() >= bytes) return;
4557
4558            // 9. Consider DropBox entries
4559            // TODO: Implement
4560
4561            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4562            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4563                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4564                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4565                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4566                return;
4567            }
4568        } else {
4569            try {
4570                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4571            } catch (InstallerException ignored) {
4572            }
4573            if (file.getUsableSpace() >= bytes) return;
4574        }
4575
4576        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4577    }
4578
4579    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4580            throws IOException {
4581        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4582        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4583
4584        List<VersionedPackage> packagesToDelete = null;
4585        final long now = System.currentTimeMillis();
4586
4587        synchronized (mPackages) {
4588            final int[] allUsers = sUserManager.getUserIds();
4589            final int libCount = mSharedLibraries.size();
4590            for (int i = 0; i < libCount; i++) {
4591                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4592                if (versionedLib == null) {
4593                    continue;
4594                }
4595                final int versionCount = versionedLib.size();
4596                for (int j = 0; j < versionCount; j++) {
4597                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4598                    // Skip packages that are not static shared libs.
4599                    if (!libInfo.isStatic()) {
4600                        break;
4601                    }
4602                    // Important: We skip static shared libs used for some user since
4603                    // in such a case we need to keep the APK on the device. The check for
4604                    // a lib being used for any user is performed by the uninstall call.
4605                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4606                    // Resolve the package name - we use synthetic package names internally
4607                    final String internalPackageName = resolveInternalPackageNameLPr(
4608                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4609                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4610                    // Skip unused static shared libs cached less than the min period
4611                    // to prevent pruning a lib needed by a subsequently installed package.
4612                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4613                        continue;
4614                    }
4615                    if (packagesToDelete == null) {
4616                        packagesToDelete = new ArrayList<>();
4617                    }
4618                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4619                            declaringPackage.getVersionCode()));
4620                }
4621            }
4622        }
4623
4624        if (packagesToDelete != null) {
4625            final int packageCount = packagesToDelete.size();
4626            for (int i = 0; i < packageCount; i++) {
4627                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4628                // Delete the package synchronously (will fail of the lib used for any user).
4629                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4630                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4631                                == PackageManager.DELETE_SUCCEEDED) {
4632                    if (volume.getUsableSpace() >= neededSpace) {
4633                        return true;
4634                    }
4635                }
4636            }
4637        }
4638
4639        return false;
4640    }
4641
4642    /**
4643     * Update given flags based on encryption status of current user.
4644     */
4645    private int updateFlags(int flags, int userId) {
4646        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4647                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4648            // Caller expressed an explicit opinion about what encryption
4649            // aware/unaware components they want to see, so fall through and
4650            // give them what they want
4651        } else {
4652            // Caller expressed no opinion, so match based on user state
4653            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4654                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4655            } else {
4656                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4657            }
4658        }
4659        return flags;
4660    }
4661
4662    private UserManagerInternal getUserManagerInternal() {
4663        if (mUserManagerInternal == null) {
4664            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4665        }
4666        return mUserManagerInternal;
4667    }
4668
4669    private DeviceIdleController.LocalService getDeviceIdleController() {
4670        if (mDeviceIdleController == null) {
4671            mDeviceIdleController =
4672                    LocalServices.getService(DeviceIdleController.LocalService.class);
4673        }
4674        return mDeviceIdleController;
4675    }
4676
4677    /**
4678     * Update given flags when being used to request {@link PackageInfo}.
4679     */
4680    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4681        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4682        boolean triaged = true;
4683        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4684                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4685            // Caller is asking for component details, so they'd better be
4686            // asking for specific encryption matching behavior, or be triaged
4687            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4688                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4689                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4690                triaged = false;
4691            }
4692        }
4693        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4694                | PackageManager.MATCH_SYSTEM_ONLY
4695                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4696            triaged = false;
4697        }
4698        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4699            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4700                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4701                    + Debug.getCallers(5));
4702        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4703                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4704            // If the caller wants all packages and has a restricted profile associated with it,
4705            // then match all users. This is to make sure that launchers that need to access work
4706            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4707            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4708            flags |= PackageManager.MATCH_ANY_USER;
4709        }
4710        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4711            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4712                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4713        }
4714        return updateFlags(flags, userId);
4715    }
4716
4717    /**
4718     * Update given flags when being used to request {@link ApplicationInfo}.
4719     */
4720    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4721        return updateFlagsForPackage(flags, userId, cookie);
4722    }
4723
4724    /**
4725     * Update given flags when being used to request {@link ComponentInfo}.
4726     */
4727    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4728        if (cookie instanceof Intent) {
4729            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4730                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4731            }
4732        }
4733
4734        boolean triaged = true;
4735        // Caller is asking for component details, so they'd better be
4736        // asking for specific encryption matching behavior, or be triaged
4737        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4738                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4739                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4740            triaged = false;
4741        }
4742        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4743            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4744                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4745        }
4746
4747        return updateFlags(flags, userId);
4748    }
4749
4750    /**
4751     * Update given intent when being used to request {@link ResolveInfo}.
4752     */
4753    private Intent updateIntentForResolve(Intent intent) {
4754        if (intent.getSelector() != null) {
4755            intent = intent.getSelector();
4756        }
4757        if (DEBUG_PREFERRED) {
4758            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4759        }
4760        return intent;
4761    }
4762
4763    /**
4764     * Update given flags when being used to request {@link ResolveInfo}.
4765     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4766     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4767     * flag set. However, this flag is only honoured in three circumstances:
4768     * <ul>
4769     * <li>when called from a system process</li>
4770     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4771     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4772     * action and a {@code android.intent.category.BROWSABLE} category</li>
4773     * </ul>
4774     */
4775    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4776        return updateFlagsForResolve(flags, userId, intent, callingUid,
4777                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4778    }
4779    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4780            boolean wantInstantApps) {
4781        return updateFlagsForResolve(flags, userId, intent, callingUid,
4782                wantInstantApps, false /*onlyExposedExplicitly*/);
4783    }
4784    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4785            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4786        // Safe mode means we shouldn't match any third-party components
4787        if (mSafeMode) {
4788            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4789        }
4790        if (getInstantAppPackageName(callingUid) != null) {
4791            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4792            if (onlyExposedExplicitly) {
4793                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4794            }
4795            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4796            flags |= PackageManager.MATCH_INSTANT;
4797        } else {
4798            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4799            final boolean allowMatchInstant =
4800                    (wantInstantApps
4801                            && Intent.ACTION_VIEW.equals(intent.getAction())
4802                            && hasWebURI(intent))
4803                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4804            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4805                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4806            if (!allowMatchInstant) {
4807                flags &= ~PackageManager.MATCH_INSTANT;
4808            }
4809        }
4810        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4811    }
4812
4813    @Override
4814    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4815        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4816    }
4817
4818    /**
4819     * Important: The provided filterCallingUid is used exclusively to filter out activities
4820     * that can be seen based on user state. It's typically the original caller uid prior
4821     * to clearing. Because it can only be provided by trusted code, it's value can be
4822     * trusted and will be used as-is; unlike userId which will be validated by this method.
4823     */
4824    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4825            int filterCallingUid, int userId) {
4826        if (!sUserManager.exists(userId)) return null;
4827        flags = updateFlagsForComponent(flags, userId, component);
4828        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4829                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4830        synchronized (mPackages) {
4831            PackageParser.Activity a = mActivities.mActivities.get(component);
4832
4833            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4834            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4835                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4836                if (ps == null) return null;
4837                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4838                    return null;
4839                }
4840                return PackageParser.generateActivityInfo(
4841                        a, flags, ps.readUserState(userId), userId);
4842            }
4843            if (mResolveComponentName.equals(component)) {
4844                return PackageParser.generateActivityInfo(
4845                        mResolveActivity, flags, new PackageUserState(), userId);
4846            }
4847        }
4848        return null;
4849    }
4850
4851    @Override
4852    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4853            String resolvedType) {
4854        synchronized (mPackages) {
4855            if (component.equals(mResolveComponentName)) {
4856                // The resolver supports EVERYTHING!
4857                return true;
4858            }
4859            final int callingUid = Binder.getCallingUid();
4860            final int callingUserId = UserHandle.getUserId(callingUid);
4861            PackageParser.Activity a = mActivities.mActivities.get(component);
4862            if (a == null) {
4863                return false;
4864            }
4865            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4866            if (ps == null) {
4867                return false;
4868            }
4869            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4870                return false;
4871            }
4872            for (int i=0; i<a.intents.size(); i++) {
4873                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4874                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4875                    return true;
4876                }
4877            }
4878            return false;
4879        }
4880    }
4881
4882    @Override
4883    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4884        if (!sUserManager.exists(userId)) return null;
4885        final int callingUid = Binder.getCallingUid();
4886        flags = updateFlagsForComponent(flags, userId, component);
4887        enforceCrossUserPermission(callingUid, userId,
4888                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4889        synchronized (mPackages) {
4890            PackageParser.Activity a = mReceivers.mActivities.get(component);
4891            if (DEBUG_PACKAGE_INFO) Log.v(
4892                TAG, "getReceiverInfo " + component + ": " + a);
4893            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4894                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4895                if (ps == null) return null;
4896                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4897                    return null;
4898                }
4899                return PackageParser.generateActivityInfo(
4900                        a, flags, ps.readUserState(userId), userId);
4901            }
4902        }
4903        return null;
4904    }
4905
4906    @Override
4907    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4908            int flags, int userId) {
4909        if (!sUserManager.exists(userId)) return null;
4910        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4911        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4912            return null;
4913        }
4914
4915        flags = updateFlagsForPackage(flags, userId, null);
4916
4917        final boolean canSeeStaticLibraries =
4918                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4919                        == PERMISSION_GRANTED
4920                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4921                        == PERMISSION_GRANTED
4922                || canRequestPackageInstallsInternal(packageName,
4923                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4924                        false  /* throwIfPermNotDeclared*/)
4925                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4926                        == PERMISSION_GRANTED;
4927
4928        synchronized (mPackages) {
4929            List<SharedLibraryInfo> result = null;
4930
4931            final int libCount = mSharedLibraries.size();
4932            for (int i = 0; i < libCount; i++) {
4933                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4934                if (versionedLib == null) {
4935                    continue;
4936                }
4937
4938                final int versionCount = versionedLib.size();
4939                for (int j = 0; j < versionCount; j++) {
4940                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4941                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4942                        break;
4943                    }
4944                    final long identity = Binder.clearCallingIdentity();
4945                    try {
4946                        PackageInfo packageInfo = getPackageInfoVersioned(
4947                                libInfo.getDeclaringPackage(), flags
4948                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4949                        if (packageInfo == null) {
4950                            continue;
4951                        }
4952                    } finally {
4953                        Binder.restoreCallingIdentity(identity);
4954                    }
4955
4956                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4957                            libInfo.getVersion(), libInfo.getType(),
4958                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4959                            flags, userId));
4960
4961                    if (result == null) {
4962                        result = new ArrayList<>();
4963                    }
4964                    result.add(resLibInfo);
4965                }
4966            }
4967
4968            return result != null ? new ParceledListSlice<>(result) : null;
4969        }
4970    }
4971
4972    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4973            SharedLibraryInfo libInfo, int flags, int userId) {
4974        List<VersionedPackage> versionedPackages = null;
4975        final int packageCount = mSettings.mPackages.size();
4976        for (int i = 0; i < packageCount; i++) {
4977            PackageSetting ps = mSettings.mPackages.valueAt(i);
4978
4979            if (ps == null) {
4980                continue;
4981            }
4982
4983            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4984                continue;
4985            }
4986
4987            final String libName = libInfo.getName();
4988            if (libInfo.isStatic()) {
4989                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4990                if (libIdx < 0) {
4991                    continue;
4992                }
4993                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4994                    continue;
4995                }
4996                if (versionedPackages == null) {
4997                    versionedPackages = new ArrayList<>();
4998                }
4999                // If the dependent is a static shared lib, use the public package name
5000                String dependentPackageName = ps.name;
5001                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5002                    dependentPackageName = ps.pkg.manifestPackageName;
5003                }
5004                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5005            } else if (ps.pkg != null) {
5006                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5007                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5008                    if (versionedPackages == null) {
5009                        versionedPackages = new ArrayList<>();
5010                    }
5011                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5012                }
5013            }
5014        }
5015
5016        return versionedPackages;
5017    }
5018
5019    @Override
5020    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5021        if (!sUserManager.exists(userId)) return null;
5022        final int callingUid = Binder.getCallingUid();
5023        flags = updateFlagsForComponent(flags, userId, component);
5024        enforceCrossUserPermission(callingUid, userId,
5025                false /* requireFullPermission */, false /* checkShell */, "get service info");
5026        synchronized (mPackages) {
5027            PackageParser.Service s = mServices.mServices.get(component);
5028            if (DEBUG_PACKAGE_INFO) Log.v(
5029                TAG, "getServiceInfo " + component + ": " + s);
5030            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5031                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5032                if (ps == null) return null;
5033                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5034                    return null;
5035                }
5036                return PackageParser.generateServiceInfo(
5037                        s, flags, ps.readUserState(userId), userId);
5038            }
5039        }
5040        return null;
5041    }
5042
5043    @Override
5044    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5045        if (!sUserManager.exists(userId)) return null;
5046        final int callingUid = Binder.getCallingUid();
5047        flags = updateFlagsForComponent(flags, userId, component);
5048        enforceCrossUserPermission(callingUid, userId,
5049                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5050        synchronized (mPackages) {
5051            PackageParser.Provider p = mProviders.mProviders.get(component);
5052            if (DEBUG_PACKAGE_INFO) Log.v(
5053                TAG, "getProviderInfo " + component + ": " + p);
5054            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5055                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5056                if (ps == null) return null;
5057                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5058                    return null;
5059                }
5060                return PackageParser.generateProviderInfo(
5061                        p, flags, ps.readUserState(userId), userId);
5062            }
5063        }
5064        return null;
5065    }
5066
5067    @Override
5068    public String[] getSystemSharedLibraryNames() {
5069        // allow instant applications
5070        synchronized (mPackages) {
5071            Set<String> libs = null;
5072            final int libCount = mSharedLibraries.size();
5073            for (int i = 0; i < libCount; i++) {
5074                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5075                if (versionedLib == null) {
5076                    continue;
5077                }
5078                final int versionCount = versionedLib.size();
5079                for (int j = 0; j < versionCount; j++) {
5080                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5081                    if (!libEntry.info.isStatic()) {
5082                        if (libs == null) {
5083                            libs = new ArraySet<>();
5084                        }
5085                        libs.add(libEntry.info.getName());
5086                        break;
5087                    }
5088                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5089                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5090                            UserHandle.getUserId(Binder.getCallingUid()),
5091                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5092                        if (libs == null) {
5093                            libs = new ArraySet<>();
5094                        }
5095                        libs.add(libEntry.info.getName());
5096                        break;
5097                    }
5098                }
5099            }
5100
5101            if (libs != null) {
5102                String[] libsArray = new String[libs.size()];
5103                libs.toArray(libsArray);
5104                return libsArray;
5105            }
5106
5107            return null;
5108        }
5109    }
5110
5111    @Override
5112    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5113        // allow instant applications
5114        synchronized (mPackages) {
5115            return mServicesSystemSharedLibraryPackageName;
5116        }
5117    }
5118
5119    @Override
5120    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5121        // allow instant applications
5122        synchronized (mPackages) {
5123            return mSharedSystemSharedLibraryPackageName;
5124        }
5125    }
5126
5127    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5128        for (int i = userList.length - 1; i >= 0; --i) {
5129            final int userId = userList[i];
5130            // don't add instant app to the list of updates
5131            if (pkgSetting.getInstantApp(userId)) {
5132                continue;
5133            }
5134            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5135            if (changedPackages == null) {
5136                changedPackages = new SparseArray<>();
5137                mChangedPackages.put(userId, changedPackages);
5138            }
5139            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5140            if (sequenceNumbers == null) {
5141                sequenceNumbers = new HashMap<>();
5142                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5143            }
5144            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5145            if (sequenceNumber != null) {
5146                changedPackages.remove(sequenceNumber);
5147            }
5148            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5149            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5150        }
5151        mChangedPackagesSequenceNumber++;
5152    }
5153
5154    @Override
5155    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5156        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5157            return null;
5158        }
5159        synchronized (mPackages) {
5160            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5161                return null;
5162            }
5163            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5164            if (changedPackages == null) {
5165                return null;
5166            }
5167            final List<String> packageNames =
5168                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5169            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5170                final String packageName = changedPackages.get(i);
5171                if (packageName != null) {
5172                    packageNames.add(packageName);
5173                }
5174            }
5175            return packageNames.isEmpty()
5176                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5177        }
5178    }
5179
5180    @Override
5181    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5182        // allow instant applications
5183        ArrayList<FeatureInfo> res;
5184        synchronized (mAvailableFeatures) {
5185            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5186            res.addAll(mAvailableFeatures.values());
5187        }
5188        final FeatureInfo fi = new FeatureInfo();
5189        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5190                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5191        res.add(fi);
5192
5193        return new ParceledListSlice<>(res);
5194    }
5195
5196    @Override
5197    public boolean hasSystemFeature(String name, int version) {
5198        // allow instant applications
5199        synchronized (mAvailableFeatures) {
5200            final FeatureInfo feat = mAvailableFeatures.get(name);
5201            if (feat == null) {
5202                return false;
5203            } else {
5204                return feat.version >= version;
5205            }
5206        }
5207    }
5208
5209    @Override
5210    public int checkPermission(String permName, String pkgName, int userId) {
5211        if (!sUserManager.exists(userId)) {
5212            return PackageManager.PERMISSION_DENIED;
5213        }
5214        final int callingUid = Binder.getCallingUid();
5215
5216        synchronized (mPackages) {
5217            final PackageParser.Package p = mPackages.get(pkgName);
5218            if (p != null && p.mExtras != null) {
5219                final PackageSetting ps = (PackageSetting) p.mExtras;
5220                if (filterAppAccessLPr(ps, callingUid, userId)) {
5221                    return PackageManager.PERMISSION_DENIED;
5222                }
5223                final boolean instantApp = ps.getInstantApp(userId);
5224                final PermissionsState permissionsState = ps.getPermissionsState();
5225                if (permissionsState.hasPermission(permName, userId)) {
5226                    if (instantApp) {
5227                        BasePermission bp = mSettings.mPermissions.get(permName);
5228                        if (bp != null && bp.isInstant()) {
5229                            return PackageManager.PERMISSION_GRANTED;
5230                        }
5231                    } else {
5232                        return PackageManager.PERMISSION_GRANTED;
5233                    }
5234                }
5235                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5236                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5237                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5238                    return PackageManager.PERMISSION_GRANTED;
5239                }
5240            }
5241        }
5242
5243        return PackageManager.PERMISSION_DENIED;
5244    }
5245
5246    @Override
5247    public int checkUidPermission(String permName, int uid) {
5248        final int callingUid = Binder.getCallingUid();
5249        final int callingUserId = UserHandle.getUserId(callingUid);
5250        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5251        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5252        final int userId = UserHandle.getUserId(uid);
5253        if (!sUserManager.exists(userId)) {
5254            return PackageManager.PERMISSION_DENIED;
5255        }
5256
5257        synchronized (mPackages) {
5258            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5259            if (obj != null) {
5260                if (obj instanceof SharedUserSetting) {
5261                    if (isCallerInstantApp) {
5262                        return PackageManager.PERMISSION_DENIED;
5263                    }
5264                } else if (obj instanceof PackageSetting) {
5265                    final PackageSetting ps = (PackageSetting) obj;
5266                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5267                        return PackageManager.PERMISSION_DENIED;
5268                    }
5269                }
5270                final SettingBase settingBase = (SettingBase) obj;
5271                final PermissionsState permissionsState = settingBase.getPermissionsState();
5272                if (permissionsState.hasPermission(permName, userId)) {
5273                    if (isUidInstantApp) {
5274                        BasePermission bp = mSettings.mPermissions.get(permName);
5275                        if (bp != null && bp.isInstant()) {
5276                            return PackageManager.PERMISSION_GRANTED;
5277                        }
5278                    } else {
5279                        return PackageManager.PERMISSION_GRANTED;
5280                    }
5281                }
5282                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5283                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5284                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5285                    return PackageManager.PERMISSION_GRANTED;
5286                }
5287            } else {
5288                ArraySet<String> perms = mSystemPermissions.get(uid);
5289                if (perms != null) {
5290                    if (perms.contains(permName)) {
5291                        return PackageManager.PERMISSION_GRANTED;
5292                    }
5293                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5294                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5295                        return PackageManager.PERMISSION_GRANTED;
5296                    }
5297                }
5298            }
5299        }
5300
5301        return PackageManager.PERMISSION_DENIED;
5302    }
5303
5304    @Override
5305    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5306        if (UserHandle.getCallingUserId() != userId) {
5307            mContext.enforceCallingPermission(
5308                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5309                    "isPermissionRevokedByPolicy for user " + userId);
5310        }
5311
5312        if (checkPermission(permission, packageName, userId)
5313                == PackageManager.PERMISSION_GRANTED) {
5314            return false;
5315        }
5316
5317        final int callingUid = Binder.getCallingUid();
5318        if (getInstantAppPackageName(callingUid) != null) {
5319            if (!isCallerSameApp(packageName, callingUid)) {
5320                return false;
5321            }
5322        } else {
5323            if (isInstantApp(packageName, userId)) {
5324                return false;
5325            }
5326        }
5327
5328        final long identity = Binder.clearCallingIdentity();
5329        try {
5330            final int flags = getPermissionFlags(permission, packageName, userId);
5331            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5332        } finally {
5333            Binder.restoreCallingIdentity(identity);
5334        }
5335    }
5336
5337    @Override
5338    public String getPermissionControllerPackageName() {
5339        synchronized (mPackages) {
5340            return mRequiredInstallerPackage;
5341        }
5342    }
5343
5344    /**
5345     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5346     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5347     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5348     * @param message the message to log on security exception
5349     */
5350    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5351            boolean checkShell, String message) {
5352        if (userId < 0) {
5353            throw new IllegalArgumentException("Invalid userId " + userId);
5354        }
5355        if (checkShell) {
5356            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5357        }
5358        if (userId == UserHandle.getUserId(callingUid)) return;
5359        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5360            if (requireFullPermission) {
5361                mContext.enforceCallingOrSelfPermission(
5362                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5363            } else {
5364                try {
5365                    mContext.enforceCallingOrSelfPermission(
5366                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5367                } catch (SecurityException se) {
5368                    mContext.enforceCallingOrSelfPermission(
5369                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5370                }
5371            }
5372        }
5373    }
5374
5375    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5376        if (callingUid == Process.SHELL_UID) {
5377            if (userHandle >= 0
5378                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5379                throw new SecurityException("Shell does not have permission to access user "
5380                        + userHandle);
5381            } else if (userHandle < 0) {
5382                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5383                        + Debug.getCallers(3));
5384            }
5385        }
5386    }
5387
5388    private BasePermission findPermissionTreeLP(String permName) {
5389        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5390            if (permName.startsWith(bp.name) &&
5391                    permName.length() > bp.name.length() &&
5392                    permName.charAt(bp.name.length()) == '.') {
5393                return bp;
5394            }
5395        }
5396        return null;
5397    }
5398
5399    private BasePermission checkPermissionTreeLP(String permName) {
5400        if (permName != null) {
5401            BasePermission bp = findPermissionTreeLP(permName);
5402            if (bp != null) {
5403                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5404                    return bp;
5405                }
5406                throw new SecurityException("Calling uid "
5407                        + Binder.getCallingUid()
5408                        + " is not allowed to add to permission tree "
5409                        + bp.name + " owned by uid " + bp.uid);
5410            }
5411        }
5412        throw new SecurityException("No permission tree found for " + permName);
5413    }
5414
5415    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5416        if (s1 == null) {
5417            return s2 == null;
5418        }
5419        if (s2 == null) {
5420            return false;
5421        }
5422        if (s1.getClass() != s2.getClass()) {
5423            return false;
5424        }
5425        return s1.equals(s2);
5426    }
5427
5428    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5429        if (pi1.icon != pi2.icon) return false;
5430        if (pi1.logo != pi2.logo) return false;
5431        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5432        if (!compareStrings(pi1.name, pi2.name)) return false;
5433        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5434        // We'll take care of setting this one.
5435        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5436        // These are not currently stored in settings.
5437        //if (!compareStrings(pi1.group, pi2.group)) return false;
5438        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5439        //if (pi1.labelRes != pi2.labelRes) return false;
5440        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5441        return true;
5442    }
5443
5444    int permissionInfoFootprint(PermissionInfo info) {
5445        int size = info.name.length();
5446        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5447        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5448        return size;
5449    }
5450
5451    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5452        int size = 0;
5453        for (BasePermission perm : mSettings.mPermissions.values()) {
5454            if (perm.uid == tree.uid) {
5455                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5456            }
5457        }
5458        return size;
5459    }
5460
5461    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5462        // We calculate the max size of permissions defined by this uid and throw
5463        // if that plus the size of 'info' would exceed our stated maximum.
5464        if (tree.uid != Process.SYSTEM_UID) {
5465            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5466            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5467                throw new SecurityException("Permission tree size cap exceeded");
5468            }
5469        }
5470    }
5471
5472    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5473        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5474            throw new SecurityException("Instant apps can't add permissions");
5475        }
5476        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5477            throw new SecurityException("Label must be specified in permission");
5478        }
5479        BasePermission tree = checkPermissionTreeLP(info.name);
5480        BasePermission bp = mSettings.mPermissions.get(info.name);
5481        boolean added = bp == null;
5482        boolean changed = true;
5483        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5484        if (added) {
5485            enforcePermissionCapLocked(info, tree);
5486            bp = new BasePermission(info.name, tree.sourcePackage,
5487                    BasePermission.TYPE_DYNAMIC);
5488        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5489            throw new SecurityException(
5490                    "Not allowed to modify non-dynamic permission "
5491                    + info.name);
5492        } else {
5493            if (bp.protectionLevel == fixedLevel
5494                    && bp.perm.owner.equals(tree.perm.owner)
5495                    && bp.uid == tree.uid
5496                    && comparePermissionInfos(bp.perm.info, info)) {
5497                changed = false;
5498            }
5499        }
5500        bp.protectionLevel = fixedLevel;
5501        info = new PermissionInfo(info);
5502        info.protectionLevel = fixedLevel;
5503        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5504        bp.perm.info.packageName = tree.perm.info.packageName;
5505        bp.uid = tree.uid;
5506        if (added) {
5507            mSettings.mPermissions.put(info.name, bp);
5508        }
5509        if (changed) {
5510            if (!async) {
5511                mSettings.writeLPr();
5512            } else {
5513                scheduleWriteSettingsLocked();
5514            }
5515        }
5516        return added;
5517    }
5518
5519    @Override
5520    public boolean addPermission(PermissionInfo info) {
5521        synchronized (mPackages) {
5522            return addPermissionLocked(info, false);
5523        }
5524    }
5525
5526    @Override
5527    public boolean addPermissionAsync(PermissionInfo info) {
5528        synchronized (mPackages) {
5529            return addPermissionLocked(info, true);
5530        }
5531    }
5532
5533    @Override
5534    public void removePermission(String name) {
5535        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5536            throw new SecurityException("Instant applications don't have access to this method");
5537        }
5538        synchronized (mPackages) {
5539            checkPermissionTreeLP(name);
5540            BasePermission bp = mSettings.mPermissions.get(name);
5541            if (bp != null) {
5542                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5543                    throw new SecurityException(
5544                            "Not allowed to modify non-dynamic permission "
5545                            + name);
5546                }
5547                mSettings.mPermissions.remove(name);
5548                mSettings.writeLPr();
5549            }
5550        }
5551    }
5552
5553    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5554            PackageParser.Package pkg, BasePermission bp) {
5555        int index = pkg.requestedPermissions.indexOf(bp.name);
5556        if (index == -1) {
5557            throw new SecurityException("Package " + pkg.packageName
5558                    + " has not requested permission " + bp.name);
5559        }
5560        if (!bp.isRuntime() && !bp.isDevelopment()) {
5561            throw new SecurityException("Permission " + bp.name
5562                    + " is not a changeable permission type");
5563        }
5564    }
5565
5566    @Override
5567    public void grantRuntimePermission(String packageName, String name, final int userId) {
5568        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5569    }
5570
5571    private void grantRuntimePermission(String packageName, String name, final int userId,
5572            boolean overridePolicy) {
5573        if (!sUserManager.exists(userId)) {
5574            Log.e(TAG, "No such user:" + userId);
5575            return;
5576        }
5577        final int callingUid = Binder.getCallingUid();
5578
5579        mContext.enforceCallingOrSelfPermission(
5580                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5581                "grantRuntimePermission");
5582
5583        enforceCrossUserPermission(callingUid, userId,
5584                true /* requireFullPermission */, true /* checkShell */,
5585                "grantRuntimePermission");
5586
5587        final int uid;
5588        final PackageSetting ps;
5589
5590        synchronized (mPackages) {
5591            final PackageParser.Package pkg = mPackages.get(packageName);
5592            if (pkg == null) {
5593                throw new IllegalArgumentException("Unknown package: " + packageName);
5594            }
5595            final BasePermission bp = mSettings.mPermissions.get(name);
5596            if (bp == null) {
5597                throw new IllegalArgumentException("Unknown permission: " + name);
5598            }
5599            ps = (PackageSetting) pkg.mExtras;
5600            if (ps == null
5601                    || filterAppAccessLPr(ps, callingUid, userId)) {
5602                throw new IllegalArgumentException("Unknown package: " + packageName);
5603            }
5604
5605            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5606
5607            // If a permission review is required for legacy apps we represent
5608            // their permissions as always granted runtime ones since we need
5609            // to keep the review required permission flag per user while an
5610            // install permission's state is shared across all users.
5611            if (mPermissionReviewRequired
5612                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5613                    && bp.isRuntime()) {
5614                return;
5615            }
5616
5617            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5618
5619            final PermissionsState permissionsState = ps.getPermissionsState();
5620
5621            final int flags = permissionsState.getPermissionFlags(name, userId);
5622            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5623                throw new SecurityException("Cannot grant system fixed permission "
5624                        + name + " for package " + packageName);
5625            }
5626            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5627                throw new SecurityException("Cannot grant policy fixed permission "
5628                        + name + " for package " + packageName);
5629            }
5630
5631            if (bp.isDevelopment()) {
5632                // Development permissions must be handled specially, since they are not
5633                // normal runtime permissions.  For now they apply to all users.
5634                if (permissionsState.grantInstallPermission(bp) !=
5635                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5636                    scheduleWriteSettingsLocked();
5637                }
5638                return;
5639            }
5640
5641            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5642                throw new SecurityException("Cannot grant non-ephemeral permission"
5643                        + name + " for package " + packageName);
5644            }
5645
5646            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5647                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5648                return;
5649            }
5650
5651            final int result = permissionsState.grantRuntimePermission(bp, userId);
5652            switch (result) {
5653                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5654                    return;
5655                }
5656
5657                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5658                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5659                    mHandler.post(new Runnable() {
5660                        @Override
5661                        public void run() {
5662                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5663                        }
5664                    });
5665                }
5666                break;
5667            }
5668
5669            if (bp.isRuntime()) {
5670                logPermissionGranted(mContext, name, packageName);
5671            }
5672
5673            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5674
5675            // Not critical if that is lost - app has to request again.
5676            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5677        }
5678
5679        // Only need to do this if user is initialized. Otherwise it's a new user
5680        // and there are no processes running as the user yet and there's no need
5681        // to make an expensive call to remount processes for the changed permissions.
5682        if (READ_EXTERNAL_STORAGE.equals(name)
5683                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5684            final long token = Binder.clearCallingIdentity();
5685            try {
5686                if (sUserManager.isInitialized(userId)) {
5687                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5688                            StorageManagerInternal.class);
5689                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5690                }
5691            } finally {
5692                Binder.restoreCallingIdentity(token);
5693            }
5694        }
5695    }
5696
5697    @Override
5698    public void revokeRuntimePermission(String packageName, String name, int userId) {
5699        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5700    }
5701
5702    private void revokeRuntimePermission(String packageName, String name, int userId,
5703            boolean overridePolicy) {
5704        if (!sUserManager.exists(userId)) {
5705            Log.e(TAG, "No such user:" + userId);
5706            return;
5707        }
5708
5709        mContext.enforceCallingOrSelfPermission(
5710                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5711                "revokeRuntimePermission");
5712
5713        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5714                true /* requireFullPermission */, true /* checkShell */,
5715                "revokeRuntimePermission");
5716
5717        final int appId;
5718
5719        synchronized (mPackages) {
5720            final PackageParser.Package pkg = mPackages.get(packageName);
5721            if (pkg == null) {
5722                throw new IllegalArgumentException("Unknown package: " + packageName);
5723            }
5724            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5725            if (ps == null
5726                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5727                throw new IllegalArgumentException("Unknown package: " + packageName);
5728            }
5729            final BasePermission bp = mSettings.mPermissions.get(name);
5730            if (bp == null) {
5731                throw new IllegalArgumentException("Unknown permission: " + name);
5732            }
5733
5734            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5735
5736            // If a permission review is required for legacy apps we represent
5737            // their permissions as always granted runtime ones since we need
5738            // to keep the review required permission flag per user while an
5739            // install permission's state is shared across all users.
5740            if (mPermissionReviewRequired
5741                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5742                    && bp.isRuntime()) {
5743                return;
5744            }
5745
5746            final PermissionsState permissionsState = ps.getPermissionsState();
5747
5748            final int flags = permissionsState.getPermissionFlags(name, userId);
5749            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5750                throw new SecurityException("Cannot revoke system fixed permission "
5751                        + name + " for package " + packageName);
5752            }
5753            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5754                throw new SecurityException("Cannot revoke policy fixed permission "
5755                        + name + " for package " + packageName);
5756            }
5757
5758            if (bp.isDevelopment()) {
5759                // Development permissions must be handled specially, since they are not
5760                // normal runtime permissions.  For now they apply to all users.
5761                if (permissionsState.revokeInstallPermission(bp) !=
5762                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5763                    scheduleWriteSettingsLocked();
5764                }
5765                return;
5766            }
5767
5768            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5769                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5770                return;
5771            }
5772
5773            if (bp.isRuntime()) {
5774                logPermissionRevoked(mContext, name, packageName);
5775            }
5776
5777            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5778
5779            // Critical, after this call app should never have the permission.
5780            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5781
5782            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5783        }
5784
5785        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5786    }
5787
5788    /**
5789     * Get the first event id for the permission.
5790     *
5791     * <p>There are four events for each permission: <ul>
5792     *     <li>Request permission: first id + 0</li>
5793     *     <li>Grant permission: first id + 1</li>
5794     *     <li>Request for permission denied: first id + 2</li>
5795     *     <li>Revoke permission: first id + 3</li>
5796     * </ul></p>
5797     *
5798     * @param name name of the permission
5799     *
5800     * @return The first event id for the permission
5801     */
5802    private static int getBaseEventId(@NonNull String name) {
5803        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5804
5805        if (eventIdIndex == -1) {
5806            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5807                    || Build.IS_USER) {
5808                Log.i(TAG, "Unknown permission " + name);
5809
5810                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5811            } else {
5812                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5813                //
5814                // Also update
5815                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5816                // - metrics_constants.proto
5817                throw new IllegalStateException("Unknown permission " + name);
5818            }
5819        }
5820
5821        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5822    }
5823
5824    /**
5825     * Log that a permission was revoked.
5826     *
5827     * @param context Context of the caller
5828     * @param name name of the permission
5829     * @param packageName package permission if for
5830     */
5831    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5832            @NonNull String packageName) {
5833        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5834    }
5835
5836    /**
5837     * Log that a permission request was granted.
5838     *
5839     * @param context Context of the caller
5840     * @param name name of the permission
5841     * @param packageName package permission if for
5842     */
5843    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5844            @NonNull String packageName) {
5845        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5846    }
5847
5848    @Override
5849    public void resetRuntimePermissions() {
5850        mContext.enforceCallingOrSelfPermission(
5851                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5852                "revokeRuntimePermission");
5853
5854        int callingUid = Binder.getCallingUid();
5855        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5856            mContext.enforceCallingOrSelfPermission(
5857                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5858                    "resetRuntimePermissions");
5859        }
5860
5861        synchronized (mPackages) {
5862            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5863            for (int userId : UserManagerService.getInstance().getUserIds()) {
5864                final int packageCount = mPackages.size();
5865                for (int i = 0; i < packageCount; i++) {
5866                    PackageParser.Package pkg = mPackages.valueAt(i);
5867                    if (!(pkg.mExtras instanceof PackageSetting)) {
5868                        continue;
5869                    }
5870                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5871                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5872                }
5873            }
5874        }
5875    }
5876
5877    @Override
5878    public int getPermissionFlags(String name, String packageName, int userId) {
5879        if (!sUserManager.exists(userId)) {
5880            return 0;
5881        }
5882
5883        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5884
5885        final int callingUid = Binder.getCallingUid();
5886        enforceCrossUserPermission(callingUid, userId,
5887                true /* requireFullPermission */, false /* checkShell */,
5888                "getPermissionFlags");
5889
5890        synchronized (mPackages) {
5891            final PackageParser.Package pkg = mPackages.get(packageName);
5892            if (pkg == null) {
5893                return 0;
5894            }
5895            final BasePermission bp = mSettings.mPermissions.get(name);
5896            if (bp == null) {
5897                return 0;
5898            }
5899            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5900            if (ps == null
5901                    || filterAppAccessLPr(ps, callingUid, userId)) {
5902                return 0;
5903            }
5904            PermissionsState permissionsState = ps.getPermissionsState();
5905            return permissionsState.getPermissionFlags(name, userId);
5906        }
5907    }
5908
5909    @Override
5910    public void updatePermissionFlags(String name, String packageName, int flagMask,
5911            int flagValues, int userId) {
5912        if (!sUserManager.exists(userId)) {
5913            return;
5914        }
5915
5916        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5917
5918        final int callingUid = Binder.getCallingUid();
5919        enforceCrossUserPermission(callingUid, userId,
5920                true /* requireFullPermission */, true /* checkShell */,
5921                "updatePermissionFlags");
5922
5923        // Only the system can change these flags and nothing else.
5924        if (getCallingUid() != Process.SYSTEM_UID) {
5925            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5926            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5927            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5928            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5929            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5930        }
5931
5932        synchronized (mPackages) {
5933            final PackageParser.Package pkg = mPackages.get(packageName);
5934            if (pkg == null) {
5935                throw new IllegalArgumentException("Unknown package: " + packageName);
5936            }
5937            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5938            if (ps == null
5939                    || filterAppAccessLPr(ps, callingUid, userId)) {
5940                throw new IllegalArgumentException("Unknown package: " + packageName);
5941            }
5942
5943            final BasePermission bp = mSettings.mPermissions.get(name);
5944            if (bp == null) {
5945                throw new IllegalArgumentException("Unknown permission: " + name);
5946            }
5947
5948            PermissionsState permissionsState = ps.getPermissionsState();
5949
5950            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5951
5952            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5953                // Install and runtime permissions are stored in different places,
5954                // so figure out what permission changed and persist the change.
5955                if (permissionsState.getInstallPermissionState(name) != null) {
5956                    scheduleWriteSettingsLocked();
5957                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5958                        || hadState) {
5959                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5960                }
5961            }
5962        }
5963    }
5964
5965    /**
5966     * Update the permission flags for all packages and runtime permissions of a user in order
5967     * to allow device or profile owner to remove POLICY_FIXED.
5968     */
5969    @Override
5970    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5971        if (!sUserManager.exists(userId)) {
5972            return;
5973        }
5974
5975        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5976
5977        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5978                true /* requireFullPermission */, true /* checkShell */,
5979                "updatePermissionFlagsForAllApps");
5980
5981        // Only the system can change system fixed flags.
5982        if (getCallingUid() != Process.SYSTEM_UID) {
5983            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5984            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5985        }
5986
5987        synchronized (mPackages) {
5988            boolean changed = false;
5989            final int packageCount = mPackages.size();
5990            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5991                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5992                final PackageSetting ps = (PackageSetting) pkg.mExtras;
5993                if (ps == null) {
5994                    continue;
5995                }
5996                PermissionsState permissionsState = ps.getPermissionsState();
5997                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5998                        userId, flagMask, flagValues);
5999            }
6000            if (changed) {
6001                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6002            }
6003        }
6004    }
6005
6006    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6007        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6008                != PackageManager.PERMISSION_GRANTED
6009            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6010                != PackageManager.PERMISSION_GRANTED) {
6011            throw new SecurityException(message + " requires "
6012                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6013                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6014        }
6015    }
6016
6017    @Override
6018    public boolean shouldShowRequestPermissionRationale(String permissionName,
6019            String packageName, int userId) {
6020        if (UserHandle.getCallingUserId() != userId) {
6021            mContext.enforceCallingPermission(
6022                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6023                    "canShowRequestPermissionRationale for user " + userId);
6024        }
6025
6026        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6027        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6028            return false;
6029        }
6030
6031        if (checkPermission(permissionName, packageName, userId)
6032                == PackageManager.PERMISSION_GRANTED) {
6033            return false;
6034        }
6035
6036        final int flags;
6037
6038        final long identity = Binder.clearCallingIdentity();
6039        try {
6040            flags = getPermissionFlags(permissionName,
6041                    packageName, userId);
6042        } finally {
6043            Binder.restoreCallingIdentity(identity);
6044        }
6045
6046        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6047                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6048                | PackageManager.FLAG_PERMISSION_USER_FIXED;
6049
6050        if ((flags & fixedFlags) != 0) {
6051            return false;
6052        }
6053
6054        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6055    }
6056
6057    @Override
6058    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6059        mContext.enforceCallingOrSelfPermission(
6060                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6061                "addOnPermissionsChangeListener");
6062
6063        synchronized (mPackages) {
6064            mOnPermissionChangeListeners.addListenerLocked(listener);
6065        }
6066    }
6067
6068    @Override
6069    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6070        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6071            throw new SecurityException("Instant applications don't have access to this method");
6072        }
6073        synchronized (mPackages) {
6074            mOnPermissionChangeListeners.removeListenerLocked(listener);
6075        }
6076    }
6077
6078    @Override
6079    public boolean isProtectedBroadcast(String actionName) {
6080        // allow instant applications
6081        synchronized (mProtectedBroadcasts) {
6082            if (mProtectedBroadcasts.contains(actionName)) {
6083                return true;
6084            } else if (actionName != null) {
6085                // TODO: remove these terrible hacks
6086                if (actionName.startsWith("android.net.netmon.lingerExpired")
6087                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6088                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6089                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6090                    return true;
6091                }
6092            }
6093        }
6094        return false;
6095    }
6096
6097    @Override
6098    public int checkSignatures(String pkg1, String pkg2) {
6099        synchronized (mPackages) {
6100            final PackageParser.Package p1 = mPackages.get(pkg1);
6101            final PackageParser.Package p2 = mPackages.get(pkg2);
6102            if (p1 == null || p1.mExtras == null
6103                    || p2 == null || p2.mExtras == null) {
6104                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6105            }
6106            final int callingUid = Binder.getCallingUid();
6107            final int callingUserId = UserHandle.getUserId(callingUid);
6108            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6109            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6110            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6111                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6112                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6113            }
6114            return compareSignatures(p1.mSignatures, p2.mSignatures);
6115        }
6116    }
6117
6118    @Override
6119    public int checkUidSignatures(int uid1, int uid2) {
6120        final int callingUid = Binder.getCallingUid();
6121        final int callingUserId = UserHandle.getUserId(callingUid);
6122        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6123        // Map to base uids.
6124        uid1 = UserHandle.getAppId(uid1);
6125        uid2 = UserHandle.getAppId(uid2);
6126        // reader
6127        synchronized (mPackages) {
6128            Signature[] s1;
6129            Signature[] s2;
6130            Object obj = mSettings.getUserIdLPr(uid1);
6131            if (obj != null) {
6132                if (obj instanceof SharedUserSetting) {
6133                    if (isCallerInstantApp) {
6134                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6135                    }
6136                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6137                } else if (obj instanceof PackageSetting) {
6138                    final PackageSetting ps = (PackageSetting) obj;
6139                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6140                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6141                    }
6142                    s1 = ps.signatures.mSignatures;
6143                } else {
6144                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6145                }
6146            } else {
6147                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6148            }
6149            obj = mSettings.getUserIdLPr(uid2);
6150            if (obj != null) {
6151                if (obj instanceof SharedUserSetting) {
6152                    if (isCallerInstantApp) {
6153                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6154                    }
6155                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6156                } else if (obj instanceof PackageSetting) {
6157                    final PackageSetting ps = (PackageSetting) obj;
6158                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6159                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6160                    }
6161                    s2 = ps.signatures.mSignatures;
6162                } else {
6163                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6164                }
6165            } else {
6166                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6167            }
6168            return compareSignatures(s1, s2);
6169        }
6170    }
6171
6172    /**
6173     * This method should typically only be used when granting or revoking
6174     * permissions, since the app may immediately restart after this call.
6175     * <p>
6176     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6177     * guard your work against the app being relaunched.
6178     */
6179    private void killUid(int appId, int userId, String reason) {
6180        final long identity = Binder.clearCallingIdentity();
6181        try {
6182            IActivityManager am = ActivityManager.getService();
6183            if (am != null) {
6184                try {
6185                    am.killUid(appId, userId, reason);
6186                } catch (RemoteException e) {
6187                    /* ignore - same process */
6188                }
6189            }
6190        } finally {
6191            Binder.restoreCallingIdentity(identity);
6192        }
6193    }
6194
6195    /**
6196     * Compares two sets of signatures. Returns:
6197     * <br />
6198     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6199     * <br />
6200     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6201     * <br />
6202     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6203     * <br />
6204     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6205     * <br />
6206     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6207     */
6208    static int compareSignatures(Signature[] s1, Signature[] s2) {
6209        if (s1 == null) {
6210            return s2 == null
6211                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
6212                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6213        }
6214
6215        if (s2 == null) {
6216            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6217        }
6218
6219        if (s1.length != s2.length) {
6220            return PackageManager.SIGNATURE_NO_MATCH;
6221        }
6222
6223        // Since both signature sets are of size 1, we can compare without HashSets.
6224        if (s1.length == 1) {
6225            return s1[0].equals(s2[0]) ?
6226                    PackageManager.SIGNATURE_MATCH :
6227                    PackageManager.SIGNATURE_NO_MATCH;
6228        }
6229
6230        ArraySet<Signature> set1 = new ArraySet<Signature>();
6231        for (Signature sig : s1) {
6232            set1.add(sig);
6233        }
6234        ArraySet<Signature> set2 = new ArraySet<Signature>();
6235        for (Signature sig : s2) {
6236            set2.add(sig);
6237        }
6238        // Make sure s2 contains all signatures in s1.
6239        if (set1.equals(set2)) {
6240            return PackageManager.SIGNATURE_MATCH;
6241        }
6242        return PackageManager.SIGNATURE_NO_MATCH;
6243    }
6244
6245    /**
6246     * If the database version for this type of package (internal storage or
6247     * external storage) is less than the version where package signatures
6248     * were updated, return true.
6249     */
6250    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6251        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6252        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6253    }
6254
6255    /**
6256     * Used for backward compatibility to make sure any packages with
6257     * certificate chains get upgraded to the new style. {@code existingSigs}
6258     * will be in the old format (since they were stored on disk from before the
6259     * system upgrade) and {@code scannedSigs} will be in the newer format.
6260     */
6261    private int compareSignaturesCompat(PackageSignatures existingSigs,
6262            PackageParser.Package scannedPkg) {
6263        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6264            return PackageManager.SIGNATURE_NO_MATCH;
6265        }
6266
6267        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6268        for (Signature sig : existingSigs.mSignatures) {
6269            existingSet.add(sig);
6270        }
6271        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6272        for (Signature sig : scannedPkg.mSignatures) {
6273            try {
6274                Signature[] chainSignatures = sig.getChainSignatures();
6275                for (Signature chainSig : chainSignatures) {
6276                    scannedCompatSet.add(chainSig);
6277                }
6278            } catch (CertificateEncodingException e) {
6279                scannedCompatSet.add(sig);
6280            }
6281        }
6282        /*
6283         * Make sure the expanded scanned set contains all signatures in the
6284         * existing one.
6285         */
6286        if (scannedCompatSet.equals(existingSet)) {
6287            // Migrate the old signatures to the new scheme.
6288            existingSigs.assignSignatures(scannedPkg.mSignatures);
6289            // The new KeySets will be re-added later in the scanning process.
6290            synchronized (mPackages) {
6291                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6292            }
6293            return PackageManager.SIGNATURE_MATCH;
6294        }
6295        return PackageManager.SIGNATURE_NO_MATCH;
6296    }
6297
6298    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6299        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6300        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6301    }
6302
6303    private int compareSignaturesRecover(PackageSignatures existingSigs,
6304            PackageParser.Package scannedPkg) {
6305        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6306            return PackageManager.SIGNATURE_NO_MATCH;
6307        }
6308
6309        String msg = null;
6310        try {
6311            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6312                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6313                        + scannedPkg.packageName);
6314                return PackageManager.SIGNATURE_MATCH;
6315            }
6316        } catch (CertificateException e) {
6317            msg = e.getMessage();
6318        }
6319
6320        logCriticalInfo(Log.INFO,
6321                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6322        return PackageManager.SIGNATURE_NO_MATCH;
6323    }
6324
6325    @Override
6326    public List<String> getAllPackages() {
6327        final int callingUid = Binder.getCallingUid();
6328        final int callingUserId = UserHandle.getUserId(callingUid);
6329        synchronized (mPackages) {
6330            if (canViewInstantApps(callingUid, callingUserId)) {
6331                return new ArrayList<String>(mPackages.keySet());
6332            }
6333            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6334            final List<String> result = new ArrayList<>();
6335            if (instantAppPkgName != null) {
6336                // caller is an instant application; filter unexposed applications
6337                for (PackageParser.Package pkg : mPackages.values()) {
6338                    if (!pkg.visibleToInstantApps) {
6339                        continue;
6340                    }
6341                    result.add(pkg.packageName);
6342                }
6343            } else {
6344                // caller is a normal application; filter instant applications
6345                for (PackageParser.Package pkg : mPackages.values()) {
6346                    final PackageSetting ps =
6347                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6348                    if (ps != null
6349                            && ps.getInstantApp(callingUserId)
6350                            && !mInstantAppRegistry.isInstantAccessGranted(
6351                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6352                        continue;
6353                    }
6354                    result.add(pkg.packageName);
6355                }
6356            }
6357            return result;
6358        }
6359    }
6360
6361    @Override
6362    public String[] getPackagesForUid(int uid) {
6363        final int callingUid = Binder.getCallingUid();
6364        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6365        final int userId = UserHandle.getUserId(uid);
6366        uid = UserHandle.getAppId(uid);
6367        // reader
6368        synchronized (mPackages) {
6369            Object obj = mSettings.getUserIdLPr(uid);
6370            if (obj instanceof SharedUserSetting) {
6371                if (isCallerInstantApp) {
6372                    return null;
6373                }
6374                final SharedUserSetting sus = (SharedUserSetting) obj;
6375                final int N = sus.packages.size();
6376                String[] res = new String[N];
6377                final Iterator<PackageSetting> it = sus.packages.iterator();
6378                int i = 0;
6379                while (it.hasNext()) {
6380                    PackageSetting ps = it.next();
6381                    if (ps.getInstalled(userId)) {
6382                        res[i++] = ps.name;
6383                    } else {
6384                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6385                    }
6386                }
6387                return res;
6388            } else if (obj instanceof PackageSetting) {
6389                final PackageSetting ps = (PackageSetting) obj;
6390                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6391                    return new String[]{ps.name};
6392                }
6393            }
6394        }
6395        return null;
6396    }
6397
6398    @Override
6399    public String getNameForUid(int uid) {
6400        final int callingUid = Binder.getCallingUid();
6401        if (getInstantAppPackageName(callingUid) != null) {
6402            return null;
6403        }
6404        synchronized (mPackages) {
6405            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6406            if (obj instanceof SharedUserSetting) {
6407                final SharedUserSetting sus = (SharedUserSetting) obj;
6408                return sus.name + ":" + sus.userId;
6409            } else if (obj instanceof PackageSetting) {
6410                final PackageSetting ps = (PackageSetting) obj;
6411                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6412                    return null;
6413                }
6414                return ps.name;
6415            }
6416        }
6417        return null;
6418    }
6419
6420    @Override
6421    public int getUidForSharedUser(String sharedUserName) {
6422        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6423            return -1;
6424        }
6425        if (sharedUserName == null) {
6426            return -1;
6427        }
6428        // reader
6429        synchronized (mPackages) {
6430            SharedUserSetting suid;
6431            try {
6432                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6433                if (suid != null) {
6434                    return suid.userId;
6435                }
6436            } catch (PackageManagerException ignore) {
6437                // can't happen, but, still need to catch it
6438            }
6439            return -1;
6440        }
6441    }
6442
6443    @Override
6444    public int getFlagsForUid(int uid) {
6445        final int callingUid = Binder.getCallingUid();
6446        if (getInstantAppPackageName(callingUid) != null) {
6447            return 0;
6448        }
6449        synchronized (mPackages) {
6450            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6451            if (obj instanceof SharedUserSetting) {
6452                final SharedUserSetting sus = (SharedUserSetting) obj;
6453                return sus.pkgFlags;
6454            } else if (obj instanceof PackageSetting) {
6455                final PackageSetting ps = (PackageSetting) obj;
6456                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6457                    return 0;
6458                }
6459                return ps.pkgFlags;
6460            }
6461        }
6462        return 0;
6463    }
6464
6465    @Override
6466    public int getPrivateFlagsForUid(int uid) {
6467        final int callingUid = Binder.getCallingUid();
6468        if (getInstantAppPackageName(callingUid) != null) {
6469            return 0;
6470        }
6471        synchronized (mPackages) {
6472            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6473            if (obj instanceof SharedUserSetting) {
6474                final SharedUserSetting sus = (SharedUserSetting) obj;
6475                return sus.pkgPrivateFlags;
6476            } else if (obj instanceof PackageSetting) {
6477                final PackageSetting ps = (PackageSetting) obj;
6478                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6479                    return 0;
6480                }
6481                return ps.pkgPrivateFlags;
6482            }
6483        }
6484        return 0;
6485    }
6486
6487    @Override
6488    public boolean isUidPrivileged(int uid) {
6489        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6490            return false;
6491        }
6492        uid = UserHandle.getAppId(uid);
6493        // reader
6494        synchronized (mPackages) {
6495            Object obj = mSettings.getUserIdLPr(uid);
6496            if (obj instanceof SharedUserSetting) {
6497                final SharedUserSetting sus = (SharedUserSetting) obj;
6498                final Iterator<PackageSetting> it = sus.packages.iterator();
6499                while (it.hasNext()) {
6500                    if (it.next().isPrivileged()) {
6501                        return true;
6502                    }
6503                }
6504            } else if (obj instanceof PackageSetting) {
6505                final PackageSetting ps = (PackageSetting) obj;
6506                return ps.isPrivileged();
6507            }
6508        }
6509        return false;
6510    }
6511
6512    @Override
6513    public String[] getAppOpPermissionPackages(String permissionName) {
6514        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6515            return null;
6516        }
6517        synchronized (mPackages) {
6518            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6519            if (pkgs == null) {
6520                return null;
6521            }
6522            return pkgs.toArray(new String[pkgs.size()]);
6523        }
6524    }
6525
6526    @Override
6527    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6528            int flags, int userId) {
6529        return resolveIntentInternal(
6530                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6531    }
6532
6533    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6534            int flags, int userId, boolean resolveForStart) {
6535        try {
6536            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6537
6538            if (!sUserManager.exists(userId)) return null;
6539            final int callingUid = Binder.getCallingUid();
6540            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6541            enforceCrossUserPermission(callingUid, userId,
6542                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6543
6544            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6545            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6546                    flags, callingUid, userId, resolveForStart);
6547            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6548
6549            final ResolveInfo bestChoice =
6550                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6551            return bestChoice;
6552        } finally {
6553            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6554        }
6555    }
6556
6557    @Override
6558    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6559        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6560            throw new SecurityException(
6561                    "findPersistentPreferredActivity can only be run by the system");
6562        }
6563        if (!sUserManager.exists(userId)) {
6564            return null;
6565        }
6566        final int callingUid = Binder.getCallingUid();
6567        intent = updateIntentForResolve(intent);
6568        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6569        final int flags = updateFlagsForResolve(
6570                0, userId, intent, callingUid, false /*includeInstantApps*/);
6571        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6572                userId);
6573        synchronized (mPackages) {
6574            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6575                    userId);
6576        }
6577    }
6578
6579    @Override
6580    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6581            IntentFilter filter, int match, ComponentName activity) {
6582        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6583            return;
6584        }
6585        final int userId = UserHandle.getCallingUserId();
6586        if (DEBUG_PREFERRED) {
6587            Log.v(TAG, "setLastChosenActivity intent=" + intent
6588                + " resolvedType=" + resolvedType
6589                + " flags=" + flags
6590                + " filter=" + filter
6591                + " match=" + match
6592                + " activity=" + activity);
6593            filter.dump(new PrintStreamPrinter(System.out), "    ");
6594        }
6595        intent.setComponent(null);
6596        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6597                userId);
6598        // Find any earlier preferred or last chosen entries and nuke them
6599        findPreferredActivity(intent, resolvedType,
6600                flags, query, 0, false, true, false, userId);
6601        // Add the new activity as the last chosen for this filter
6602        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6603                "Setting last chosen");
6604    }
6605
6606    @Override
6607    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6608        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6609            return null;
6610        }
6611        final int userId = UserHandle.getCallingUserId();
6612        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6613        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6614                userId);
6615        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6616                false, false, false, userId);
6617    }
6618
6619    /**
6620     * Returns whether or not instant apps have been disabled remotely.
6621     */
6622    private boolean isEphemeralDisabled() {
6623        return mEphemeralAppsDisabled;
6624    }
6625
6626    private boolean isInstantAppAllowed(
6627            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6628            boolean skipPackageCheck) {
6629        if (mInstantAppResolverConnection == null) {
6630            return false;
6631        }
6632        if (mInstantAppInstallerActivity == null) {
6633            return false;
6634        }
6635        if (intent.getComponent() != null) {
6636            return false;
6637        }
6638        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6639            return false;
6640        }
6641        if (!skipPackageCheck && intent.getPackage() != null) {
6642            return false;
6643        }
6644        final boolean isWebUri = hasWebURI(intent);
6645        if (!isWebUri || intent.getData().getHost() == null) {
6646            return false;
6647        }
6648        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6649        // Or if there's already an ephemeral app installed that handles the action
6650        synchronized (mPackages) {
6651            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6652            for (int n = 0; n < count; n++) {
6653                final ResolveInfo info = resolvedActivities.get(n);
6654                final String packageName = info.activityInfo.packageName;
6655                final PackageSetting ps = mSettings.mPackages.get(packageName);
6656                if (ps != null) {
6657                    // only check domain verification status if the app is not a browser
6658                    if (!info.handleAllWebDataURI) {
6659                        // Try to get the status from User settings first
6660                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6661                        final int status = (int) (packedStatus >> 32);
6662                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6663                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6664                            if (DEBUG_EPHEMERAL) {
6665                                Slog.v(TAG, "DENY instant app;"
6666                                    + " pkg: " + packageName + ", status: " + status);
6667                            }
6668                            return false;
6669                        }
6670                    }
6671                    if (ps.getInstantApp(userId)) {
6672                        if (DEBUG_EPHEMERAL) {
6673                            Slog.v(TAG, "DENY instant app installed;"
6674                                    + " pkg: " + packageName);
6675                        }
6676                        return false;
6677                    }
6678                }
6679            }
6680        }
6681        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6682        return true;
6683    }
6684
6685    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6686            Intent origIntent, String resolvedType, String callingPackage,
6687            Bundle verificationBundle, int userId) {
6688        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6689                new InstantAppRequest(responseObj, origIntent, resolvedType,
6690                        callingPackage, userId, verificationBundle));
6691        mHandler.sendMessage(msg);
6692    }
6693
6694    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6695            int flags, List<ResolveInfo> query, int userId) {
6696        if (query != null) {
6697            final int N = query.size();
6698            if (N == 1) {
6699                return query.get(0);
6700            } else if (N > 1) {
6701                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6702                // If there is more than one activity with the same priority,
6703                // then let the user decide between them.
6704                ResolveInfo r0 = query.get(0);
6705                ResolveInfo r1 = query.get(1);
6706                if (DEBUG_INTENT_MATCHING || debug) {
6707                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6708                            + r1.activityInfo.name + "=" + r1.priority);
6709                }
6710                // If the first activity has a higher priority, or a different
6711                // default, then it is always desirable to pick it.
6712                if (r0.priority != r1.priority
6713                        || r0.preferredOrder != r1.preferredOrder
6714                        || r0.isDefault != r1.isDefault) {
6715                    return query.get(0);
6716                }
6717                // If we have saved a preference for a preferred activity for
6718                // this Intent, use that.
6719                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6720                        flags, query, r0.priority, true, false, debug, userId);
6721                if (ri != null) {
6722                    return ri;
6723                }
6724                // If we have an ephemeral app, use it
6725                for (int i = 0; i < N; i++) {
6726                    ri = query.get(i);
6727                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6728                        final String packageName = ri.activityInfo.packageName;
6729                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6730                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6731                        final int status = (int)(packedStatus >> 32);
6732                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6733                            return ri;
6734                        }
6735                    }
6736                }
6737                ri = new ResolveInfo(mResolveInfo);
6738                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6739                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6740                // If all of the options come from the same package, show the application's
6741                // label and icon instead of the generic resolver's.
6742                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6743                // and then throw away the ResolveInfo itself, meaning that the caller loses
6744                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6745                // a fallback for this case; we only set the target package's resources on
6746                // the ResolveInfo, not the ActivityInfo.
6747                final String intentPackage = intent.getPackage();
6748                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6749                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6750                    ri.resolvePackageName = intentPackage;
6751                    if (userNeedsBadging(userId)) {
6752                        ri.noResourceId = true;
6753                    } else {
6754                        ri.icon = appi.icon;
6755                    }
6756                    ri.iconResourceId = appi.icon;
6757                    ri.labelRes = appi.labelRes;
6758                }
6759                ri.activityInfo.applicationInfo = new ApplicationInfo(
6760                        ri.activityInfo.applicationInfo);
6761                if (userId != 0) {
6762                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6763                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6764                }
6765                // Make sure that the resolver is displayable in car mode
6766                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6767                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6768                return ri;
6769            }
6770        }
6771        return null;
6772    }
6773
6774    /**
6775     * Return true if the given list is not empty and all of its contents have
6776     * an activityInfo with the given package name.
6777     */
6778    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6779        if (ArrayUtils.isEmpty(list)) {
6780            return false;
6781        }
6782        for (int i = 0, N = list.size(); i < N; i++) {
6783            final ResolveInfo ri = list.get(i);
6784            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6785            if (ai == null || !packageName.equals(ai.packageName)) {
6786                return false;
6787            }
6788        }
6789        return true;
6790    }
6791
6792    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6793            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6794        final int N = query.size();
6795        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6796                .get(userId);
6797        // Get the list of persistent preferred activities that handle the intent
6798        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6799        List<PersistentPreferredActivity> pprefs = ppir != null
6800                ? ppir.queryIntent(intent, resolvedType,
6801                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6802                        userId)
6803                : null;
6804        if (pprefs != null && pprefs.size() > 0) {
6805            final int M = pprefs.size();
6806            for (int i=0; i<M; i++) {
6807                final PersistentPreferredActivity ppa = pprefs.get(i);
6808                if (DEBUG_PREFERRED || debug) {
6809                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6810                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6811                            + "\n  component=" + ppa.mComponent);
6812                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6813                }
6814                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6815                        flags | MATCH_DISABLED_COMPONENTS, userId);
6816                if (DEBUG_PREFERRED || debug) {
6817                    Slog.v(TAG, "Found persistent preferred activity:");
6818                    if (ai != null) {
6819                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6820                    } else {
6821                        Slog.v(TAG, "  null");
6822                    }
6823                }
6824                if (ai == null) {
6825                    // This previously registered persistent preferred activity
6826                    // component is no longer known. Ignore it and do NOT remove it.
6827                    continue;
6828                }
6829                for (int j=0; j<N; j++) {
6830                    final ResolveInfo ri = query.get(j);
6831                    if (!ri.activityInfo.applicationInfo.packageName
6832                            .equals(ai.applicationInfo.packageName)) {
6833                        continue;
6834                    }
6835                    if (!ri.activityInfo.name.equals(ai.name)) {
6836                        continue;
6837                    }
6838                    //  Found a persistent preference that can handle the intent.
6839                    if (DEBUG_PREFERRED || debug) {
6840                        Slog.v(TAG, "Returning persistent preferred activity: " +
6841                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6842                    }
6843                    return ri;
6844                }
6845            }
6846        }
6847        return null;
6848    }
6849
6850    // TODO: handle preferred activities missing while user has amnesia
6851    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6852            List<ResolveInfo> query, int priority, boolean always,
6853            boolean removeMatches, boolean debug, int userId) {
6854        if (!sUserManager.exists(userId)) return null;
6855        final int callingUid = Binder.getCallingUid();
6856        flags = updateFlagsForResolve(
6857                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6858        intent = updateIntentForResolve(intent);
6859        // writer
6860        synchronized (mPackages) {
6861            // Try to find a matching persistent preferred activity.
6862            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6863                    debug, userId);
6864
6865            // If a persistent preferred activity matched, use it.
6866            if (pri != null) {
6867                return pri;
6868            }
6869
6870            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6871            // Get the list of preferred activities that handle the intent
6872            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6873            List<PreferredActivity> prefs = pir != null
6874                    ? pir.queryIntent(intent, resolvedType,
6875                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6876                            userId)
6877                    : null;
6878            if (prefs != null && prefs.size() > 0) {
6879                boolean changed = false;
6880                try {
6881                    // First figure out how good the original match set is.
6882                    // We will only allow preferred activities that came
6883                    // from the same match quality.
6884                    int match = 0;
6885
6886                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6887
6888                    final int N = query.size();
6889                    for (int j=0; j<N; j++) {
6890                        final ResolveInfo ri = query.get(j);
6891                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6892                                + ": 0x" + Integer.toHexString(match));
6893                        if (ri.match > match) {
6894                            match = ri.match;
6895                        }
6896                    }
6897
6898                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6899                            + Integer.toHexString(match));
6900
6901                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6902                    final int M = prefs.size();
6903                    for (int i=0; i<M; i++) {
6904                        final PreferredActivity pa = prefs.get(i);
6905                        if (DEBUG_PREFERRED || debug) {
6906                            Slog.v(TAG, "Checking PreferredActivity ds="
6907                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6908                                    + "\n  component=" + pa.mPref.mComponent);
6909                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6910                        }
6911                        if (pa.mPref.mMatch != match) {
6912                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6913                                    + Integer.toHexString(pa.mPref.mMatch));
6914                            continue;
6915                        }
6916                        // If it's not an "always" type preferred activity and that's what we're
6917                        // looking for, skip it.
6918                        if (always && !pa.mPref.mAlways) {
6919                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6920                            continue;
6921                        }
6922                        final ActivityInfo ai = getActivityInfo(
6923                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6924                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6925                                userId);
6926                        if (DEBUG_PREFERRED || debug) {
6927                            Slog.v(TAG, "Found preferred activity:");
6928                            if (ai != null) {
6929                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6930                            } else {
6931                                Slog.v(TAG, "  null");
6932                            }
6933                        }
6934                        if (ai == null) {
6935                            // This previously registered preferred activity
6936                            // component is no longer known.  Most likely an update
6937                            // to the app was installed and in the new version this
6938                            // component no longer exists.  Clean it up by removing
6939                            // it from the preferred activities list, and skip it.
6940                            Slog.w(TAG, "Removing dangling preferred activity: "
6941                                    + pa.mPref.mComponent);
6942                            pir.removeFilter(pa);
6943                            changed = true;
6944                            continue;
6945                        }
6946                        for (int j=0; j<N; j++) {
6947                            final ResolveInfo ri = query.get(j);
6948                            if (!ri.activityInfo.applicationInfo.packageName
6949                                    .equals(ai.applicationInfo.packageName)) {
6950                                continue;
6951                            }
6952                            if (!ri.activityInfo.name.equals(ai.name)) {
6953                                continue;
6954                            }
6955
6956                            if (removeMatches) {
6957                                pir.removeFilter(pa);
6958                                changed = true;
6959                                if (DEBUG_PREFERRED) {
6960                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6961                                }
6962                                break;
6963                            }
6964
6965                            // Okay we found a previously set preferred or last chosen app.
6966                            // If the result set is different from when this
6967                            // was created, we need to clear it and re-ask the
6968                            // user their preference, if we're looking for an "always" type entry.
6969                            if (always && !pa.mPref.sameSet(query)) {
6970                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6971                                        + intent + " type " + resolvedType);
6972                                if (DEBUG_PREFERRED) {
6973                                    Slog.v(TAG, "Removing preferred activity since set changed "
6974                                            + pa.mPref.mComponent);
6975                                }
6976                                pir.removeFilter(pa);
6977                                // Re-add the filter as a "last chosen" entry (!always)
6978                                PreferredActivity lastChosen = new PreferredActivity(
6979                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6980                                pir.addFilter(lastChosen);
6981                                changed = true;
6982                                return null;
6983                            }
6984
6985                            // Yay! Either the set matched or we're looking for the last chosen
6986                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6987                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6988                            return ri;
6989                        }
6990                    }
6991                } finally {
6992                    if (changed) {
6993                        if (DEBUG_PREFERRED) {
6994                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6995                        }
6996                        scheduleWritePackageRestrictionsLocked(userId);
6997                    }
6998                }
6999            }
7000        }
7001        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7002        return null;
7003    }
7004
7005    /*
7006     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7007     */
7008    @Override
7009    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7010            int targetUserId) {
7011        mContext.enforceCallingOrSelfPermission(
7012                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7013        List<CrossProfileIntentFilter> matches =
7014                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7015        if (matches != null) {
7016            int size = matches.size();
7017            for (int i = 0; i < size; i++) {
7018                if (matches.get(i).getTargetUserId() == targetUserId) return true;
7019            }
7020        }
7021        if (hasWebURI(intent)) {
7022            // cross-profile app linking works only towards the parent.
7023            final int callingUid = Binder.getCallingUid();
7024            final UserInfo parent = getProfileParent(sourceUserId);
7025            synchronized(mPackages) {
7026                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7027                        false /*includeInstantApps*/);
7028                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7029                        intent, resolvedType, flags, sourceUserId, parent.id);
7030                return xpDomainInfo != null;
7031            }
7032        }
7033        return false;
7034    }
7035
7036    private UserInfo getProfileParent(int userId) {
7037        final long identity = Binder.clearCallingIdentity();
7038        try {
7039            return sUserManager.getProfileParent(userId);
7040        } finally {
7041            Binder.restoreCallingIdentity(identity);
7042        }
7043    }
7044
7045    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7046            String resolvedType, int userId) {
7047        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7048        if (resolver != null) {
7049            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7050        }
7051        return null;
7052    }
7053
7054    @Override
7055    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7056            String resolvedType, int flags, int userId) {
7057        try {
7058            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7059
7060            return new ParceledListSlice<>(
7061                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7062        } finally {
7063            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7064        }
7065    }
7066
7067    /**
7068     * Returns the package name of the calling Uid if it's an instant app. If it isn't
7069     * instant, returns {@code null}.
7070     */
7071    private String getInstantAppPackageName(int callingUid) {
7072        synchronized (mPackages) {
7073            // If the caller is an isolated app use the owner's uid for the lookup.
7074            if (Process.isIsolated(callingUid)) {
7075                callingUid = mIsolatedOwners.get(callingUid);
7076            }
7077            final int appId = UserHandle.getAppId(callingUid);
7078            final Object obj = mSettings.getUserIdLPr(appId);
7079            if (obj instanceof PackageSetting) {
7080                final PackageSetting ps = (PackageSetting) obj;
7081                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7082                return isInstantApp ? ps.pkg.packageName : null;
7083            }
7084        }
7085        return null;
7086    }
7087
7088    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7089            String resolvedType, int flags, int userId) {
7090        return queryIntentActivitiesInternal(
7091                intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
7092    }
7093
7094    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7095            String resolvedType, int flags, int filterCallingUid, int userId,
7096            boolean resolveForStart) {
7097        if (!sUserManager.exists(userId)) return Collections.emptyList();
7098        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7099        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7100                false /* requireFullPermission */, false /* checkShell */,
7101                "query intent activities");
7102        final String pkgName = intent.getPackage();
7103        ComponentName comp = intent.getComponent();
7104        if (comp == null) {
7105            if (intent.getSelector() != null) {
7106                intent = intent.getSelector();
7107                comp = intent.getComponent();
7108            }
7109        }
7110
7111        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7112                comp != null || pkgName != null /*onlyExposedExplicitly*/);
7113        if (comp != null) {
7114            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7115            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7116            if (ai != null) {
7117                // When specifying an explicit component, we prevent the activity from being
7118                // used when either 1) the calling package is normal and the activity is within
7119                // an ephemeral application or 2) the calling package is ephemeral and the
7120                // activity is not visible to ephemeral applications.
7121                final boolean matchInstantApp =
7122                        (flags & PackageManager.MATCH_INSTANT) != 0;
7123                final boolean matchVisibleToInstantAppOnly =
7124                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7125                final boolean matchExplicitlyVisibleOnly =
7126                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7127                final boolean isCallerInstantApp =
7128                        instantAppPkgName != null;
7129                final boolean isTargetSameInstantApp =
7130                        comp.getPackageName().equals(instantAppPkgName);
7131                final boolean isTargetInstantApp =
7132                        (ai.applicationInfo.privateFlags
7133                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7134                final boolean isTargetVisibleToInstantApp =
7135                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7136                final boolean isTargetExplicitlyVisibleToInstantApp =
7137                        isTargetVisibleToInstantApp
7138                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7139                final boolean isTargetHiddenFromInstantApp =
7140                        !isTargetVisibleToInstantApp
7141                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7142                final boolean blockResolution =
7143                        !isTargetSameInstantApp
7144                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7145                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7146                                        && isTargetHiddenFromInstantApp));
7147                if (!blockResolution) {
7148                    final ResolveInfo ri = new ResolveInfo();
7149                    ri.activityInfo = ai;
7150                    list.add(ri);
7151                }
7152            }
7153            return applyPostResolutionFilter(list, instantAppPkgName);
7154        }
7155
7156        // reader
7157        boolean sortResult = false;
7158        boolean addEphemeral = false;
7159        List<ResolveInfo> result;
7160        final boolean ephemeralDisabled = isEphemeralDisabled();
7161        synchronized (mPackages) {
7162            if (pkgName == null) {
7163                List<CrossProfileIntentFilter> matchingFilters =
7164                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7165                // Check for results that need to skip the current profile.
7166                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7167                        resolvedType, flags, userId);
7168                if (xpResolveInfo != null) {
7169                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7170                    xpResult.add(xpResolveInfo);
7171                    return applyPostResolutionFilter(
7172                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
7173                }
7174
7175                // Check for results in the current profile.
7176                result = filterIfNotSystemUser(mActivities.queryIntent(
7177                        intent, resolvedType, flags, userId), userId);
7178                addEphemeral = !ephemeralDisabled
7179                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7180                // Check for cross profile results.
7181                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7182                xpResolveInfo = queryCrossProfileIntents(
7183                        matchingFilters, intent, resolvedType, flags, userId,
7184                        hasNonNegativePriorityResult);
7185                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7186                    boolean isVisibleToUser = filterIfNotSystemUser(
7187                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
7188                    if (isVisibleToUser) {
7189                        result.add(xpResolveInfo);
7190                        sortResult = true;
7191                    }
7192                }
7193                if (hasWebURI(intent)) {
7194                    CrossProfileDomainInfo xpDomainInfo = null;
7195                    final UserInfo parent = getProfileParent(userId);
7196                    if (parent != null) {
7197                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7198                                flags, userId, parent.id);
7199                    }
7200                    if (xpDomainInfo != null) {
7201                        if (xpResolveInfo != null) {
7202                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
7203                            // in the result.
7204                            result.remove(xpResolveInfo);
7205                        }
7206                        if (result.size() == 0 && !addEphemeral) {
7207                            // No result in current profile, but found candidate in parent user.
7208                            // And we are not going to add emphemeral app, so we can return the
7209                            // result straight away.
7210                            result.add(xpDomainInfo.resolveInfo);
7211                            return applyPostResolutionFilter(result, instantAppPkgName);
7212                        }
7213                    } else if (result.size() <= 1 && !addEphemeral) {
7214                        // No result in parent user and <= 1 result in current profile, and we
7215                        // are not going to add emphemeral app, so we can return the result without
7216                        // further processing.
7217                        return applyPostResolutionFilter(result, instantAppPkgName);
7218                    }
7219                    // We have more than one candidate (combining results from current and parent
7220                    // profile), so we need filtering and sorting.
7221                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7222                            intent, flags, result, xpDomainInfo, userId);
7223                    sortResult = true;
7224                }
7225            } else {
7226                final PackageParser.Package pkg = mPackages.get(pkgName);
7227                result = null;
7228                if (pkg != null) {
7229                    result = filterIfNotSystemUser(
7230                            mActivities.queryIntentForPackage(
7231                                    intent, resolvedType, flags, pkg.activities, userId),
7232                            userId);
7233                }
7234                if (result == null || result.size() == 0) {
7235                    // the caller wants to resolve for a particular package; however, there
7236                    // were no installed results, so, try to find an ephemeral result
7237                    addEphemeral = !ephemeralDisabled
7238                            && isInstantAppAllowed(
7239                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7240                    if (result == null) {
7241                        result = new ArrayList<>();
7242                    }
7243                }
7244            }
7245        }
7246        if (addEphemeral) {
7247            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
7248        }
7249        if (sortResult) {
7250            Collections.sort(result, mResolvePrioritySorter);
7251        }
7252        return applyPostResolutionFilter(result, instantAppPkgName);
7253    }
7254
7255    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7256            String resolvedType, int flags, int userId) {
7257        // first, check to see if we've got an instant app already installed
7258        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7259        ResolveInfo localInstantApp = null;
7260        boolean blockResolution = false;
7261        if (!alreadyResolvedLocally) {
7262            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7263                    flags
7264                        | PackageManager.GET_RESOLVED_FILTER
7265                        | PackageManager.MATCH_INSTANT
7266                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7267                    userId);
7268            for (int i = instantApps.size() - 1; i >= 0; --i) {
7269                final ResolveInfo info = instantApps.get(i);
7270                final String packageName = info.activityInfo.packageName;
7271                final PackageSetting ps = mSettings.mPackages.get(packageName);
7272                if (ps.getInstantApp(userId)) {
7273                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7274                    final int status = (int)(packedStatus >> 32);
7275                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7276                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7277                        // there's a local instant application installed, but, the user has
7278                        // chosen to never use it; skip resolution and don't acknowledge
7279                        // an instant application is even available
7280                        if (DEBUG_EPHEMERAL) {
7281                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7282                        }
7283                        blockResolution = true;
7284                        break;
7285                    } else {
7286                        // we have a locally installed instant application; skip resolution
7287                        // but acknowledge there's an instant application available
7288                        if (DEBUG_EPHEMERAL) {
7289                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7290                        }
7291                        localInstantApp = info;
7292                        break;
7293                    }
7294                }
7295            }
7296        }
7297        // no app installed, let's see if one's available
7298        AuxiliaryResolveInfo auxiliaryResponse = null;
7299        if (!blockResolution) {
7300            if (localInstantApp == null) {
7301                // we don't have an instant app locally, resolve externally
7302                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7303                final InstantAppRequest requestObject = new InstantAppRequest(
7304                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7305                        null /*callingPackage*/, userId, null /*verificationBundle*/);
7306                auxiliaryResponse =
7307                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7308                                mContext, mInstantAppResolverConnection, requestObject);
7309                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7310            } else {
7311                // we have an instant application locally, but, we can't admit that since
7312                // callers shouldn't be able to determine prior browsing. create a dummy
7313                // auxiliary response so the downstream code behaves as if there's an
7314                // instant application available externally. when it comes time to start
7315                // the instant application, we'll do the right thing.
7316                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7317                auxiliaryResponse = new AuxiliaryResolveInfo(
7318                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
7319            }
7320        }
7321        if (auxiliaryResponse != null) {
7322            if (DEBUG_EPHEMERAL) {
7323                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7324            }
7325            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7326            final PackageSetting ps =
7327                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7328            if (ps != null) {
7329                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7330                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7331                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7332                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7333                // make sure this resolver is the default
7334                ephemeralInstaller.isDefault = true;
7335                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7336                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7337                // add a non-generic filter
7338                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7339                ephemeralInstaller.filter.addDataPath(
7340                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7341                ephemeralInstaller.isInstantAppAvailable = true;
7342                result.add(ephemeralInstaller);
7343            }
7344        }
7345        return result;
7346    }
7347
7348    private static class CrossProfileDomainInfo {
7349        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7350        ResolveInfo resolveInfo;
7351        /* Best domain verification status of the activities found in the other profile */
7352        int bestDomainVerificationStatus;
7353    }
7354
7355    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7356            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7357        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7358                sourceUserId)) {
7359            return null;
7360        }
7361        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7362                resolvedType, flags, parentUserId);
7363
7364        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7365            return null;
7366        }
7367        CrossProfileDomainInfo result = null;
7368        int size = resultTargetUser.size();
7369        for (int i = 0; i < size; i++) {
7370            ResolveInfo riTargetUser = resultTargetUser.get(i);
7371            // Intent filter verification is only for filters that specify a host. So don't return
7372            // those that handle all web uris.
7373            if (riTargetUser.handleAllWebDataURI) {
7374                continue;
7375            }
7376            String packageName = riTargetUser.activityInfo.packageName;
7377            PackageSetting ps = mSettings.mPackages.get(packageName);
7378            if (ps == null) {
7379                continue;
7380            }
7381            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7382            int status = (int)(verificationState >> 32);
7383            if (result == null) {
7384                result = new CrossProfileDomainInfo();
7385                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7386                        sourceUserId, parentUserId);
7387                result.bestDomainVerificationStatus = status;
7388            } else {
7389                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7390                        result.bestDomainVerificationStatus);
7391            }
7392        }
7393        // Don't consider matches with status NEVER across profiles.
7394        if (result != null && result.bestDomainVerificationStatus
7395                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7396            return null;
7397        }
7398        return result;
7399    }
7400
7401    /**
7402     * Verification statuses are ordered from the worse to the best, except for
7403     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7404     */
7405    private int bestDomainVerificationStatus(int status1, int status2) {
7406        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7407            return status2;
7408        }
7409        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7410            return status1;
7411        }
7412        return (int) MathUtils.max(status1, status2);
7413    }
7414
7415    private boolean isUserEnabled(int userId) {
7416        long callingId = Binder.clearCallingIdentity();
7417        try {
7418            UserInfo userInfo = sUserManager.getUserInfo(userId);
7419            return userInfo != null && userInfo.isEnabled();
7420        } finally {
7421            Binder.restoreCallingIdentity(callingId);
7422        }
7423    }
7424
7425    /**
7426     * Filter out activities with systemUserOnly flag set, when current user is not System.
7427     *
7428     * @return filtered list
7429     */
7430    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7431        if (userId == UserHandle.USER_SYSTEM) {
7432            return resolveInfos;
7433        }
7434        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7435            ResolveInfo info = resolveInfos.get(i);
7436            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7437                resolveInfos.remove(i);
7438            }
7439        }
7440        return resolveInfos;
7441    }
7442
7443    /**
7444     * Filters out ephemeral activities.
7445     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7446     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7447     *
7448     * @param resolveInfos The pre-filtered list of resolved activities
7449     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7450     *          is performed.
7451     * @return A filtered list of resolved activities.
7452     */
7453    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7454            String ephemeralPkgName) {
7455        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7456            final ResolveInfo info = resolveInfos.get(i);
7457            // TODO: When adding on-demand split support for non-instant apps, remove this check
7458            // and always apply post filtering
7459            // allow activities that are defined in the provided package
7460            if (info.activityInfo.splitName != null
7461                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7462                            info.activityInfo.splitName)) {
7463                // requested activity is defined in a split that hasn't been installed yet.
7464                // add the installer to the resolve list
7465                if (DEBUG_INSTALL) {
7466                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
7467                }
7468                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7469                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7470                        info.activityInfo.packageName, info.activityInfo.splitName,
7471                        info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
7472                // make sure this resolver is the default
7473                installerInfo.isDefault = true;
7474                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7475                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7476                // add a non-generic filter
7477                installerInfo.filter = new IntentFilter();
7478                // load resources from the correct package
7479                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7480                resolveInfos.set(i, installerInfo);
7481                continue;
7482            }
7483            // caller is a full app, don't need to apply any other filtering
7484            if (ephemeralPkgName == null) {
7485                continue;
7486            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7487                // caller is same app; don't need to apply any other filtering
7488                continue;
7489            }
7490            // allow activities that have been explicitly exposed to ephemeral apps
7491            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7492            if (!isEphemeralApp
7493                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7494                continue;
7495            }
7496            resolveInfos.remove(i);
7497        }
7498        return resolveInfos;
7499    }
7500
7501    /**
7502     * @param resolveInfos list of resolve infos in descending priority order
7503     * @return if the list contains a resolve info with non-negative priority
7504     */
7505    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7506        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7507    }
7508
7509    private static boolean hasWebURI(Intent intent) {
7510        if (intent.getData() == null) {
7511            return false;
7512        }
7513        final String scheme = intent.getScheme();
7514        if (TextUtils.isEmpty(scheme)) {
7515            return false;
7516        }
7517        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7518    }
7519
7520    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7521            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7522            int userId) {
7523        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7524
7525        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7526            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7527                    candidates.size());
7528        }
7529
7530        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7531        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7532        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7533        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7534        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7535        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7536
7537        synchronized (mPackages) {
7538            final int count = candidates.size();
7539            // First, try to use linked apps. Partition the candidates into four lists:
7540            // one for the final results, one for the "do not use ever", one for "undefined status"
7541            // and finally one for "browser app type".
7542            for (int n=0; n<count; n++) {
7543                ResolveInfo info = candidates.get(n);
7544                String packageName = info.activityInfo.packageName;
7545                PackageSetting ps = mSettings.mPackages.get(packageName);
7546                if (ps != null) {
7547                    // Add to the special match all list (Browser use case)
7548                    if (info.handleAllWebDataURI) {
7549                        matchAllList.add(info);
7550                        continue;
7551                    }
7552                    // Try to get the status from User settings first
7553                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7554                    int status = (int)(packedStatus >> 32);
7555                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7556                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7557                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7558                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7559                                    + " : linkgen=" + linkGeneration);
7560                        }
7561                        // Use link-enabled generation as preferredOrder, i.e.
7562                        // prefer newly-enabled over earlier-enabled.
7563                        info.preferredOrder = linkGeneration;
7564                        alwaysList.add(info);
7565                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7566                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7567                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7568                        }
7569                        neverList.add(info);
7570                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7571                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7572                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7573                        }
7574                        alwaysAskList.add(info);
7575                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7576                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7577                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7578                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7579                        }
7580                        undefinedList.add(info);
7581                    }
7582                }
7583            }
7584
7585            // We'll want to include browser possibilities in a few cases
7586            boolean includeBrowser = false;
7587
7588            // First try to add the "always" resolution(s) for the current user, if any
7589            if (alwaysList.size() > 0) {
7590                result.addAll(alwaysList);
7591            } else {
7592                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7593                result.addAll(undefinedList);
7594                // Maybe add one for the other profile.
7595                if (xpDomainInfo != null && (
7596                        xpDomainInfo.bestDomainVerificationStatus
7597                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7598                    result.add(xpDomainInfo.resolveInfo);
7599                }
7600                includeBrowser = true;
7601            }
7602
7603            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7604            // If there were 'always' entries their preferred order has been set, so we also
7605            // back that off to make the alternatives equivalent
7606            if (alwaysAskList.size() > 0) {
7607                for (ResolveInfo i : result) {
7608                    i.preferredOrder = 0;
7609                }
7610                result.addAll(alwaysAskList);
7611                includeBrowser = true;
7612            }
7613
7614            if (includeBrowser) {
7615                // Also add browsers (all of them or only the default one)
7616                if (DEBUG_DOMAIN_VERIFICATION) {
7617                    Slog.v(TAG, "   ...including browsers in candidate set");
7618                }
7619                if ((matchFlags & MATCH_ALL) != 0) {
7620                    result.addAll(matchAllList);
7621                } else {
7622                    // Browser/generic handling case.  If there's a default browser, go straight
7623                    // to that (but only if there is no other higher-priority match).
7624                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7625                    int maxMatchPrio = 0;
7626                    ResolveInfo defaultBrowserMatch = null;
7627                    final int numCandidates = matchAllList.size();
7628                    for (int n = 0; n < numCandidates; n++) {
7629                        ResolveInfo info = matchAllList.get(n);
7630                        // track the highest overall match priority...
7631                        if (info.priority > maxMatchPrio) {
7632                            maxMatchPrio = info.priority;
7633                        }
7634                        // ...and the highest-priority default browser match
7635                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7636                            if (defaultBrowserMatch == null
7637                                    || (defaultBrowserMatch.priority < info.priority)) {
7638                                if (debug) {
7639                                    Slog.v(TAG, "Considering default browser match " + info);
7640                                }
7641                                defaultBrowserMatch = info;
7642                            }
7643                        }
7644                    }
7645                    if (defaultBrowserMatch != null
7646                            && defaultBrowserMatch.priority >= maxMatchPrio
7647                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7648                    {
7649                        if (debug) {
7650                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7651                        }
7652                        result.add(defaultBrowserMatch);
7653                    } else {
7654                        result.addAll(matchAllList);
7655                    }
7656                }
7657
7658                // If there is nothing selected, add all candidates and remove the ones that the user
7659                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7660                if (result.size() == 0) {
7661                    result.addAll(candidates);
7662                    result.removeAll(neverList);
7663                }
7664            }
7665        }
7666        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7667            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7668                    result.size());
7669            for (ResolveInfo info : result) {
7670                Slog.v(TAG, "  + " + info.activityInfo);
7671            }
7672        }
7673        return result;
7674    }
7675
7676    // Returns a packed value as a long:
7677    //
7678    // high 'int'-sized word: link status: undefined/ask/never/always.
7679    // low 'int'-sized word: relative priority among 'always' results.
7680    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7681        long result = ps.getDomainVerificationStatusForUser(userId);
7682        // if none available, get the master status
7683        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7684            if (ps.getIntentFilterVerificationInfo() != null) {
7685                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7686            }
7687        }
7688        return result;
7689    }
7690
7691    private ResolveInfo querySkipCurrentProfileIntents(
7692            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7693            int flags, int sourceUserId) {
7694        if (matchingFilters != null) {
7695            int size = matchingFilters.size();
7696            for (int i = 0; i < size; i ++) {
7697                CrossProfileIntentFilter filter = matchingFilters.get(i);
7698                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7699                    // Checking if there are activities in the target user that can handle the
7700                    // intent.
7701                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7702                            resolvedType, flags, sourceUserId);
7703                    if (resolveInfo != null) {
7704                        return resolveInfo;
7705                    }
7706                }
7707            }
7708        }
7709        return null;
7710    }
7711
7712    // Return matching ResolveInfo in target user if any.
7713    private ResolveInfo queryCrossProfileIntents(
7714            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7715            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7716        if (matchingFilters != null) {
7717            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7718            // match the same intent. For performance reasons, it is better not to
7719            // run queryIntent twice for the same userId
7720            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7721            int size = matchingFilters.size();
7722            for (int i = 0; i < size; i++) {
7723                CrossProfileIntentFilter filter = matchingFilters.get(i);
7724                int targetUserId = filter.getTargetUserId();
7725                boolean skipCurrentProfile =
7726                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7727                boolean skipCurrentProfileIfNoMatchFound =
7728                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7729                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7730                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7731                    // Checking if there are activities in the target user that can handle the
7732                    // intent.
7733                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7734                            resolvedType, flags, sourceUserId);
7735                    if (resolveInfo != null) return resolveInfo;
7736                    alreadyTriedUserIds.put(targetUserId, true);
7737                }
7738            }
7739        }
7740        return null;
7741    }
7742
7743    /**
7744     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7745     * will forward the intent to the filter's target user.
7746     * Otherwise, returns null.
7747     */
7748    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7749            String resolvedType, int flags, int sourceUserId) {
7750        int targetUserId = filter.getTargetUserId();
7751        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7752                resolvedType, flags, targetUserId);
7753        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7754            // If all the matches in the target profile are suspended, return null.
7755            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7756                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7757                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7758                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7759                            targetUserId);
7760                }
7761            }
7762        }
7763        return null;
7764    }
7765
7766    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7767            int sourceUserId, int targetUserId) {
7768        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7769        long ident = Binder.clearCallingIdentity();
7770        boolean targetIsProfile;
7771        try {
7772            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7773        } finally {
7774            Binder.restoreCallingIdentity(ident);
7775        }
7776        String className;
7777        if (targetIsProfile) {
7778            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7779        } else {
7780            className = FORWARD_INTENT_TO_PARENT;
7781        }
7782        ComponentName forwardingActivityComponentName = new ComponentName(
7783                mAndroidApplication.packageName, className);
7784        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7785                sourceUserId);
7786        if (!targetIsProfile) {
7787            forwardingActivityInfo.showUserIcon = targetUserId;
7788            forwardingResolveInfo.noResourceId = true;
7789        }
7790        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7791        forwardingResolveInfo.priority = 0;
7792        forwardingResolveInfo.preferredOrder = 0;
7793        forwardingResolveInfo.match = 0;
7794        forwardingResolveInfo.isDefault = true;
7795        forwardingResolveInfo.filter = filter;
7796        forwardingResolveInfo.targetUserId = targetUserId;
7797        return forwardingResolveInfo;
7798    }
7799
7800    @Override
7801    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7802            Intent[] specifics, String[] specificTypes, Intent intent,
7803            String resolvedType, int flags, int userId) {
7804        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7805                specificTypes, intent, resolvedType, flags, userId));
7806    }
7807
7808    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7809            Intent[] specifics, String[] specificTypes, Intent intent,
7810            String resolvedType, int flags, int userId) {
7811        if (!sUserManager.exists(userId)) return Collections.emptyList();
7812        final int callingUid = Binder.getCallingUid();
7813        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7814                false /*includeInstantApps*/);
7815        enforceCrossUserPermission(callingUid, userId,
7816                false /*requireFullPermission*/, false /*checkShell*/,
7817                "query intent activity options");
7818        final String resultsAction = intent.getAction();
7819
7820        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7821                | PackageManager.GET_RESOLVED_FILTER, userId);
7822
7823        if (DEBUG_INTENT_MATCHING) {
7824            Log.v(TAG, "Query " + intent + ": " + results);
7825        }
7826
7827        int specificsPos = 0;
7828        int N;
7829
7830        // todo: note that the algorithm used here is O(N^2).  This
7831        // isn't a problem in our current environment, but if we start running
7832        // into situations where we have more than 5 or 10 matches then this
7833        // should probably be changed to something smarter...
7834
7835        // First we go through and resolve each of the specific items
7836        // that were supplied, taking care of removing any corresponding
7837        // duplicate items in the generic resolve list.
7838        if (specifics != null) {
7839            for (int i=0; i<specifics.length; i++) {
7840                final Intent sintent = specifics[i];
7841                if (sintent == null) {
7842                    continue;
7843                }
7844
7845                if (DEBUG_INTENT_MATCHING) {
7846                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7847                }
7848
7849                String action = sintent.getAction();
7850                if (resultsAction != null && resultsAction.equals(action)) {
7851                    // If this action was explicitly requested, then don't
7852                    // remove things that have it.
7853                    action = null;
7854                }
7855
7856                ResolveInfo ri = null;
7857                ActivityInfo ai = null;
7858
7859                ComponentName comp = sintent.getComponent();
7860                if (comp == null) {
7861                    ri = resolveIntent(
7862                        sintent,
7863                        specificTypes != null ? specificTypes[i] : null,
7864                            flags, userId);
7865                    if (ri == null) {
7866                        continue;
7867                    }
7868                    if (ri == mResolveInfo) {
7869                        // ACK!  Must do something better with this.
7870                    }
7871                    ai = ri.activityInfo;
7872                    comp = new ComponentName(ai.applicationInfo.packageName,
7873                            ai.name);
7874                } else {
7875                    ai = getActivityInfo(comp, flags, userId);
7876                    if (ai == null) {
7877                        continue;
7878                    }
7879                }
7880
7881                // Look for any generic query activities that are duplicates
7882                // of this specific one, and remove them from the results.
7883                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7884                N = results.size();
7885                int j;
7886                for (j=specificsPos; j<N; j++) {
7887                    ResolveInfo sri = results.get(j);
7888                    if ((sri.activityInfo.name.equals(comp.getClassName())
7889                            && sri.activityInfo.applicationInfo.packageName.equals(
7890                                    comp.getPackageName()))
7891                        || (action != null && sri.filter.matchAction(action))) {
7892                        results.remove(j);
7893                        if (DEBUG_INTENT_MATCHING) Log.v(
7894                            TAG, "Removing duplicate item from " + j
7895                            + " due to specific " + specificsPos);
7896                        if (ri == null) {
7897                            ri = sri;
7898                        }
7899                        j--;
7900                        N--;
7901                    }
7902                }
7903
7904                // Add this specific item to its proper place.
7905                if (ri == null) {
7906                    ri = new ResolveInfo();
7907                    ri.activityInfo = ai;
7908                }
7909                results.add(specificsPos, ri);
7910                ri.specificIndex = i;
7911                specificsPos++;
7912            }
7913        }
7914
7915        // Now we go through the remaining generic results and remove any
7916        // duplicate actions that are found here.
7917        N = results.size();
7918        for (int i=specificsPos; i<N-1; i++) {
7919            final ResolveInfo rii = results.get(i);
7920            if (rii.filter == null) {
7921                continue;
7922            }
7923
7924            // Iterate over all of the actions of this result's intent
7925            // filter...  typically this should be just one.
7926            final Iterator<String> it = rii.filter.actionsIterator();
7927            if (it == null) {
7928                continue;
7929            }
7930            while (it.hasNext()) {
7931                final String action = it.next();
7932                if (resultsAction != null && resultsAction.equals(action)) {
7933                    // If this action was explicitly requested, then don't
7934                    // remove things that have it.
7935                    continue;
7936                }
7937                for (int j=i+1; j<N; j++) {
7938                    final ResolveInfo rij = results.get(j);
7939                    if (rij.filter != null && rij.filter.hasAction(action)) {
7940                        results.remove(j);
7941                        if (DEBUG_INTENT_MATCHING) Log.v(
7942                            TAG, "Removing duplicate item from " + j
7943                            + " due to action " + action + " at " + i);
7944                        j--;
7945                        N--;
7946                    }
7947                }
7948            }
7949
7950            // If the caller didn't request filter information, drop it now
7951            // so we don't have to marshall/unmarshall it.
7952            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7953                rii.filter = null;
7954            }
7955        }
7956
7957        // Filter out the caller activity if so requested.
7958        if (caller != null) {
7959            N = results.size();
7960            for (int i=0; i<N; i++) {
7961                ActivityInfo ainfo = results.get(i).activityInfo;
7962                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7963                        && caller.getClassName().equals(ainfo.name)) {
7964                    results.remove(i);
7965                    break;
7966                }
7967            }
7968        }
7969
7970        // If the caller didn't request filter information,
7971        // drop them now so we don't have to
7972        // marshall/unmarshall it.
7973        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7974            N = results.size();
7975            for (int i=0; i<N; i++) {
7976                results.get(i).filter = null;
7977            }
7978        }
7979
7980        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7981        return results;
7982    }
7983
7984    @Override
7985    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7986            String resolvedType, int flags, int userId) {
7987        return new ParceledListSlice<>(
7988                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7989    }
7990
7991    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7992            String resolvedType, int flags, int userId) {
7993        if (!sUserManager.exists(userId)) return Collections.emptyList();
7994        final int callingUid = Binder.getCallingUid();
7995        enforceCrossUserPermission(callingUid, userId,
7996                false /*requireFullPermission*/, false /*checkShell*/,
7997                "query intent receivers");
7998        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7999        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8000                false /*includeInstantApps*/);
8001        ComponentName comp = intent.getComponent();
8002        if (comp == null) {
8003            if (intent.getSelector() != null) {
8004                intent = intent.getSelector();
8005                comp = intent.getComponent();
8006            }
8007        }
8008        if (comp != null) {
8009            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8010            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8011            if (ai != null) {
8012                // When specifying an explicit component, we prevent the activity from being
8013                // used when either 1) the calling package is normal and the activity is within
8014                // an instant application or 2) the calling package is ephemeral and the
8015                // activity is not visible to instant applications.
8016                final boolean matchInstantApp =
8017                        (flags & PackageManager.MATCH_INSTANT) != 0;
8018                final boolean matchVisibleToInstantAppOnly =
8019                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8020                final boolean matchExplicitlyVisibleOnly =
8021                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8022                final boolean isCallerInstantApp =
8023                        instantAppPkgName != null;
8024                final boolean isTargetSameInstantApp =
8025                        comp.getPackageName().equals(instantAppPkgName);
8026                final boolean isTargetInstantApp =
8027                        (ai.applicationInfo.privateFlags
8028                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8029                final boolean isTargetVisibleToInstantApp =
8030                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8031                final boolean isTargetExplicitlyVisibleToInstantApp =
8032                        isTargetVisibleToInstantApp
8033                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8034                final boolean isTargetHiddenFromInstantApp =
8035                        !isTargetVisibleToInstantApp
8036                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8037                final boolean blockResolution =
8038                        !isTargetSameInstantApp
8039                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8040                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8041                                        && isTargetHiddenFromInstantApp));
8042                if (!blockResolution) {
8043                    ResolveInfo ri = new ResolveInfo();
8044                    ri.activityInfo = ai;
8045                    list.add(ri);
8046                }
8047            }
8048            return applyPostResolutionFilter(list, instantAppPkgName);
8049        }
8050
8051        // reader
8052        synchronized (mPackages) {
8053            String pkgName = intent.getPackage();
8054            if (pkgName == null) {
8055                final List<ResolveInfo> result =
8056                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
8057                return applyPostResolutionFilter(result, instantAppPkgName);
8058            }
8059            final PackageParser.Package pkg = mPackages.get(pkgName);
8060            if (pkg != null) {
8061                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8062                        intent, resolvedType, flags, pkg.receivers, userId);
8063                return applyPostResolutionFilter(result, instantAppPkgName);
8064            }
8065            return Collections.emptyList();
8066        }
8067    }
8068
8069    @Override
8070    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8071        final int callingUid = Binder.getCallingUid();
8072        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8073    }
8074
8075    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8076            int userId, int callingUid) {
8077        if (!sUserManager.exists(userId)) return null;
8078        flags = updateFlagsForResolve(
8079                flags, userId, intent, callingUid, false /*includeInstantApps*/);
8080        List<ResolveInfo> query = queryIntentServicesInternal(
8081                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8082        if (query != null) {
8083            if (query.size() >= 1) {
8084                // If there is more than one service with the same priority,
8085                // just arbitrarily pick the first one.
8086                return query.get(0);
8087            }
8088        }
8089        return null;
8090    }
8091
8092    @Override
8093    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8094            String resolvedType, int flags, int userId) {
8095        final int callingUid = Binder.getCallingUid();
8096        return new ParceledListSlice<>(queryIntentServicesInternal(
8097                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8098    }
8099
8100    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8101            String resolvedType, int flags, int userId, int callingUid,
8102            boolean includeInstantApps) {
8103        if (!sUserManager.exists(userId)) return Collections.emptyList();
8104        enforceCrossUserPermission(callingUid, userId,
8105                false /*requireFullPermission*/, false /*checkShell*/,
8106                "query intent receivers");
8107        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8108        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8109        ComponentName comp = intent.getComponent();
8110        if (comp == null) {
8111            if (intent.getSelector() != null) {
8112                intent = intent.getSelector();
8113                comp = intent.getComponent();
8114            }
8115        }
8116        if (comp != null) {
8117            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8118            final ServiceInfo si = getServiceInfo(comp, flags, userId);
8119            if (si != null) {
8120                // When specifying an explicit component, we prevent the service from being
8121                // used when either 1) the service is in an instant application and the
8122                // caller is not the same instant application or 2) the calling package is
8123                // ephemeral and the activity is not visible to ephemeral applications.
8124                final boolean matchInstantApp =
8125                        (flags & PackageManager.MATCH_INSTANT) != 0;
8126                final boolean matchVisibleToInstantAppOnly =
8127                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8128                final boolean isCallerInstantApp =
8129                        instantAppPkgName != null;
8130                final boolean isTargetSameInstantApp =
8131                        comp.getPackageName().equals(instantAppPkgName);
8132                final boolean isTargetInstantApp =
8133                        (si.applicationInfo.privateFlags
8134                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8135                final boolean isTargetHiddenFromInstantApp =
8136                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8137                final boolean blockResolution =
8138                        !isTargetSameInstantApp
8139                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8140                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8141                                        && isTargetHiddenFromInstantApp));
8142                if (!blockResolution) {
8143                    final ResolveInfo ri = new ResolveInfo();
8144                    ri.serviceInfo = si;
8145                    list.add(ri);
8146                }
8147            }
8148            return list;
8149        }
8150
8151        // reader
8152        synchronized (mPackages) {
8153            String pkgName = intent.getPackage();
8154            if (pkgName == null) {
8155                return applyPostServiceResolutionFilter(
8156                        mServices.queryIntent(intent, resolvedType, flags, userId),
8157                        instantAppPkgName);
8158            }
8159            final PackageParser.Package pkg = mPackages.get(pkgName);
8160            if (pkg != null) {
8161                return applyPostServiceResolutionFilter(
8162                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8163                                userId),
8164                        instantAppPkgName);
8165            }
8166            return Collections.emptyList();
8167        }
8168    }
8169
8170    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8171            String instantAppPkgName) {
8172        // TODO: When adding on-demand split support for non-instant apps, remove this check
8173        // and always apply post filtering
8174        if (instantAppPkgName == null) {
8175            return resolveInfos;
8176        }
8177        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8178            final ResolveInfo info = resolveInfos.get(i);
8179            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8180            // allow services that are defined in the provided package
8181            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8182                if (info.serviceInfo.splitName != null
8183                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8184                                info.serviceInfo.splitName)) {
8185                    // requested service is defined in a split that hasn't been installed yet.
8186                    // add the installer to the resolve list
8187                    if (DEBUG_EPHEMERAL) {
8188                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8189                    }
8190                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8191                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8192                            info.serviceInfo.packageName, info.serviceInfo.splitName,
8193                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
8194                    // make sure this resolver is the default
8195                    installerInfo.isDefault = true;
8196                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8197                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8198                    // add a non-generic filter
8199                    installerInfo.filter = new IntentFilter();
8200                    // load resources from the correct package
8201                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8202                    resolveInfos.set(i, installerInfo);
8203                }
8204                continue;
8205            }
8206            // allow services that have been explicitly exposed to ephemeral apps
8207            if (!isEphemeralApp
8208                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8209                continue;
8210            }
8211            resolveInfos.remove(i);
8212        }
8213        return resolveInfos;
8214    }
8215
8216    @Override
8217    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8218            String resolvedType, int flags, int userId) {
8219        return new ParceledListSlice<>(
8220                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8221    }
8222
8223    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8224            Intent intent, String resolvedType, int flags, int userId) {
8225        if (!sUserManager.exists(userId)) return Collections.emptyList();
8226        final int callingUid = Binder.getCallingUid();
8227        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8228        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8229                false /*includeInstantApps*/);
8230        ComponentName comp = intent.getComponent();
8231        if (comp == null) {
8232            if (intent.getSelector() != null) {
8233                intent = intent.getSelector();
8234                comp = intent.getComponent();
8235            }
8236        }
8237        if (comp != null) {
8238            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8239            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8240            if (pi != null) {
8241                // When specifying an explicit component, we prevent the provider from being
8242                // used when either 1) the provider is in an instant application and the
8243                // caller is not the same instant application or 2) the calling package is an
8244                // instant application and the provider is not visible to instant applications.
8245                final boolean matchInstantApp =
8246                        (flags & PackageManager.MATCH_INSTANT) != 0;
8247                final boolean matchVisibleToInstantAppOnly =
8248                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8249                final boolean isCallerInstantApp =
8250                        instantAppPkgName != null;
8251                final boolean isTargetSameInstantApp =
8252                        comp.getPackageName().equals(instantAppPkgName);
8253                final boolean isTargetInstantApp =
8254                        (pi.applicationInfo.privateFlags
8255                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8256                final boolean isTargetHiddenFromInstantApp =
8257                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8258                final boolean blockResolution =
8259                        !isTargetSameInstantApp
8260                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8261                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8262                                        && isTargetHiddenFromInstantApp));
8263                if (!blockResolution) {
8264                    final ResolveInfo ri = new ResolveInfo();
8265                    ri.providerInfo = pi;
8266                    list.add(ri);
8267                }
8268            }
8269            return list;
8270        }
8271
8272        // reader
8273        synchronized (mPackages) {
8274            String pkgName = intent.getPackage();
8275            if (pkgName == null) {
8276                return applyPostContentProviderResolutionFilter(
8277                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8278                        instantAppPkgName);
8279            }
8280            final PackageParser.Package pkg = mPackages.get(pkgName);
8281            if (pkg != null) {
8282                return applyPostContentProviderResolutionFilter(
8283                        mProviders.queryIntentForPackage(
8284                        intent, resolvedType, flags, pkg.providers, userId),
8285                        instantAppPkgName);
8286            }
8287            return Collections.emptyList();
8288        }
8289    }
8290
8291    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8292            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8293        // TODO: When adding on-demand split support for non-instant applications, remove
8294        // this check and always apply post filtering
8295        if (instantAppPkgName == null) {
8296            return resolveInfos;
8297        }
8298        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8299            final ResolveInfo info = resolveInfos.get(i);
8300            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8301            // allow providers that are defined in the provided package
8302            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8303                if (info.providerInfo.splitName != null
8304                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8305                                info.providerInfo.splitName)) {
8306                    // requested provider is defined in a split that hasn't been installed yet.
8307                    // add the installer to the resolve list
8308                    if (DEBUG_EPHEMERAL) {
8309                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8310                    }
8311                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8312                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8313                            info.providerInfo.packageName, info.providerInfo.splitName,
8314                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
8315                    // make sure this resolver is the default
8316                    installerInfo.isDefault = true;
8317                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8318                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8319                    // add a non-generic filter
8320                    installerInfo.filter = new IntentFilter();
8321                    // load resources from the correct package
8322                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8323                    resolveInfos.set(i, installerInfo);
8324                }
8325                continue;
8326            }
8327            // allow providers that have been explicitly exposed to instant applications
8328            if (!isEphemeralApp
8329                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8330                continue;
8331            }
8332            resolveInfos.remove(i);
8333        }
8334        return resolveInfos;
8335    }
8336
8337    @Override
8338    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8339        final int callingUid = Binder.getCallingUid();
8340        if (getInstantAppPackageName(callingUid) != null) {
8341            return ParceledListSlice.emptyList();
8342        }
8343        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8344        flags = updateFlagsForPackage(flags, userId, null);
8345        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8346        enforceCrossUserPermission(callingUid, userId,
8347                true /* requireFullPermission */, false /* checkShell */,
8348                "get installed packages");
8349
8350        // writer
8351        synchronized (mPackages) {
8352            ArrayList<PackageInfo> list;
8353            if (listUninstalled) {
8354                list = new ArrayList<>(mSettings.mPackages.size());
8355                for (PackageSetting ps : mSettings.mPackages.values()) {
8356                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8357                        continue;
8358                    }
8359                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8360                        return null;
8361                    }
8362                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8363                    if (pi != null) {
8364                        list.add(pi);
8365                    }
8366                }
8367            } else {
8368                list = new ArrayList<>(mPackages.size());
8369                for (PackageParser.Package p : mPackages.values()) {
8370                    final PackageSetting ps = (PackageSetting) p.mExtras;
8371                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8372                        continue;
8373                    }
8374                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8375                        return null;
8376                    }
8377                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8378                            p.mExtras, flags, userId);
8379                    if (pi != null) {
8380                        list.add(pi);
8381                    }
8382                }
8383            }
8384
8385            return new ParceledListSlice<>(list);
8386        }
8387    }
8388
8389    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8390            String[] permissions, boolean[] tmp, int flags, int userId) {
8391        int numMatch = 0;
8392        final PermissionsState permissionsState = ps.getPermissionsState();
8393        for (int i=0; i<permissions.length; i++) {
8394            final String permission = permissions[i];
8395            if (permissionsState.hasPermission(permission, userId)) {
8396                tmp[i] = true;
8397                numMatch++;
8398            } else {
8399                tmp[i] = false;
8400            }
8401        }
8402        if (numMatch == 0) {
8403            return;
8404        }
8405        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8406
8407        // The above might return null in cases of uninstalled apps or install-state
8408        // skew across users/profiles.
8409        if (pi != null) {
8410            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8411                if (numMatch == permissions.length) {
8412                    pi.requestedPermissions = permissions;
8413                } else {
8414                    pi.requestedPermissions = new String[numMatch];
8415                    numMatch = 0;
8416                    for (int i=0; i<permissions.length; i++) {
8417                        if (tmp[i]) {
8418                            pi.requestedPermissions[numMatch] = permissions[i];
8419                            numMatch++;
8420                        }
8421                    }
8422                }
8423            }
8424            list.add(pi);
8425        }
8426    }
8427
8428    @Override
8429    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8430            String[] permissions, int flags, int userId) {
8431        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8432        flags = updateFlagsForPackage(flags, userId, permissions);
8433        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8434                true /* requireFullPermission */, false /* checkShell */,
8435                "get packages holding permissions");
8436        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8437
8438        // writer
8439        synchronized (mPackages) {
8440            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8441            boolean[] tmpBools = new boolean[permissions.length];
8442            if (listUninstalled) {
8443                for (PackageSetting ps : mSettings.mPackages.values()) {
8444                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8445                            userId);
8446                }
8447            } else {
8448                for (PackageParser.Package pkg : mPackages.values()) {
8449                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8450                    if (ps != null) {
8451                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8452                                userId);
8453                    }
8454                }
8455            }
8456
8457            return new ParceledListSlice<PackageInfo>(list);
8458        }
8459    }
8460
8461    @Override
8462    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8463        final int callingUid = Binder.getCallingUid();
8464        if (getInstantAppPackageName(callingUid) != null) {
8465            return ParceledListSlice.emptyList();
8466        }
8467        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8468        flags = updateFlagsForApplication(flags, userId, null);
8469        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8470
8471        // writer
8472        synchronized (mPackages) {
8473            ArrayList<ApplicationInfo> list;
8474            if (listUninstalled) {
8475                list = new ArrayList<>(mSettings.mPackages.size());
8476                for (PackageSetting ps : mSettings.mPackages.values()) {
8477                    ApplicationInfo ai;
8478                    int effectiveFlags = flags;
8479                    if (ps.isSystem()) {
8480                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8481                    }
8482                    if (ps.pkg != null) {
8483                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8484                            continue;
8485                        }
8486                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8487                            return null;
8488                        }
8489                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8490                                ps.readUserState(userId), userId);
8491                        if (ai != null) {
8492                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8493                        }
8494                    } else {
8495                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8496                        // and already converts to externally visible package name
8497                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8498                                callingUid, effectiveFlags, userId);
8499                    }
8500                    if (ai != null) {
8501                        list.add(ai);
8502                    }
8503                }
8504            } else {
8505                list = new ArrayList<>(mPackages.size());
8506                for (PackageParser.Package p : mPackages.values()) {
8507                    if (p.mExtras != null) {
8508                        PackageSetting ps = (PackageSetting) p.mExtras;
8509                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8510                            continue;
8511                        }
8512                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8513                            return null;
8514                        }
8515                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8516                                ps.readUserState(userId), userId);
8517                        if (ai != null) {
8518                            ai.packageName = resolveExternalPackageNameLPr(p);
8519                            list.add(ai);
8520                        }
8521                    }
8522                }
8523            }
8524
8525            return new ParceledListSlice<>(list);
8526        }
8527    }
8528
8529    @Override
8530    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8531        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8532            return null;
8533        }
8534        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8535            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8536                    "getEphemeralApplications");
8537        }
8538        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8539                true /* requireFullPermission */, false /* checkShell */,
8540                "getEphemeralApplications");
8541        synchronized (mPackages) {
8542            List<InstantAppInfo> instantApps = mInstantAppRegistry
8543                    .getInstantAppsLPr(userId);
8544            if (instantApps != null) {
8545                return new ParceledListSlice<>(instantApps);
8546            }
8547        }
8548        return null;
8549    }
8550
8551    @Override
8552    public boolean isInstantApp(String packageName, int userId) {
8553        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8554                true /* requireFullPermission */, false /* checkShell */,
8555                "isInstantApp");
8556        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8557            return false;
8558        }
8559
8560        synchronized (mPackages) {
8561            int callingUid = Binder.getCallingUid();
8562            if (Process.isIsolated(callingUid)) {
8563                callingUid = mIsolatedOwners.get(callingUid);
8564            }
8565            final PackageSetting ps = mSettings.mPackages.get(packageName);
8566            PackageParser.Package pkg = mPackages.get(packageName);
8567            final boolean returnAllowed =
8568                    ps != null
8569                    && (isCallerSameApp(packageName, callingUid)
8570                            || canViewInstantApps(callingUid, userId)
8571                            || mInstantAppRegistry.isInstantAccessGranted(
8572                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8573            if (returnAllowed) {
8574                return ps.getInstantApp(userId);
8575            }
8576        }
8577        return false;
8578    }
8579
8580    @Override
8581    public byte[] getInstantAppCookie(String packageName, int userId) {
8582        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8583            return null;
8584        }
8585
8586        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8587                true /* requireFullPermission */, false /* checkShell */,
8588                "getInstantAppCookie");
8589        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8590            return null;
8591        }
8592        synchronized (mPackages) {
8593            return mInstantAppRegistry.getInstantAppCookieLPw(
8594                    packageName, userId);
8595        }
8596    }
8597
8598    @Override
8599    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8600        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8601            return true;
8602        }
8603
8604        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8605                true /* requireFullPermission */, true /* checkShell */,
8606                "setInstantAppCookie");
8607        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8608            return false;
8609        }
8610        synchronized (mPackages) {
8611            return mInstantAppRegistry.setInstantAppCookieLPw(
8612                    packageName, cookie, userId);
8613        }
8614    }
8615
8616    @Override
8617    public Bitmap getInstantAppIcon(String packageName, int userId) {
8618        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8619            return null;
8620        }
8621
8622        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8623            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8624                    "getInstantAppIcon");
8625        }
8626        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8627                true /* requireFullPermission */, false /* checkShell */,
8628                "getInstantAppIcon");
8629
8630        synchronized (mPackages) {
8631            return mInstantAppRegistry.getInstantAppIconLPw(
8632                    packageName, userId);
8633        }
8634    }
8635
8636    private boolean isCallerSameApp(String packageName, int uid) {
8637        PackageParser.Package pkg = mPackages.get(packageName);
8638        return pkg != null
8639                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8640    }
8641
8642    @Override
8643    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8644        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8645            return ParceledListSlice.emptyList();
8646        }
8647        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8648    }
8649
8650    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8651        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8652
8653        // reader
8654        synchronized (mPackages) {
8655            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8656            final int userId = UserHandle.getCallingUserId();
8657            while (i.hasNext()) {
8658                final PackageParser.Package p = i.next();
8659                if (p.applicationInfo == null) continue;
8660
8661                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8662                        && !p.applicationInfo.isDirectBootAware();
8663                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8664                        && p.applicationInfo.isDirectBootAware();
8665
8666                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8667                        && (!mSafeMode || isSystemApp(p))
8668                        && (matchesUnaware || matchesAware)) {
8669                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8670                    if (ps != null) {
8671                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8672                                ps.readUserState(userId), userId);
8673                        if (ai != null) {
8674                            finalList.add(ai);
8675                        }
8676                    }
8677                }
8678            }
8679        }
8680
8681        return finalList;
8682    }
8683
8684    @Override
8685    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8686        if (!sUserManager.exists(userId)) return null;
8687        flags = updateFlagsForComponent(flags, userId, name);
8688        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8689        // reader
8690        synchronized (mPackages) {
8691            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8692            PackageSetting ps = provider != null
8693                    ? mSettings.mPackages.get(provider.owner.packageName)
8694                    : null;
8695            if (ps != null) {
8696                final boolean isInstantApp = ps.getInstantApp(userId);
8697                // normal application; filter out instant application provider
8698                if (instantAppPkgName == null && isInstantApp) {
8699                    return null;
8700                }
8701                // instant application; filter out other instant applications
8702                if (instantAppPkgName != null
8703                        && isInstantApp
8704                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8705                    return null;
8706                }
8707                // instant application; filter out non-exposed provider
8708                if (instantAppPkgName != null
8709                        && !isInstantApp
8710                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8711                    return null;
8712                }
8713                // provider not enabled
8714                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8715                    return null;
8716                }
8717                return PackageParser.generateProviderInfo(
8718                        provider, flags, ps.readUserState(userId), userId);
8719            }
8720            return null;
8721        }
8722    }
8723
8724    /**
8725     * @deprecated
8726     */
8727    @Deprecated
8728    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8729        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8730            return;
8731        }
8732        // reader
8733        synchronized (mPackages) {
8734            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8735                    .entrySet().iterator();
8736            final int userId = UserHandle.getCallingUserId();
8737            while (i.hasNext()) {
8738                Map.Entry<String, PackageParser.Provider> entry = i.next();
8739                PackageParser.Provider p = entry.getValue();
8740                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8741
8742                if (ps != null && p.syncable
8743                        && (!mSafeMode || (p.info.applicationInfo.flags
8744                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8745                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8746                            ps.readUserState(userId), userId);
8747                    if (info != null) {
8748                        outNames.add(entry.getKey());
8749                        outInfo.add(info);
8750                    }
8751                }
8752            }
8753        }
8754    }
8755
8756    @Override
8757    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8758            int uid, int flags, String metaDataKey) {
8759        final int callingUid = Binder.getCallingUid();
8760        final int userId = processName != null ? UserHandle.getUserId(uid)
8761                : UserHandle.getCallingUserId();
8762        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8763        flags = updateFlagsForComponent(flags, userId, processName);
8764        ArrayList<ProviderInfo> finalList = null;
8765        // reader
8766        synchronized (mPackages) {
8767            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8768            while (i.hasNext()) {
8769                final PackageParser.Provider p = i.next();
8770                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8771                if (ps != null && p.info.authority != null
8772                        && (processName == null
8773                                || (p.info.processName.equals(processName)
8774                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8775                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8776
8777                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8778                    // parameter.
8779                    if (metaDataKey != null
8780                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8781                        continue;
8782                    }
8783                    final ComponentName component =
8784                            new ComponentName(p.info.packageName, p.info.name);
8785                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8786                        continue;
8787                    }
8788                    if (finalList == null) {
8789                        finalList = new ArrayList<ProviderInfo>(3);
8790                    }
8791                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8792                            ps.readUserState(userId), userId);
8793                    if (info != null) {
8794                        finalList.add(info);
8795                    }
8796                }
8797            }
8798        }
8799
8800        if (finalList != null) {
8801            Collections.sort(finalList, mProviderInitOrderSorter);
8802            return new ParceledListSlice<ProviderInfo>(finalList);
8803        }
8804
8805        return ParceledListSlice.emptyList();
8806    }
8807
8808    @Override
8809    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8810        // reader
8811        synchronized (mPackages) {
8812            final int callingUid = Binder.getCallingUid();
8813            final int callingUserId = UserHandle.getUserId(callingUid);
8814            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8815            if (ps == null) return null;
8816            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8817                return null;
8818            }
8819            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8820            return PackageParser.generateInstrumentationInfo(i, flags);
8821        }
8822    }
8823
8824    @Override
8825    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8826            String targetPackage, int flags) {
8827        final int callingUid = Binder.getCallingUid();
8828        final int callingUserId = UserHandle.getUserId(callingUid);
8829        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8830        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8831            return ParceledListSlice.emptyList();
8832        }
8833        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8834    }
8835
8836    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8837            int flags) {
8838        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8839
8840        // reader
8841        synchronized (mPackages) {
8842            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8843            while (i.hasNext()) {
8844                final PackageParser.Instrumentation p = i.next();
8845                if (targetPackage == null
8846                        || targetPackage.equals(p.info.targetPackage)) {
8847                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8848                            flags);
8849                    if (ii != null) {
8850                        finalList.add(ii);
8851                    }
8852                }
8853            }
8854        }
8855
8856        return finalList;
8857    }
8858
8859    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8860        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8861        try {
8862            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8863        } finally {
8864            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8865        }
8866    }
8867
8868    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8869        final File[] files = dir.listFiles();
8870        if (ArrayUtils.isEmpty(files)) {
8871            Log.d(TAG, "No files in app dir " + dir);
8872            return;
8873        }
8874
8875        if (DEBUG_PACKAGE_SCANNING) {
8876            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8877                    + " flags=0x" + Integer.toHexString(parseFlags));
8878        }
8879        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8880                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8881                mParallelPackageParserCallback);
8882
8883        // Submit files for parsing in parallel
8884        int fileCount = 0;
8885        for (File file : files) {
8886            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8887                    && !PackageInstallerService.isStageName(file.getName());
8888            if (!isPackage) {
8889                // Ignore entries which are not packages
8890                continue;
8891            }
8892            parallelPackageParser.submit(file, parseFlags);
8893            fileCount++;
8894        }
8895
8896        // Process results one by one
8897        for (; fileCount > 0; fileCount--) {
8898            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8899            Throwable throwable = parseResult.throwable;
8900            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8901
8902            if (throwable == null) {
8903                // Static shared libraries have synthetic package names
8904                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8905                    renameStaticSharedLibraryPackage(parseResult.pkg);
8906                }
8907                try {
8908                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8909                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8910                                currentTime, null);
8911                    }
8912                } catch (PackageManagerException e) {
8913                    errorCode = e.error;
8914                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8915                }
8916            } else if (throwable instanceof PackageParser.PackageParserException) {
8917                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8918                        throwable;
8919                errorCode = e.error;
8920                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8921            } else {
8922                throw new IllegalStateException("Unexpected exception occurred while parsing "
8923                        + parseResult.scanFile, throwable);
8924            }
8925
8926            // Delete invalid userdata apps
8927            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8928                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8929                logCriticalInfo(Log.WARN,
8930                        "Deleting invalid package at " + parseResult.scanFile);
8931                removeCodePathLI(parseResult.scanFile);
8932            }
8933        }
8934        parallelPackageParser.close();
8935    }
8936
8937    private static File getSettingsProblemFile() {
8938        File dataDir = Environment.getDataDirectory();
8939        File systemDir = new File(dataDir, "system");
8940        File fname = new File(systemDir, "uiderrors.txt");
8941        return fname;
8942    }
8943
8944    static void reportSettingsProblem(int priority, String msg) {
8945        logCriticalInfo(priority, msg);
8946    }
8947
8948    public static void logCriticalInfo(int priority, String msg) {
8949        Slog.println(priority, TAG, msg);
8950        EventLogTags.writePmCriticalInfo(msg);
8951        try {
8952            File fname = getSettingsProblemFile();
8953            FileOutputStream out = new FileOutputStream(fname, true);
8954            PrintWriter pw = new FastPrintWriter(out);
8955            SimpleDateFormat formatter = new SimpleDateFormat();
8956            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8957            pw.println(dateString + ": " + msg);
8958            pw.close();
8959            FileUtils.setPermissions(
8960                    fname.toString(),
8961                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8962                    -1, -1);
8963        } catch (java.io.IOException e) {
8964        }
8965    }
8966
8967    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8968        if (srcFile.isDirectory()) {
8969            final File baseFile = new File(pkg.baseCodePath);
8970            long maxModifiedTime = baseFile.lastModified();
8971            if (pkg.splitCodePaths != null) {
8972                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8973                    final File splitFile = new File(pkg.splitCodePaths[i]);
8974                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8975                }
8976            }
8977            return maxModifiedTime;
8978        }
8979        return srcFile.lastModified();
8980    }
8981
8982    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8983            final int policyFlags) throws PackageManagerException {
8984        // When upgrading from pre-N MR1, verify the package time stamp using the package
8985        // directory and not the APK file.
8986        final long lastModifiedTime = mIsPreNMR1Upgrade
8987                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8988        if (ps != null
8989                && ps.codePath.equals(srcFile)
8990                && ps.timeStamp == lastModifiedTime
8991                && !isCompatSignatureUpdateNeeded(pkg)
8992                && !isRecoverSignatureUpdateNeeded(pkg)) {
8993            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8994            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8995            ArraySet<PublicKey> signingKs;
8996            synchronized (mPackages) {
8997                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8998            }
8999            if (ps.signatures.mSignatures != null
9000                    && ps.signatures.mSignatures.length != 0
9001                    && signingKs != null) {
9002                // Optimization: reuse the existing cached certificates
9003                // if the package appears to be unchanged.
9004                pkg.mSignatures = ps.signatures.mSignatures;
9005                pkg.mSigningKeys = signingKs;
9006                return;
9007            }
9008
9009            Slog.w(TAG, "PackageSetting for " + ps.name
9010                    + " is missing signatures.  Collecting certs again to recover them.");
9011        } else {
9012            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9013        }
9014
9015        try {
9016            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9017            PackageParser.collectCertificates(pkg, policyFlags);
9018        } catch (PackageParserException e) {
9019            throw PackageManagerException.from(e);
9020        } finally {
9021            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9022        }
9023    }
9024
9025    /**
9026     *  Traces a package scan.
9027     *  @see #scanPackageLI(File, int, int, long, UserHandle)
9028     */
9029    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9030            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9031        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9032        try {
9033            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9034        } finally {
9035            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9036        }
9037    }
9038
9039    /**
9040     *  Scans a package and returns the newly parsed package.
9041     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9042     */
9043    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9044            long currentTime, UserHandle user) throws PackageManagerException {
9045        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9046        PackageParser pp = new PackageParser();
9047        pp.setSeparateProcesses(mSeparateProcesses);
9048        pp.setOnlyCoreApps(mOnlyCore);
9049        pp.setDisplayMetrics(mMetrics);
9050        pp.setCallback(mPackageParserCallback);
9051
9052        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9053            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9054        }
9055
9056        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9057        final PackageParser.Package pkg;
9058        try {
9059            pkg = pp.parsePackage(scanFile, parseFlags);
9060        } catch (PackageParserException e) {
9061            throw PackageManagerException.from(e);
9062        } finally {
9063            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9064        }
9065
9066        // Static shared libraries have synthetic package names
9067        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9068            renameStaticSharedLibraryPackage(pkg);
9069        }
9070
9071        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9072    }
9073
9074    /**
9075     *  Scans a package and returns the newly parsed package.
9076     *  @throws PackageManagerException on a parse error.
9077     */
9078    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9079            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9080            throws PackageManagerException {
9081        // If the package has children and this is the first dive in the function
9082        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9083        // packages (parent and children) would be successfully scanned before the
9084        // actual scan since scanning mutates internal state and we want to atomically
9085        // install the package and its children.
9086        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9087            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9088                scanFlags |= SCAN_CHECK_ONLY;
9089            }
9090        } else {
9091            scanFlags &= ~SCAN_CHECK_ONLY;
9092        }
9093
9094        // Scan the parent
9095        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9096                scanFlags, currentTime, user);
9097
9098        // Scan the children
9099        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9100        for (int i = 0; i < childCount; i++) {
9101            PackageParser.Package childPackage = pkg.childPackages.get(i);
9102            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9103                    currentTime, user);
9104        }
9105
9106
9107        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9108            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9109        }
9110
9111        return scannedPkg;
9112    }
9113
9114    /**
9115     *  Scans a package and returns the newly parsed package.
9116     *  @throws PackageManagerException on a parse error.
9117     */
9118    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9119            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9120            throws PackageManagerException {
9121        PackageSetting ps = null;
9122        PackageSetting updatedPkg;
9123        // reader
9124        synchronized (mPackages) {
9125            // Look to see if we already know about this package.
9126            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9127            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9128                // This package has been renamed to its original name.  Let's
9129                // use that.
9130                ps = mSettings.getPackageLPr(oldName);
9131            }
9132            // If there was no original package, see one for the real package name.
9133            if (ps == null) {
9134                ps = mSettings.getPackageLPr(pkg.packageName);
9135            }
9136            // Check to see if this package could be hiding/updating a system
9137            // package.  Must look for it either under the original or real
9138            // package name depending on our state.
9139            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9140            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9141
9142            // If this is a package we don't know about on the system partition, we
9143            // may need to remove disabled child packages on the system partition
9144            // or may need to not add child packages if the parent apk is updated
9145            // on the data partition and no longer defines this child package.
9146            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9147                // If this is a parent package for an updated system app and this system
9148                // app got an OTA update which no longer defines some of the child packages
9149                // we have to prune them from the disabled system packages.
9150                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9151                if (disabledPs != null) {
9152                    final int scannedChildCount = (pkg.childPackages != null)
9153                            ? pkg.childPackages.size() : 0;
9154                    final int disabledChildCount = disabledPs.childPackageNames != null
9155                            ? disabledPs.childPackageNames.size() : 0;
9156                    for (int i = 0; i < disabledChildCount; i++) {
9157                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9158                        boolean disabledPackageAvailable = false;
9159                        for (int j = 0; j < scannedChildCount; j++) {
9160                            PackageParser.Package childPkg = pkg.childPackages.get(j);
9161                            if (childPkg.packageName.equals(disabledChildPackageName)) {
9162                                disabledPackageAvailable = true;
9163                                break;
9164                            }
9165                         }
9166                         if (!disabledPackageAvailable) {
9167                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9168                         }
9169                    }
9170                }
9171            }
9172        }
9173
9174        final boolean isUpdatedPkg = updatedPkg != null;
9175        final boolean isUpdatedSystemPkg = isUpdatedPkg
9176                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9177        boolean isUpdatedPkgBetter = false;
9178        // First check if this is a system package that may involve an update
9179        if (isUpdatedSystemPkg) {
9180            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9181            // it needs to drop FLAG_PRIVILEGED.
9182            if (locationIsPrivileged(scanFile)) {
9183                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9184            } else {
9185                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9186            }
9187
9188            if (ps != null && !ps.codePath.equals(scanFile)) {
9189                // The path has changed from what was last scanned...  check the
9190                // version of the new path against what we have stored to determine
9191                // what to do.
9192                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9193                if (pkg.mVersionCode <= ps.versionCode) {
9194                    // The system package has been updated and the code path does not match
9195                    // Ignore entry. Skip it.
9196                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9197                            + " ignored: updated version " + ps.versionCode
9198                            + " better than this " + pkg.mVersionCode);
9199                    if (!updatedPkg.codePath.equals(scanFile)) {
9200                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9201                                + ps.name + " changing from " + updatedPkg.codePathString
9202                                + " to " + scanFile);
9203                        updatedPkg.codePath = scanFile;
9204                        updatedPkg.codePathString = scanFile.toString();
9205                        updatedPkg.resourcePath = scanFile;
9206                        updatedPkg.resourcePathString = scanFile.toString();
9207                    }
9208                    updatedPkg.pkg = pkg;
9209                    updatedPkg.versionCode = pkg.mVersionCode;
9210
9211                    // Update the disabled system child packages to point to the package too.
9212                    final int childCount = updatedPkg.childPackageNames != null
9213                            ? updatedPkg.childPackageNames.size() : 0;
9214                    for (int i = 0; i < childCount; i++) {
9215                        String childPackageName = updatedPkg.childPackageNames.get(i);
9216                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9217                                childPackageName);
9218                        if (updatedChildPkg != null) {
9219                            updatedChildPkg.pkg = pkg;
9220                            updatedChildPkg.versionCode = pkg.mVersionCode;
9221                        }
9222                    }
9223                } else {
9224                    // The current app on the system partition is better than
9225                    // what we have updated to on the data partition; switch
9226                    // back to the system partition version.
9227                    // At this point, its safely assumed that package installation for
9228                    // apps in system partition will go through. If not there won't be a working
9229                    // version of the app
9230                    // writer
9231                    synchronized (mPackages) {
9232                        // Just remove the loaded entries from package lists.
9233                        mPackages.remove(ps.name);
9234                    }
9235
9236                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9237                            + " reverting from " + ps.codePathString
9238                            + ": new version " + pkg.mVersionCode
9239                            + " better than installed " + ps.versionCode);
9240
9241                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9242                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9243                    synchronized (mInstallLock) {
9244                        args.cleanUpResourcesLI();
9245                    }
9246                    synchronized (mPackages) {
9247                        mSettings.enableSystemPackageLPw(ps.name);
9248                    }
9249                    isUpdatedPkgBetter = true;
9250                }
9251            }
9252        }
9253
9254        String resourcePath = null;
9255        String baseResourcePath = null;
9256        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9257            if (ps != null && ps.resourcePathString != null) {
9258                resourcePath = ps.resourcePathString;
9259                baseResourcePath = ps.resourcePathString;
9260            } else {
9261                // Should not happen at all. Just log an error.
9262                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9263            }
9264        } else {
9265            resourcePath = pkg.codePath;
9266            baseResourcePath = pkg.baseCodePath;
9267        }
9268
9269        // Set application objects path explicitly.
9270        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9271        pkg.setApplicationInfoCodePath(pkg.codePath);
9272        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9273        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9274        pkg.setApplicationInfoResourcePath(resourcePath);
9275        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9276        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9277
9278        // throw an exception if we have an update to a system application, but, it's not more
9279        // recent than the package we've already scanned
9280        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9281            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9282                    + scanFile + " ignored: updated version " + ps.versionCode
9283                    + " better than this " + pkg.mVersionCode);
9284        }
9285
9286        if (isUpdatedPkg) {
9287            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9288            // initially
9289            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9290
9291            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9292            // flag set initially
9293            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9294                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9295            }
9296        }
9297
9298        // Verify certificates against what was last scanned
9299        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9300
9301        /*
9302         * A new system app appeared, but we already had a non-system one of the
9303         * same name installed earlier.
9304         */
9305        boolean shouldHideSystemApp = false;
9306        if (!isUpdatedPkg && ps != null
9307                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9308            /*
9309             * Check to make sure the signatures match first. If they don't,
9310             * wipe the installed application and its data.
9311             */
9312            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9313                    != PackageManager.SIGNATURE_MATCH) {
9314                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9315                        + " signatures don't match existing userdata copy; removing");
9316                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9317                        "scanPackageInternalLI")) {
9318                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9319                }
9320                ps = null;
9321            } else {
9322                /*
9323                 * If the newly-added system app is an older version than the
9324                 * already installed version, hide it. It will be scanned later
9325                 * and re-added like an update.
9326                 */
9327                if (pkg.mVersionCode <= ps.versionCode) {
9328                    shouldHideSystemApp = true;
9329                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9330                            + " but new version " + pkg.mVersionCode + " better than installed "
9331                            + ps.versionCode + "; hiding system");
9332                } else {
9333                    /*
9334                     * The newly found system app is a newer version that the
9335                     * one previously installed. Simply remove the
9336                     * already-installed application and replace it with our own
9337                     * while keeping the application data.
9338                     */
9339                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9340                            + " reverting from " + ps.codePathString + ": new version "
9341                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9342                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9343                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9344                    synchronized (mInstallLock) {
9345                        args.cleanUpResourcesLI();
9346                    }
9347                }
9348            }
9349        }
9350
9351        // The apk is forward locked (not public) if its code and resources
9352        // are kept in different files. (except for app in either system or
9353        // vendor path).
9354        // TODO grab this value from PackageSettings
9355        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9356            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9357                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9358            }
9359        }
9360
9361        final int userId = ((user == null) ? 0 : user.getIdentifier());
9362        if (ps != null && ps.getInstantApp(userId)) {
9363            scanFlags |= SCAN_AS_INSTANT_APP;
9364        }
9365
9366        // Note that we invoke the following method only if we are about to unpack an application
9367        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9368                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9369
9370        /*
9371         * If the system app should be overridden by a previously installed
9372         * data, hide the system app now and let the /data/app scan pick it up
9373         * again.
9374         */
9375        if (shouldHideSystemApp) {
9376            synchronized (mPackages) {
9377                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9378            }
9379        }
9380
9381        return scannedPkg;
9382    }
9383
9384    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9385        // Derive the new package synthetic package name
9386        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9387                + pkg.staticSharedLibVersion);
9388    }
9389
9390    private static String fixProcessName(String defProcessName,
9391            String processName) {
9392        if (processName == null) {
9393            return defProcessName;
9394        }
9395        return processName;
9396    }
9397
9398    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9399            throws PackageManagerException {
9400        if (pkgSetting.signatures.mSignatures != null) {
9401            // Already existing package. Make sure signatures match
9402            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9403                    == PackageManager.SIGNATURE_MATCH;
9404            if (!match) {
9405                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9406                        == PackageManager.SIGNATURE_MATCH;
9407            }
9408            if (!match) {
9409                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9410                        == PackageManager.SIGNATURE_MATCH;
9411            }
9412            if (!match) {
9413                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9414                        + pkg.packageName + " signatures do not match the "
9415                        + "previously installed version; ignoring!");
9416            }
9417        }
9418
9419        // Check for shared user signatures
9420        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9421            // Already existing package. Make sure signatures match
9422            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9423                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9424            if (!match) {
9425                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9426                        == PackageManager.SIGNATURE_MATCH;
9427            }
9428            if (!match) {
9429                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9430                        == PackageManager.SIGNATURE_MATCH;
9431            }
9432            if (!match) {
9433                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9434                        "Package " + pkg.packageName
9435                        + " has no signatures that match those in shared user "
9436                        + pkgSetting.sharedUser.name + "; ignoring!");
9437            }
9438        }
9439    }
9440
9441    /**
9442     * Enforces that only the system UID or root's UID can call a method exposed
9443     * via Binder.
9444     *
9445     * @param message used as message if SecurityException is thrown
9446     * @throws SecurityException if the caller is not system or root
9447     */
9448    private static final void enforceSystemOrRoot(String message) {
9449        final int uid = Binder.getCallingUid();
9450        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9451            throw new SecurityException(message);
9452        }
9453    }
9454
9455    @Override
9456    public void performFstrimIfNeeded() {
9457        enforceSystemOrRoot("Only the system can request fstrim");
9458
9459        // Before everything else, see whether we need to fstrim.
9460        try {
9461            IStorageManager sm = PackageHelper.getStorageManager();
9462            if (sm != null) {
9463                boolean doTrim = false;
9464                final long interval = android.provider.Settings.Global.getLong(
9465                        mContext.getContentResolver(),
9466                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9467                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9468                if (interval > 0) {
9469                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9470                    if (timeSinceLast > interval) {
9471                        doTrim = true;
9472                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9473                                + "; running immediately");
9474                    }
9475                }
9476                if (doTrim) {
9477                    final boolean dexOptDialogShown;
9478                    synchronized (mPackages) {
9479                        dexOptDialogShown = mDexOptDialogShown;
9480                    }
9481                    if (!isFirstBoot() && dexOptDialogShown) {
9482                        try {
9483                            ActivityManager.getService().showBootMessage(
9484                                    mContext.getResources().getString(
9485                                            R.string.android_upgrading_fstrim), true);
9486                        } catch (RemoteException e) {
9487                        }
9488                    }
9489                    sm.runMaintenance();
9490                }
9491            } else {
9492                Slog.e(TAG, "storageManager service unavailable!");
9493            }
9494        } catch (RemoteException e) {
9495            // Can't happen; StorageManagerService is local
9496        }
9497    }
9498
9499    @Override
9500    public void updatePackagesIfNeeded() {
9501        enforceSystemOrRoot("Only the system can request package update");
9502
9503        // We need to re-extract after an OTA.
9504        boolean causeUpgrade = isUpgrade();
9505
9506        // First boot or factory reset.
9507        // Note: we also handle devices that are upgrading to N right now as if it is their
9508        //       first boot, as they do not have profile data.
9509        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9510
9511        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9512        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9513
9514        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9515            return;
9516        }
9517
9518        List<PackageParser.Package> pkgs;
9519        synchronized (mPackages) {
9520            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9521        }
9522
9523        final long startTime = System.nanoTime();
9524        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9525                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9526                    false /* bootComplete */);
9527
9528        final int elapsedTimeSeconds =
9529                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9530
9531        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9532        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9533        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9534        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9535        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9536    }
9537
9538    /*
9539     * Return the prebuilt profile path given a package base code path.
9540     */
9541    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9542        return pkg.baseCodePath + ".prof";
9543    }
9544
9545    /**
9546     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9547     * containing statistics about the invocation. The array consists of three elements,
9548     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9549     * and {@code numberOfPackagesFailed}.
9550     */
9551    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9552            String compilerFilter, boolean bootComplete) {
9553
9554        int numberOfPackagesVisited = 0;
9555        int numberOfPackagesOptimized = 0;
9556        int numberOfPackagesSkipped = 0;
9557        int numberOfPackagesFailed = 0;
9558        final int numberOfPackagesToDexopt = pkgs.size();
9559
9560        for (PackageParser.Package pkg : pkgs) {
9561            numberOfPackagesVisited++;
9562
9563            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9564                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9565                // that are already compiled.
9566                File profileFile = new File(getPrebuildProfilePath(pkg));
9567                // Copy profile if it exists.
9568                if (profileFile.exists()) {
9569                    try {
9570                        // We could also do this lazily before calling dexopt in
9571                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9572                        // is that we don't have a good way to say "do this only once".
9573                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9574                                pkg.applicationInfo.uid, pkg.packageName)) {
9575                            Log.e(TAG, "Installer failed to copy system profile!");
9576                        }
9577                    } catch (Exception e) {
9578                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9579                                e);
9580                    }
9581                }
9582            }
9583
9584            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9585                if (DEBUG_DEXOPT) {
9586                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9587                }
9588                numberOfPackagesSkipped++;
9589                continue;
9590            }
9591
9592            if (DEBUG_DEXOPT) {
9593                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9594                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9595            }
9596
9597            if (showDialog) {
9598                try {
9599                    ActivityManager.getService().showBootMessage(
9600                            mContext.getResources().getString(R.string.android_upgrading_apk,
9601                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9602                } catch (RemoteException e) {
9603                }
9604                synchronized (mPackages) {
9605                    mDexOptDialogShown = true;
9606                }
9607            }
9608
9609            // If the OTA updates a system app which was previously preopted to a non-preopted state
9610            // the app might end up being verified at runtime. That's because by default the apps
9611            // are verify-profile but for preopted apps there's no profile.
9612            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
9613            // that before the OTA the app was preopted) the app gets compiled with a non-profile
9614            // filter (by default 'quicken').
9615            // Note that at this stage unused apps are already filtered.
9616            if (isSystemApp(pkg) &&
9617                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
9618                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
9619                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
9620            }
9621
9622            // checkProfiles is false to avoid merging profiles during boot which
9623            // might interfere with background compilation (b/28612421).
9624            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9625            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9626            // trade-off worth doing to save boot time work.
9627            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9628            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9629                    pkg.packageName,
9630                    compilerFilter,
9631                    dexoptFlags));
9632
9633            if (pkg.isSystemApp()) {
9634                // Only dexopt shared secondary dex files belonging to system apps to not slow down
9635                // too much boot after an OTA.
9636                int secondaryDexoptFlags = dexoptFlags |
9637                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9638                        DexoptOptions.DEXOPT_ONLY_SHARED_DEX;
9639                mDexManager.dexoptSecondaryDex(new DexoptOptions(
9640                        pkg.packageName,
9641                        compilerFilter,
9642                        secondaryDexoptFlags));
9643            }
9644
9645            // TODO(shubhamajmera): Record secondary dexopt stats.
9646            switch (primaryDexOptStaus) {
9647                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9648                    numberOfPackagesOptimized++;
9649                    break;
9650                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9651                    numberOfPackagesSkipped++;
9652                    break;
9653                case PackageDexOptimizer.DEX_OPT_FAILED:
9654                    numberOfPackagesFailed++;
9655                    break;
9656                default:
9657                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9658                    break;
9659            }
9660        }
9661
9662        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9663                numberOfPackagesFailed };
9664    }
9665
9666    @Override
9667    public void notifyPackageUse(String packageName, int reason) {
9668        synchronized (mPackages) {
9669            final int callingUid = Binder.getCallingUid();
9670            final int callingUserId = UserHandle.getUserId(callingUid);
9671            if (getInstantAppPackageName(callingUid) != null) {
9672                if (!isCallerSameApp(packageName, callingUid)) {
9673                    return;
9674                }
9675            } else {
9676                if (isInstantApp(packageName, callingUserId)) {
9677                    return;
9678                }
9679            }
9680            final PackageParser.Package p = mPackages.get(packageName);
9681            if (p == null) {
9682                return;
9683            }
9684            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9685        }
9686    }
9687
9688    @Override
9689    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9690            List<String> classPaths, String loaderIsa) {
9691        int userId = UserHandle.getCallingUserId();
9692        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9693        if (ai == null) {
9694            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9695                + loadingPackageName + ", user=" + userId);
9696            return;
9697        }
9698        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9699    }
9700
9701    @Override
9702    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9703            IDexModuleRegisterCallback callback) {
9704        int userId = UserHandle.getCallingUserId();
9705        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9706        DexManager.RegisterDexModuleResult result;
9707        if (ai == null) {
9708            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9709                     " calling user. package=" + packageName + ", user=" + userId);
9710            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9711        } else {
9712            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9713        }
9714
9715        if (callback != null) {
9716            mHandler.post(() -> {
9717                try {
9718                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9719                } catch (RemoteException e) {
9720                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9721                }
9722            });
9723        }
9724    }
9725
9726    /**
9727     * Ask the package manager to perform a dex-opt with the given compiler filter.
9728     *
9729     * Note: exposed only for the shell command to allow moving packages explicitly to a
9730     *       definite state.
9731     */
9732    @Override
9733    public boolean performDexOptMode(String packageName,
9734            boolean checkProfiles, String targetCompilerFilter, boolean force,
9735            boolean bootComplete, String splitName) {
9736        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9737                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9738                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9739        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
9740                splitName, flags));
9741    }
9742
9743    /**
9744     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9745     * secondary dex files belonging to the given package.
9746     *
9747     * Note: exposed only for the shell command to allow moving packages explicitly to a
9748     *       definite state.
9749     */
9750    @Override
9751    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9752            boolean force) {
9753        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9754                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9755                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9756                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9757        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9758    }
9759
9760    /*package*/ boolean performDexOpt(DexoptOptions options) {
9761        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9762            return false;
9763        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9764            return false;
9765        }
9766
9767        if (options.isDexoptOnlySecondaryDex()) {
9768            return mDexManager.dexoptSecondaryDex(options);
9769        } else {
9770            int dexoptStatus = performDexOptWithStatus(options);
9771            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9772        }
9773    }
9774
9775    /**
9776     * Perform dexopt on the given package and return one of following result:
9777     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9778     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9779     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9780     */
9781    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9782        return performDexOptTraced(options);
9783    }
9784
9785    private int performDexOptTraced(DexoptOptions options) {
9786        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9787        try {
9788            return performDexOptInternal(options);
9789        } finally {
9790            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9791        }
9792    }
9793
9794    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9795    // if the package can now be considered up to date for the given filter.
9796    private int performDexOptInternal(DexoptOptions options) {
9797        PackageParser.Package p;
9798        synchronized (mPackages) {
9799            p = mPackages.get(options.getPackageName());
9800            if (p == null) {
9801                // Package could not be found. Report failure.
9802                return PackageDexOptimizer.DEX_OPT_FAILED;
9803            }
9804            mPackageUsage.maybeWriteAsync(mPackages);
9805            mCompilerStats.maybeWriteAsync();
9806        }
9807        long callingId = Binder.clearCallingIdentity();
9808        try {
9809            synchronized (mInstallLock) {
9810                return performDexOptInternalWithDependenciesLI(p, options);
9811            }
9812        } finally {
9813            Binder.restoreCallingIdentity(callingId);
9814        }
9815    }
9816
9817    public ArraySet<String> getOptimizablePackages() {
9818        ArraySet<String> pkgs = new ArraySet<String>();
9819        synchronized (mPackages) {
9820            for (PackageParser.Package p : mPackages.values()) {
9821                if (PackageDexOptimizer.canOptimizePackage(p)) {
9822                    pkgs.add(p.packageName);
9823                }
9824            }
9825        }
9826        return pkgs;
9827    }
9828
9829    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9830            DexoptOptions options) {
9831        // Select the dex optimizer based on the force parameter.
9832        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9833        //       allocate an object here.
9834        PackageDexOptimizer pdo = options.isForce()
9835                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9836                : mPackageDexOptimizer;
9837
9838        // Dexopt all dependencies first. Note: we ignore the return value and march on
9839        // on errors.
9840        // Note that we are going to call performDexOpt on those libraries as many times as
9841        // they are referenced in packages. When we do a batch of performDexOpt (for example
9842        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9843        // and the first package that uses the library will dexopt it. The
9844        // others will see that the compiled code for the library is up to date.
9845        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9846        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9847        if (!deps.isEmpty()) {
9848            for (PackageParser.Package depPackage : deps) {
9849                // TODO: Analyze and investigate if we (should) profile libraries.
9850                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9851                        getOrCreateCompilerPackageStats(depPackage),
9852                        true /* isUsedByOtherApps */,
9853                        options);
9854            }
9855        }
9856        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9857                getOrCreateCompilerPackageStats(p),
9858                mDexManager.isUsedByOtherApps(p.packageName), options);
9859    }
9860
9861    /**
9862     * Reconcile the information we have about the secondary dex files belonging to
9863     * {@code packagName} and the actual dex files. For all dex files that were
9864     * deleted, update the internal records and delete the generated oat files.
9865     */
9866    @Override
9867    public void reconcileSecondaryDexFiles(String packageName) {
9868        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9869            return;
9870        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9871            return;
9872        }
9873        mDexManager.reconcileSecondaryDexFiles(packageName);
9874    }
9875
9876    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9877    // a reference there.
9878    /*package*/ DexManager getDexManager() {
9879        return mDexManager;
9880    }
9881
9882    /**
9883     * Execute the background dexopt job immediately.
9884     */
9885    @Override
9886    public boolean runBackgroundDexoptJob() {
9887        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9888            return false;
9889        }
9890        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9891    }
9892
9893    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9894        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9895                || p.usesStaticLibraries != null) {
9896            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9897            Set<String> collectedNames = new HashSet<>();
9898            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9899
9900            retValue.remove(p);
9901
9902            return retValue;
9903        } else {
9904            return Collections.emptyList();
9905        }
9906    }
9907
9908    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9909            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9910        if (!collectedNames.contains(p.packageName)) {
9911            collectedNames.add(p.packageName);
9912            collected.add(p);
9913
9914            if (p.usesLibraries != null) {
9915                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9916                        null, collected, collectedNames);
9917            }
9918            if (p.usesOptionalLibraries != null) {
9919                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9920                        null, collected, collectedNames);
9921            }
9922            if (p.usesStaticLibraries != null) {
9923                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9924                        p.usesStaticLibrariesVersions, collected, collectedNames);
9925            }
9926        }
9927    }
9928
9929    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9930            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9931        final int libNameCount = libs.size();
9932        for (int i = 0; i < libNameCount; i++) {
9933            String libName = libs.get(i);
9934            int version = (versions != null && versions.length == libNameCount)
9935                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9936            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9937            if (libPkg != null) {
9938                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9939            }
9940        }
9941    }
9942
9943    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9944        synchronized (mPackages) {
9945            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9946            if (libEntry != null) {
9947                return mPackages.get(libEntry.apk);
9948            }
9949            return null;
9950        }
9951    }
9952
9953    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9954        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9955        if (versionedLib == null) {
9956            return null;
9957        }
9958        return versionedLib.get(version);
9959    }
9960
9961    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9962        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9963                pkg.staticSharedLibName);
9964        if (versionedLib == null) {
9965            return null;
9966        }
9967        int previousLibVersion = -1;
9968        final int versionCount = versionedLib.size();
9969        for (int i = 0; i < versionCount; i++) {
9970            final int libVersion = versionedLib.keyAt(i);
9971            if (libVersion < pkg.staticSharedLibVersion) {
9972                previousLibVersion = Math.max(previousLibVersion, libVersion);
9973            }
9974        }
9975        if (previousLibVersion >= 0) {
9976            return versionedLib.get(previousLibVersion);
9977        }
9978        return null;
9979    }
9980
9981    public void shutdown() {
9982        mPackageUsage.writeNow(mPackages);
9983        mCompilerStats.writeNow();
9984    }
9985
9986    @Override
9987    public void dumpProfiles(String packageName) {
9988        PackageParser.Package pkg;
9989        synchronized (mPackages) {
9990            pkg = mPackages.get(packageName);
9991            if (pkg == null) {
9992                throw new IllegalArgumentException("Unknown package: " + packageName);
9993            }
9994        }
9995        /* Only the shell, root, or the app user should be able to dump profiles. */
9996        int callingUid = Binder.getCallingUid();
9997        if (callingUid != Process.SHELL_UID &&
9998            callingUid != Process.ROOT_UID &&
9999            callingUid != pkg.applicationInfo.uid) {
10000            throw new SecurityException("dumpProfiles");
10001        }
10002
10003        synchronized (mInstallLock) {
10004            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10005            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10006            try {
10007                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10008                String codePaths = TextUtils.join(";", allCodePaths);
10009                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10010            } catch (InstallerException e) {
10011                Slog.w(TAG, "Failed to dump profiles", e);
10012            }
10013            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10014        }
10015    }
10016
10017    @Override
10018    public void forceDexOpt(String packageName) {
10019        enforceSystemOrRoot("forceDexOpt");
10020
10021        PackageParser.Package pkg;
10022        synchronized (mPackages) {
10023            pkg = mPackages.get(packageName);
10024            if (pkg == null) {
10025                throw new IllegalArgumentException("Unknown package: " + packageName);
10026            }
10027        }
10028
10029        synchronized (mInstallLock) {
10030            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10031
10032            // Whoever is calling forceDexOpt wants a compiled package.
10033            // Don't use profiles since that may cause compilation to be skipped.
10034            final int res = performDexOptInternalWithDependenciesLI(
10035                    pkg,
10036                    new DexoptOptions(packageName,
10037                            getDefaultCompilerFilter(),
10038                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10039
10040            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10041            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10042                throw new IllegalStateException("Failed to dexopt: " + res);
10043            }
10044        }
10045    }
10046
10047    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10048        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10049            Slog.w(TAG, "Unable to update from " + oldPkg.name
10050                    + " to " + newPkg.packageName
10051                    + ": old package not in system partition");
10052            return false;
10053        } else if (mPackages.get(oldPkg.name) != null) {
10054            Slog.w(TAG, "Unable to update from " + oldPkg.name
10055                    + " to " + newPkg.packageName
10056                    + ": old package still exists");
10057            return false;
10058        }
10059        return true;
10060    }
10061
10062    void removeCodePathLI(File codePath) {
10063        if (codePath.isDirectory()) {
10064            try {
10065                mInstaller.rmPackageDir(codePath.getAbsolutePath());
10066            } catch (InstallerException e) {
10067                Slog.w(TAG, "Failed to remove code path", e);
10068            }
10069        } else {
10070            codePath.delete();
10071        }
10072    }
10073
10074    private int[] resolveUserIds(int userId) {
10075        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10076    }
10077
10078    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10079        if (pkg == null) {
10080            Slog.wtf(TAG, "Package was null!", new Throwable());
10081            return;
10082        }
10083        clearAppDataLeafLIF(pkg, userId, flags);
10084        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10085        for (int i = 0; i < childCount; i++) {
10086            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10087        }
10088    }
10089
10090    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10091        final PackageSetting ps;
10092        synchronized (mPackages) {
10093            ps = mSettings.mPackages.get(pkg.packageName);
10094        }
10095        for (int realUserId : resolveUserIds(userId)) {
10096            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10097            try {
10098                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10099                        ceDataInode);
10100            } catch (InstallerException e) {
10101                Slog.w(TAG, String.valueOf(e));
10102            }
10103        }
10104    }
10105
10106    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10107        if (pkg == null) {
10108            Slog.wtf(TAG, "Package was null!", new Throwable());
10109            return;
10110        }
10111        destroyAppDataLeafLIF(pkg, userId, flags);
10112        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10113        for (int i = 0; i < childCount; i++) {
10114            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10115        }
10116    }
10117
10118    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10119        final PackageSetting ps;
10120        synchronized (mPackages) {
10121            ps = mSettings.mPackages.get(pkg.packageName);
10122        }
10123        for (int realUserId : resolveUserIds(userId)) {
10124            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10125            try {
10126                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10127                        ceDataInode);
10128            } catch (InstallerException e) {
10129                Slog.w(TAG, String.valueOf(e));
10130            }
10131            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10132        }
10133    }
10134
10135    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10136        if (pkg == null) {
10137            Slog.wtf(TAG, "Package was null!", new Throwable());
10138            return;
10139        }
10140        destroyAppProfilesLeafLIF(pkg);
10141        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10142        for (int i = 0; i < childCount; i++) {
10143            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10144        }
10145    }
10146
10147    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10148        try {
10149            mInstaller.destroyAppProfiles(pkg.packageName);
10150        } catch (InstallerException e) {
10151            Slog.w(TAG, String.valueOf(e));
10152        }
10153    }
10154
10155    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10156        if (pkg == null) {
10157            Slog.wtf(TAG, "Package was null!", new Throwable());
10158            return;
10159        }
10160        clearAppProfilesLeafLIF(pkg);
10161        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10162        for (int i = 0; i < childCount; i++) {
10163            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10164        }
10165    }
10166
10167    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10168        try {
10169            mInstaller.clearAppProfiles(pkg.packageName);
10170        } catch (InstallerException e) {
10171            Slog.w(TAG, String.valueOf(e));
10172        }
10173    }
10174
10175    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10176            long lastUpdateTime) {
10177        // Set parent install/update time
10178        PackageSetting ps = (PackageSetting) pkg.mExtras;
10179        if (ps != null) {
10180            ps.firstInstallTime = firstInstallTime;
10181            ps.lastUpdateTime = lastUpdateTime;
10182        }
10183        // Set children install/update time
10184        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10185        for (int i = 0; i < childCount; i++) {
10186            PackageParser.Package childPkg = pkg.childPackages.get(i);
10187            ps = (PackageSetting) childPkg.mExtras;
10188            if (ps != null) {
10189                ps.firstInstallTime = firstInstallTime;
10190                ps.lastUpdateTime = lastUpdateTime;
10191            }
10192        }
10193    }
10194
10195    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10196            PackageParser.Package changingLib) {
10197        if (file.path != null) {
10198            usesLibraryFiles.add(file.path);
10199            return;
10200        }
10201        PackageParser.Package p = mPackages.get(file.apk);
10202        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10203            // If we are doing this while in the middle of updating a library apk,
10204            // then we need to make sure to use that new apk for determining the
10205            // dependencies here.  (We haven't yet finished committing the new apk
10206            // to the package manager state.)
10207            if (p == null || p.packageName.equals(changingLib.packageName)) {
10208                p = changingLib;
10209            }
10210        }
10211        if (p != null) {
10212            usesLibraryFiles.addAll(p.getAllCodePaths());
10213            if (p.usesLibraryFiles != null) {
10214                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10215            }
10216        }
10217    }
10218
10219    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10220            PackageParser.Package changingLib) throws PackageManagerException {
10221        if (pkg == null) {
10222            return;
10223        }
10224        ArraySet<String> usesLibraryFiles = null;
10225        if (pkg.usesLibraries != null) {
10226            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10227                    null, null, pkg.packageName, changingLib, true, null);
10228        }
10229        if (pkg.usesStaticLibraries != null) {
10230            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10231                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10232                    pkg.packageName, changingLib, true, usesLibraryFiles);
10233        }
10234        if (pkg.usesOptionalLibraries != null) {
10235            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10236                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
10237        }
10238        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10239            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10240        } else {
10241            pkg.usesLibraryFiles = null;
10242        }
10243    }
10244
10245    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10246            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
10247            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10248            boolean required, @Nullable ArraySet<String> outUsedLibraries)
10249            throws PackageManagerException {
10250        final int libCount = requestedLibraries.size();
10251        for (int i = 0; i < libCount; i++) {
10252            final String libName = requestedLibraries.get(i);
10253            final int libVersion = requiredVersions != null ? requiredVersions[i]
10254                    : SharedLibraryInfo.VERSION_UNDEFINED;
10255            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10256            if (libEntry == null) {
10257                if (required) {
10258                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10259                            "Package " + packageName + " requires unavailable shared library "
10260                                    + libName + "; failing!");
10261                } else if (DEBUG_SHARED_LIBRARIES) {
10262                    Slog.i(TAG, "Package " + packageName
10263                            + " desires unavailable shared library "
10264                            + libName + "; ignoring!");
10265                }
10266            } else {
10267                if (requiredVersions != null && requiredCertDigests != null) {
10268                    if (libEntry.info.getVersion() != requiredVersions[i]) {
10269                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10270                            "Package " + packageName + " requires unavailable static shared"
10271                                    + " library " + libName + " version "
10272                                    + libEntry.info.getVersion() + "; failing!");
10273                    }
10274
10275                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10276                    if (libPkg == null) {
10277                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10278                                "Package " + packageName + " requires unavailable static shared"
10279                                        + " library; failing!");
10280                    }
10281
10282                    String expectedCertDigest = requiredCertDigests[i];
10283                    String libCertDigest = PackageUtils.computeCertSha256Digest(
10284                                libPkg.mSignatures[0]);
10285                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
10286                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10287                                "Package " + packageName + " requires differently signed" +
10288                                        " static shared library; failing!");
10289                    }
10290                }
10291
10292                if (outUsedLibraries == null) {
10293                    outUsedLibraries = new ArraySet<>();
10294                }
10295                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10296            }
10297        }
10298        return outUsedLibraries;
10299    }
10300
10301    private static boolean hasString(List<String> list, List<String> which) {
10302        if (list == null) {
10303            return false;
10304        }
10305        for (int i=list.size()-1; i>=0; i--) {
10306            for (int j=which.size()-1; j>=0; j--) {
10307                if (which.get(j).equals(list.get(i))) {
10308                    return true;
10309                }
10310            }
10311        }
10312        return false;
10313    }
10314
10315    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10316            PackageParser.Package changingPkg) {
10317        ArrayList<PackageParser.Package> res = null;
10318        for (PackageParser.Package pkg : mPackages.values()) {
10319            if (changingPkg != null
10320                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10321                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10322                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10323                            changingPkg.staticSharedLibName)) {
10324                return null;
10325            }
10326            if (res == null) {
10327                res = new ArrayList<>();
10328            }
10329            res.add(pkg);
10330            try {
10331                updateSharedLibrariesLPr(pkg, changingPkg);
10332            } catch (PackageManagerException e) {
10333                // If a system app update or an app and a required lib missing we
10334                // delete the package and for updated system apps keep the data as
10335                // it is better for the user to reinstall than to be in an limbo
10336                // state. Also libs disappearing under an app should never happen
10337                // - just in case.
10338                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10339                    final int flags = pkg.isUpdatedSystemApp()
10340                            ? PackageManager.DELETE_KEEP_DATA : 0;
10341                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10342                            flags , null, true, null);
10343                }
10344                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10345            }
10346        }
10347        return res;
10348    }
10349
10350    /**
10351     * Derive the value of the {@code cpuAbiOverride} based on the provided
10352     * value and an optional stored value from the package settings.
10353     */
10354    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10355        String cpuAbiOverride = null;
10356
10357        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10358            cpuAbiOverride = null;
10359        } else if (abiOverride != null) {
10360            cpuAbiOverride = abiOverride;
10361        } else if (settings != null) {
10362            cpuAbiOverride = settings.cpuAbiOverrideString;
10363        }
10364
10365        return cpuAbiOverride;
10366    }
10367
10368    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10369            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10370                    throws PackageManagerException {
10371        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10372        // If the package has children and this is the first dive in the function
10373        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10374        // whether all packages (parent and children) would be successfully scanned
10375        // before the actual scan since scanning mutates internal state and we want
10376        // to atomically install the package and its children.
10377        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10378            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10379                scanFlags |= SCAN_CHECK_ONLY;
10380            }
10381        } else {
10382            scanFlags &= ~SCAN_CHECK_ONLY;
10383        }
10384
10385        final PackageParser.Package scannedPkg;
10386        try {
10387            // Scan the parent
10388            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10389            // Scan the children
10390            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10391            for (int i = 0; i < childCount; i++) {
10392                PackageParser.Package childPkg = pkg.childPackages.get(i);
10393                scanPackageLI(childPkg, policyFlags,
10394                        scanFlags, currentTime, user);
10395            }
10396        } finally {
10397            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10398        }
10399
10400        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10401            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10402        }
10403
10404        return scannedPkg;
10405    }
10406
10407    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10408            int scanFlags, long currentTime, @Nullable UserHandle user)
10409                    throws PackageManagerException {
10410        boolean success = false;
10411        try {
10412            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10413                    currentTime, user);
10414            success = true;
10415            return res;
10416        } finally {
10417            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10418                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10419                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10420                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10421                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10422            }
10423        }
10424    }
10425
10426    /**
10427     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10428     */
10429    private static boolean apkHasCode(String fileName) {
10430        StrictJarFile jarFile = null;
10431        try {
10432            jarFile = new StrictJarFile(fileName,
10433                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10434            return jarFile.findEntry("classes.dex") != null;
10435        } catch (IOException ignore) {
10436        } finally {
10437            try {
10438                if (jarFile != null) {
10439                    jarFile.close();
10440                }
10441            } catch (IOException ignore) {}
10442        }
10443        return false;
10444    }
10445
10446    /**
10447     * Enforces code policy for the package. This ensures that if an APK has
10448     * declared hasCode="true" in its manifest that the APK actually contains
10449     * code.
10450     *
10451     * @throws PackageManagerException If bytecode could not be found when it should exist
10452     */
10453    private static void assertCodePolicy(PackageParser.Package pkg)
10454            throws PackageManagerException {
10455        final boolean shouldHaveCode =
10456                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10457        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10458            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10459                    "Package " + pkg.baseCodePath + " code is missing");
10460        }
10461
10462        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10463            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10464                final boolean splitShouldHaveCode =
10465                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10466                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10467                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10468                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10469                }
10470            }
10471        }
10472    }
10473
10474    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10475            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10476                    throws PackageManagerException {
10477        if (DEBUG_PACKAGE_SCANNING) {
10478            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10479                Log.d(TAG, "Scanning package " + pkg.packageName);
10480        }
10481
10482        applyPolicy(pkg, policyFlags);
10483
10484        assertPackageIsValid(pkg, policyFlags, scanFlags);
10485
10486        // Initialize package source and resource directories
10487        final File scanFile = new File(pkg.codePath);
10488        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10489        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10490
10491        SharedUserSetting suid = null;
10492        PackageSetting pkgSetting = null;
10493
10494        // Getting the package setting may have a side-effect, so if we
10495        // are only checking if scan would succeed, stash a copy of the
10496        // old setting to restore at the end.
10497        PackageSetting nonMutatedPs = null;
10498
10499        // We keep references to the derived CPU Abis from settings in oder to reuse
10500        // them in the case where we're not upgrading or booting for the first time.
10501        String primaryCpuAbiFromSettings = null;
10502        String secondaryCpuAbiFromSettings = null;
10503
10504        // writer
10505        synchronized (mPackages) {
10506            if (pkg.mSharedUserId != null) {
10507                // SIDE EFFECTS; may potentially allocate a new shared user
10508                suid = mSettings.getSharedUserLPw(
10509                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10510                if (DEBUG_PACKAGE_SCANNING) {
10511                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10512                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10513                                + "): packages=" + suid.packages);
10514                }
10515            }
10516
10517            // Check if we are renaming from an original package name.
10518            PackageSetting origPackage = null;
10519            String realName = null;
10520            if (pkg.mOriginalPackages != null) {
10521                // This package may need to be renamed to a previously
10522                // installed name.  Let's check on that...
10523                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10524                if (pkg.mOriginalPackages.contains(renamed)) {
10525                    // This package had originally been installed as the
10526                    // original name, and we have already taken care of
10527                    // transitioning to the new one.  Just update the new
10528                    // one to continue using the old name.
10529                    realName = pkg.mRealPackage;
10530                    if (!pkg.packageName.equals(renamed)) {
10531                        // Callers into this function may have already taken
10532                        // care of renaming the package; only do it here if
10533                        // it is not already done.
10534                        pkg.setPackageName(renamed);
10535                    }
10536                } else {
10537                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10538                        if ((origPackage = mSettings.getPackageLPr(
10539                                pkg.mOriginalPackages.get(i))) != null) {
10540                            // We do have the package already installed under its
10541                            // original name...  should we use it?
10542                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10543                                // New package is not compatible with original.
10544                                origPackage = null;
10545                                continue;
10546                            } else if (origPackage.sharedUser != null) {
10547                                // Make sure uid is compatible between packages.
10548                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10549                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10550                                            + " to " + pkg.packageName + ": old uid "
10551                                            + origPackage.sharedUser.name
10552                                            + " differs from " + pkg.mSharedUserId);
10553                                    origPackage = null;
10554                                    continue;
10555                                }
10556                                // TODO: Add case when shared user id is added [b/28144775]
10557                            } else {
10558                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10559                                        + pkg.packageName + " to old name " + origPackage.name);
10560                            }
10561                            break;
10562                        }
10563                    }
10564                }
10565            }
10566
10567            if (mTransferedPackages.contains(pkg.packageName)) {
10568                Slog.w(TAG, "Package " + pkg.packageName
10569                        + " was transferred to another, but its .apk remains");
10570            }
10571
10572            // See comments in nonMutatedPs declaration
10573            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10574                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10575                if (foundPs != null) {
10576                    nonMutatedPs = new PackageSetting(foundPs);
10577                }
10578            }
10579
10580            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10581                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10582                if (foundPs != null) {
10583                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10584                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10585                }
10586            }
10587
10588            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10589            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10590                PackageManagerService.reportSettingsProblem(Log.WARN,
10591                        "Package " + pkg.packageName + " shared user changed from "
10592                                + (pkgSetting.sharedUser != null
10593                                        ? pkgSetting.sharedUser.name : "<nothing>")
10594                                + " to "
10595                                + (suid != null ? suid.name : "<nothing>")
10596                                + "; replacing with new");
10597                pkgSetting = null;
10598            }
10599            final PackageSetting oldPkgSetting =
10600                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10601            final PackageSetting disabledPkgSetting =
10602                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10603
10604            String[] usesStaticLibraries = null;
10605            if (pkg.usesStaticLibraries != null) {
10606                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10607                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10608            }
10609
10610            if (pkgSetting == null) {
10611                final String parentPackageName = (pkg.parentPackage != null)
10612                        ? pkg.parentPackage.packageName : null;
10613                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10614                // REMOVE SharedUserSetting from method; update in a separate call
10615                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10616                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10617                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10618                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10619                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10620                        true /*allowInstall*/, instantApp, parentPackageName,
10621                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
10622                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10623                // SIDE EFFECTS; updates system state; move elsewhere
10624                if (origPackage != null) {
10625                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10626                }
10627                mSettings.addUserToSettingLPw(pkgSetting);
10628            } else {
10629                // REMOVE SharedUserSetting from method; update in a separate call.
10630                //
10631                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10632                // secondaryCpuAbi are not known at this point so we always update them
10633                // to null here, only to reset them at a later point.
10634                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10635                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10636                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10637                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10638                        UserManagerService.getInstance(), usesStaticLibraries,
10639                        pkg.usesStaticLibrariesVersions);
10640            }
10641            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10642            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10643
10644            // SIDE EFFECTS; modifies system state; move elsewhere
10645            if (pkgSetting.origPackage != null) {
10646                // If we are first transitioning from an original package,
10647                // fix up the new package's name now.  We need to do this after
10648                // looking up the package under its new name, so getPackageLP
10649                // can take care of fiddling things correctly.
10650                pkg.setPackageName(origPackage.name);
10651
10652                // File a report about this.
10653                String msg = "New package " + pkgSetting.realName
10654                        + " renamed to replace old package " + pkgSetting.name;
10655                reportSettingsProblem(Log.WARN, msg);
10656
10657                // Make a note of it.
10658                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10659                    mTransferedPackages.add(origPackage.name);
10660                }
10661
10662                // No longer need to retain this.
10663                pkgSetting.origPackage = null;
10664            }
10665
10666            // SIDE EFFECTS; modifies system state; move elsewhere
10667            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10668                // Make a note of it.
10669                mTransferedPackages.add(pkg.packageName);
10670            }
10671
10672            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10673                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10674            }
10675
10676            if ((scanFlags & SCAN_BOOTING) == 0
10677                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10678                // Check all shared libraries and map to their actual file path.
10679                // We only do this here for apps not on a system dir, because those
10680                // are the only ones that can fail an install due to this.  We
10681                // will take care of the system apps by updating all of their
10682                // library paths after the scan is done. Also during the initial
10683                // scan don't update any libs as we do this wholesale after all
10684                // apps are scanned to avoid dependency based scanning.
10685                updateSharedLibrariesLPr(pkg, null);
10686            }
10687
10688            if (mFoundPolicyFile) {
10689                SELinuxMMAC.assignSeInfoValue(pkg);
10690            }
10691            pkg.applicationInfo.uid = pkgSetting.appId;
10692            pkg.mExtras = pkgSetting;
10693
10694
10695            // Static shared libs have same package with different versions where
10696            // we internally use a synthetic package name to allow multiple versions
10697            // of the same package, therefore we need to compare signatures against
10698            // the package setting for the latest library version.
10699            PackageSetting signatureCheckPs = pkgSetting;
10700            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10701                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10702                if (libraryEntry != null) {
10703                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10704                }
10705            }
10706
10707            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10708                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10709                    // We just determined the app is signed correctly, so bring
10710                    // over the latest parsed certs.
10711                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10712                } else {
10713                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10714                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10715                                "Package " + pkg.packageName + " upgrade keys do not match the "
10716                                + "previously installed version");
10717                    } else {
10718                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10719                        String msg = "System package " + pkg.packageName
10720                                + " signature changed; retaining data.";
10721                        reportSettingsProblem(Log.WARN, msg);
10722                    }
10723                }
10724            } else {
10725                try {
10726                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10727                    verifySignaturesLP(signatureCheckPs, pkg);
10728                    // We just determined the app is signed correctly, so bring
10729                    // over the latest parsed certs.
10730                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10731                } catch (PackageManagerException e) {
10732                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10733                        throw e;
10734                    }
10735                    // The signature has changed, but this package is in the system
10736                    // image...  let's recover!
10737                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10738                    // However...  if this package is part of a shared user, but it
10739                    // doesn't match the signature of the shared user, let's fail.
10740                    // What this means is that you can't change the signatures
10741                    // associated with an overall shared user, which doesn't seem all
10742                    // that unreasonable.
10743                    if (signatureCheckPs.sharedUser != null) {
10744                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10745                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10746                            throw new PackageManagerException(
10747                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10748                                    "Signature mismatch for shared user: "
10749                                            + pkgSetting.sharedUser);
10750                        }
10751                    }
10752                    // File a report about this.
10753                    String msg = "System package " + pkg.packageName
10754                            + " signature changed; retaining data.";
10755                    reportSettingsProblem(Log.WARN, msg);
10756                }
10757            }
10758
10759            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10760                // This package wants to adopt ownership of permissions from
10761                // another package.
10762                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10763                    final String origName = pkg.mAdoptPermissions.get(i);
10764                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10765                    if (orig != null) {
10766                        if (verifyPackageUpdateLPr(orig, pkg)) {
10767                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10768                                    + pkg.packageName);
10769                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10770                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10771                        }
10772                    }
10773                }
10774            }
10775        }
10776
10777        pkg.applicationInfo.processName = fixProcessName(
10778                pkg.applicationInfo.packageName,
10779                pkg.applicationInfo.processName);
10780
10781        if (pkg != mPlatformPackage) {
10782            // Get all of our default paths setup
10783            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10784        }
10785
10786        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10787
10788        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10789            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10790                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10791                final boolean extractNativeLibs = !pkg.isLibrary();
10792                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
10793                        mAppLib32InstallDir);
10794                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10795
10796                // Some system apps still use directory structure for native libraries
10797                // in which case we might end up not detecting abi solely based on apk
10798                // structure. Try to detect abi based on directory structure.
10799                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10800                        pkg.applicationInfo.primaryCpuAbi == null) {
10801                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10802                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10803                }
10804            } else {
10805                // This is not a first boot or an upgrade, don't bother deriving the
10806                // ABI during the scan. Instead, trust the value that was stored in the
10807                // package setting.
10808                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10809                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10810
10811                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10812
10813                if (DEBUG_ABI_SELECTION) {
10814                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10815                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10816                        pkg.applicationInfo.secondaryCpuAbi);
10817                }
10818            }
10819        } else {
10820            if ((scanFlags & SCAN_MOVE) != 0) {
10821                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10822                // but we already have this packages package info in the PackageSetting. We just
10823                // use that and derive the native library path based on the new codepath.
10824                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10825                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10826            }
10827
10828            // Set native library paths again. For moves, the path will be updated based on the
10829            // ABIs we've determined above. For non-moves, the path will be updated based on the
10830            // ABIs we determined during compilation, but the path will depend on the final
10831            // package path (after the rename away from the stage path).
10832            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10833        }
10834
10835        // This is a special case for the "system" package, where the ABI is
10836        // dictated by the zygote configuration (and init.rc). We should keep track
10837        // of this ABI so that we can deal with "normal" applications that run under
10838        // the same UID correctly.
10839        if (mPlatformPackage == pkg) {
10840            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10841                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10842        }
10843
10844        // If there's a mismatch between the abi-override in the package setting
10845        // and the abiOverride specified for the install. Warn about this because we
10846        // would've already compiled the app without taking the package setting into
10847        // account.
10848        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10849            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10850                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10851                        " for package " + pkg.packageName);
10852            }
10853        }
10854
10855        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10856        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10857        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10858
10859        // Copy the derived override back to the parsed package, so that we can
10860        // update the package settings accordingly.
10861        pkg.cpuAbiOverride = cpuAbiOverride;
10862
10863        if (DEBUG_ABI_SELECTION) {
10864            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10865                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10866                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10867        }
10868
10869        // Push the derived path down into PackageSettings so we know what to
10870        // clean up at uninstall time.
10871        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10872
10873        if (DEBUG_ABI_SELECTION) {
10874            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10875                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10876                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10877        }
10878
10879        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10880        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10881            // We don't do this here during boot because we can do it all
10882            // at once after scanning all existing packages.
10883            //
10884            // We also do this *before* we perform dexopt on this package, so that
10885            // we can avoid redundant dexopts, and also to make sure we've got the
10886            // code and package path correct.
10887            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10888        }
10889
10890        if (mFactoryTest && pkg.requestedPermissions.contains(
10891                android.Manifest.permission.FACTORY_TEST)) {
10892            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10893        }
10894
10895        if (isSystemApp(pkg)) {
10896            pkgSetting.isOrphaned = true;
10897        }
10898
10899        // Take care of first install / last update times.
10900        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10901        if (currentTime != 0) {
10902            if (pkgSetting.firstInstallTime == 0) {
10903                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10904            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10905                pkgSetting.lastUpdateTime = currentTime;
10906            }
10907        } else if (pkgSetting.firstInstallTime == 0) {
10908            // We need *something*.  Take time time stamp of the file.
10909            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10910        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10911            if (scanFileTime != pkgSetting.timeStamp) {
10912                // A package on the system image has changed; consider this
10913                // to be an update.
10914                pkgSetting.lastUpdateTime = scanFileTime;
10915            }
10916        }
10917        pkgSetting.setTimeStamp(scanFileTime);
10918
10919        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10920            if (nonMutatedPs != null) {
10921                synchronized (mPackages) {
10922                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10923                }
10924            }
10925        } else {
10926            final int userId = user == null ? 0 : user.getIdentifier();
10927            // Modify state for the given package setting
10928            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10929                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10930            if (pkgSetting.getInstantApp(userId)) {
10931                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10932            }
10933        }
10934        return pkg;
10935    }
10936
10937    /**
10938     * Applies policy to the parsed package based upon the given policy flags.
10939     * Ensures the package is in a good state.
10940     * <p>
10941     * Implementation detail: This method must NOT have any side effect. It would
10942     * ideally be static, but, it requires locks to read system state.
10943     */
10944    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10945        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10946            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10947            if (pkg.applicationInfo.isDirectBootAware()) {
10948                // we're direct boot aware; set for all components
10949                for (PackageParser.Service s : pkg.services) {
10950                    s.info.encryptionAware = s.info.directBootAware = true;
10951                }
10952                for (PackageParser.Provider p : pkg.providers) {
10953                    p.info.encryptionAware = p.info.directBootAware = true;
10954                }
10955                for (PackageParser.Activity a : pkg.activities) {
10956                    a.info.encryptionAware = a.info.directBootAware = true;
10957                }
10958                for (PackageParser.Activity r : pkg.receivers) {
10959                    r.info.encryptionAware = r.info.directBootAware = true;
10960                }
10961            }
10962            if (compressedFileExists(pkg.baseCodePath)) {
10963                pkg.isStub = true;
10964            }
10965        } else {
10966            // Only allow system apps to be flagged as core apps.
10967            pkg.coreApp = false;
10968            // clear flags not applicable to regular apps
10969            pkg.applicationInfo.privateFlags &=
10970                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10971            pkg.applicationInfo.privateFlags &=
10972                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10973        }
10974        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10975
10976        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10977            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10978        }
10979
10980        if (!isSystemApp(pkg)) {
10981            // Only system apps can use these features.
10982            pkg.mOriginalPackages = null;
10983            pkg.mRealPackage = null;
10984            pkg.mAdoptPermissions = null;
10985        }
10986    }
10987
10988    /**
10989     * Asserts the parsed package is valid according to the given policy. If the
10990     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10991     * <p>
10992     * Implementation detail: This method must NOT have any side effects. It would
10993     * ideally be static, but, it requires locks to read system state.
10994     *
10995     * @throws PackageManagerException If the package fails any of the validation checks
10996     */
10997    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10998            throws PackageManagerException {
10999        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11000            assertCodePolicy(pkg);
11001        }
11002
11003        if (pkg.applicationInfo.getCodePath() == null ||
11004                pkg.applicationInfo.getResourcePath() == null) {
11005            // Bail out. The resource and code paths haven't been set.
11006            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11007                    "Code and resource paths haven't been set correctly");
11008        }
11009
11010        // Make sure we're not adding any bogus keyset info
11011        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11012        ksms.assertScannedPackageValid(pkg);
11013
11014        synchronized (mPackages) {
11015            // The special "android" package can only be defined once
11016            if (pkg.packageName.equals("android")) {
11017                if (mAndroidApplication != null) {
11018                    Slog.w(TAG, "*************************************************");
11019                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
11020                    Slog.w(TAG, " codePath=" + pkg.codePath);
11021                    Slog.w(TAG, "*************************************************");
11022                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11023                            "Core android package being redefined.  Skipping.");
11024                }
11025            }
11026
11027            // A package name must be unique; don't allow duplicates
11028            if (mPackages.containsKey(pkg.packageName)) {
11029                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11030                        "Application package " + pkg.packageName
11031                        + " already installed.  Skipping duplicate.");
11032            }
11033
11034            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11035                // Static libs have a synthetic package name containing the version
11036                // but we still want the base name to be unique.
11037                if (mPackages.containsKey(pkg.manifestPackageName)) {
11038                    throw new PackageManagerException(
11039                            "Duplicate static shared lib provider package");
11040                }
11041
11042                // Static shared libraries should have at least O target SDK
11043                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11044                    throw new PackageManagerException(
11045                            "Packages declaring static-shared libs must target O SDK or higher");
11046                }
11047
11048                // Package declaring static a shared lib cannot be instant apps
11049                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11050                    throw new PackageManagerException(
11051                            "Packages declaring static-shared libs cannot be instant apps");
11052                }
11053
11054                // Package declaring static a shared lib cannot be renamed since the package
11055                // name is synthetic and apps can't code around package manager internals.
11056                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11057                    throw new PackageManagerException(
11058                            "Packages declaring static-shared libs cannot be renamed");
11059                }
11060
11061                // Package declaring static a shared lib cannot declare child packages
11062                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11063                    throw new PackageManagerException(
11064                            "Packages declaring static-shared libs cannot have child packages");
11065                }
11066
11067                // Package declaring static a shared lib cannot declare dynamic libs
11068                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11069                    throw new PackageManagerException(
11070                            "Packages declaring static-shared libs cannot declare dynamic libs");
11071                }
11072
11073                // Package declaring static a shared lib cannot declare shared users
11074                if (pkg.mSharedUserId != null) {
11075                    throw new PackageManagerException(
11076                            "Packages declaring static-shared libs cannot declare shared users");
11077                }
11078
11079                // Static shared libs cannot declare activities
11080                if (!pkg.activities.isEmpty()) {
11081                    throw new PackageManagerException(
11082                            "Static shared libs cannot declare activities");
11083                }
11084
11085                // Static shared libs cannot declare services
11086                if (!pkg.services.isEmpty()) {
11087                    throw new PackageManagerException(
11088                            "Static shared libs cannot declare services");
11089                }
11090
11091                // Static shared libs cannot declare providers
11092                if (!pkg.providers.isEmpty()) {
11093                    throw new PackageManagerException(
11094                            "Static shared libs cannot declare content providers");
11095                }
11096
11097                // Static shared libs cannot declare receivers
11098                if (!pkg.receivers.isEmpty()) {
11099                    throw new PackageManagerException(
11100                            "Static shared libs cannot declare broadcast receivers");
11101                }
11102
11103                // Static shared libs cannot declare permission groups
11104                if (!pkg.permissionGroups.isEmpty()) {
11105                    throw new PackageManagerException(
11106                            "Static shared libs cannot declare permission groups");
11107                }
11108
11109                // Static shared libs cannot declare permissions
11110                if (!pkg.permissions.isEmpty()) {
11111                    throw new PackageManagerException(
11112                            "Static shared libs cannot declare permissions");
11113                }
11114
11115                // Static shared libs cannot declare protected broadcasts
11116                if (pkg.protectedBroadcasts != null) {
11117                    throw new PackageManagerException(
11118                            "Static shared libs cannot declare protected broadcasts");
11119                }
11120
11121                // Static shared libs cannot be overlay targets
11122                if (pkg.mOverlayTarget != null) {
11123                    throw new PackageManagerException(
11124                            "Static shared libs cannot be overlay targets");
11125                }
11126
11127                // The version codes must be ordered as lib versions
11128                int minVersionCode = Integer.MIN_VALUE;
11129                int maxVersionCode = Integer.MAX_VALUE;
11130
11131                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11132                        pkg.staticSharedLibName);
11133                if (versionedLib != null) {
11134                    final int versionCount = versionedLib.size();
11135                    for (int i = 0; i < versionCount; i++) {
11136                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11137                        final int libVersionCode = libInfo.getDeclaringPackage()
11138                                .getVersionCode();
11139                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11140                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11141                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11142                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11143                        } else {
11144                            minVersionCode = maxVersionCode = libVersionCode;
11145                            break;
11146                        }
11147                    }
11148                }
11149                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11150                    throw new PackageManagerException("Static shared"
11151                            + " lib version codes must be ordered as lib versions");
11152                }
11153            }
11154
11155            // Only privileged apps and updated privileged apps can add child packages.
11156            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11157                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11158                    throw new PackageManagerException("Only privileged apps can add child "
11159                            + "packages. Ignoring package " + pkg.packageName);
11160                }
11161                final int childCount = pkg.childPackages.size();
11162                for (int i = 0; i < childCount; i++) {
11163                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11164                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11165                            childPkg.packageName)) {
11166                        throw new PackageManagerException("Can't override child of "
11167                                + "another disabled app. Ignoring package " + pkg.packageName);
11168                    }
11169                }
11170            }
11171
11172            // If we're only installing presumed-existing packages, require that the
11173            // scanned APK is both already known and at the path previously established
11174            // for it.  Previously unknown packages we pick up normally, but if we have an
11175            // a priori expectation about this package's install presence, enforce it.
11176            // With a singular exception for new system packages. When an OTA contains
11177            // a new system package, we allow the codepath to change from a system location
11178            // to the user-installed location. If we don't allow this change, any newer,
11179            // user-installed version of the application will be ignored.
11180            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11181                if (mExpectingBetter.containsKey(pkg.packageName)) {
11182                    logCriticalInfo(Log.WARN,
11183                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11184                } else {
11185                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11186                    if (known != null) {
11187                        if (DEBUG_PACKAGE_SCANNING) {
11188                            Log.d(TAG, "Examining " + pkg.codePath
11189                                    + " and requiring known paths " + known.codePathString
11190                                    + " & " + known.resourcePathString);
11191                        }
11192                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11193                                || !pkg.applicationInfo.getResourcePath().equals(
11194                                        known.resourcePathString)) {
11195                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11196                                    "Application package " + pkg.packageName
11197                                    + " found at " + pkg.applicationInfo.getCodePath()
11198                                    + " but expected at " + known.codePathString
11199                                    + "; ignoring.");
11200                        }
11201                    }
11202                }
11203            }
11204
11205            // Verify that this new package doesn't have any content providers
11206            // that conflict with existing packages.  Only do this if the
11207            // package isn't already installed, since we don't want to break
11208            // things that are installed.
11209            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11210                final int N = pkg.providers.size();
11211                int i;
11212                for (i=0; i<N; i++) {
11213                    PackageParser.Provider p = pkg.providers.get(i);
11214                    if (p.info.authority != null) {
11215                        String names[] = p.info.authority.split(";");
11216                        for (int j = 0; j < names.length; j++) {
11217                            if (mProvidersByAuthority.containsKey(names[j])) {
11218                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11219                                final String otherPackageName =
11220                                        ((other != null && other.getComponentName() != null) ?
11221                                                other.getComponentName().getPackageName() : "?");
11222                                throw new PackageManagerException(
11223                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11224                                        "Can't install because provider name " + names[j]
11225                                                + " (in package " + pkg.applicationInfo.packageName
11226                                                + ") is already used by " + otherPackageName);
11227                            }
11228                        }
11229                    }
11230                }
11231            }
11232        }
11233    }
11234
11235    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11236            int type, String declaringPackageName, int declaringVersionCode) {
11237        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11238        if (versionedLib == null) {
11239            versionedLib = new SparseArray<>();
11240            mSharedLibraries.put(name, versionedLib);
11241            if (type == SharedLibraryInfo.TYPE_STATIC) {
11242                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11243            }
11244        } else if (versionedLib.indexOfKey(version) >= 0) {
11245            return false;
11246        }
11247        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11248                version, type, declaringPackageName, declaringVersionCode);
11249        versionedLib.put(version, libEntry);
11250        return true;
11251    }
11252
11253    private boolean removeSharedLibraryLPw(String name, int version) {
11254        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11255        if (versionedLib == null) {
11256            return false;
11257        }
11258        final int libIdx = versionedLib.indexOfKey(version);
11259        if (libIdx < 0) {
11260            return false;
11261        }
11262        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11263        versionedLib.remove(version);
11264        if (versionedLib.size() <= 0) {
11265            mSharedLibraries.remove(name);
11266            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11267                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11268                        .getPackageName());
11269            }
11270        }
11271        return true;
11272    }
11273
11274    /**
11275     * Adds a scanned package to the system. When this method is finished, the package will
11276     * be available for query, resolution, etc...
11277     */
11278    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11279            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11280        final String pkgName = pkg.packageName;
11281        if (mCustomResolverComponentName != null &&
11282                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11283            setUpCustomResolverActivity(pkg);
11284        }
11285
11286        if (pkg.packageName.equals("android")) {
11287            synchronized (mPackages) {
11288                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11289                    // Set up information for our fall-back user intent resolution activity.
11290                    mPlatformPackage = pkg;
11291                    pkg.mVersionCode = mSdkVersion;
11292                    mAndroidApplication = pkg.applicationInfo;
11293                    if (!mResolverReplaced) {
11294                        mResolveActivity.applicationInfo = mAndroidApplication;
11295                        mResolveActivity.name = ResolverActivity.class.getName();
11296                        mResolveActivity.packageName = mAndroidApplication.packageName;
11297                        mResolveActivity.processName = "system:ui";
11298                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11299                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11300                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11301                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11302                        mResolveActivity.exported = true;
11303                        mResolveActivity.enabled = true;
11304                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11305                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11306                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11307                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11308                                | ActivityInfo.CONFIG_ORIENTATION
11309                                | ActivityInfo.CONFIG_KEYBOARD
11310                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11311                        mResolveInfo.activityInfo = mResolveActivity;
11312                        mResolveInfo.priority = 0;
11313                        mResolveInfo.preferredOrder = 0;
11314                        mResolveInfo.match = 0;
11315                        mResolveComponentName = new ComponentName(
11316                                mAndroidApplication.packageName, mResolveActivity.name);
11317                    }
11318                }
11319            }
11320        }
11321
11322        ArrayList<PackageParser.Package> clientLibPkgs = null;
11323        // writer
11324        synchronized (mPackages) {
11325            boolean hasStaticSharedLibs = false;
11326
11327            // Any app can add new static shared libraries
11328            if (pkg.staticSharedLibName != null) {
11329                // Static shared libs don't allow renaming as they have synthetic package
11330                // names to allow install of multiple versions, so use name from manifest.
11331                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11332                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11333                        pkg.manifestPackageName, pkg.mVersionCode)) {
11334                    hasStaticSharedLibs = true;
11335                } else {
11336                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11337                                + pkg.staticSharedLibName + " already exists; skipping");
11338                }
11339                // Static shared libs cannot be updated once installed since they
11340                // use synthetic package name which includes the version code, so
11341                // not need to update other packages's shared lib dependencies.
11342            }
11343
11344            if (!hasStaticSharedLibs
11345                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11346                // Only system apps can add new dynamic shared libraries.
11347                if (pkg.libraryNames != null) {
11348                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11349                        String name = pkg.libraryNames.get(i);
11350                        boolean allowed = false;
11351                        if (pkg.isUpdatedSystemApp()) {
11352                            // New library entries can only be added through the
11353                            // system image.  This is important to get rid of a lot
11354                            // of nasty edge cases: for example if we allowed a non-
11355                            // system update of the app to add a library, then uninstalling
11356                            // the update would make the library go away, and assumptions
11357                            // we made such as through app install filtering would now
11358                            // have allowed apps on the device which aren't compatible
11359                            // with it.  Better to just have the restriction here, be
11360                            // conservative, and create many fewer cases that can negatively
11361                            // impact the user experience.
11362                            final PackageSetting sysPs = mSettings
11363                                    .getDisabledSystemPkgLPr(pkg.packageName);
11364                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11365                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11366                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11367                                        allowed = true;
11368                                        break;
11369                                    }
11370                                }
11371                            }
11372                        } else {
11373                            allowed = true;
11374                        }
11375                        if (allowed) {
11376                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11377                                    SharedLibraryInfo.VERSION_UNDEFINED,
11378                                    SharedLibraryInfo.TYPE_DYNAMIC,
11379                                    pkg.packageName, pkg.mVersionCode)) {
11380                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11381                                        + name + " already exists; skipping");
11382                            }
11383                        } else {
11384                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11385                                    + name + " that is not declared on system image; skipping");
11386                        }
11387                    }
11388
11389                    if ((scanFlags & SCAN_BOOTING) == 0) {
11390                        // If we are not booting, we need to update any applications
11391                        // that are clients of our shared library.  If we are booting,
11392                        // this will all be done once the scan is complete.
11393                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11394                    }
11395                }
11396            }
11397        }
11398
11399        if ((scanFlags & SCAN_BOOTING) != 0) {
11400            // No apps can run during boot scan, so they don't need to be frozen
11401        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11402            // Caller asked to not kill app, so it's probably not frozen
11403        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11404            // Caller asked us to ignore frozen check for some reason; they
11405            // probably didn't know the package name
11406        } else {
11407            // We're doing major surgery on this package, so it better be frozen
11408            // right now to keep it from launching
11409            checkPackageFrozen(pkgName);
11410        }
11411
11412        // Also need to kill any apps that are dependent on the library.
11413        if (clientLibPkgs != null) {
11414            for (int i=0; i<clientLibPkgs.size(); i++) {
11415                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11416                killApplication(clientPkg.applicationInfo.packageName,
11417                        clientPkg.applicationInfo.uid, "update lib");
11418            }
11419        }
11420
11421        // writer
11422        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11423
11424        synchronized (mPackages) {
11425            // We don't expect installation to fail beyond this point
11426
11427            // Add the new setting to mSettings
11428            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11429            // Add the new setting to mPackages
11430            mPackages.put(pkg.applicationInfo.packageName, pkg);
11431            // Make sure we don't accidentally delete its data.
11432            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11433            while (iter.hasNext()) {
11434                PackageCleanItem item = iter.next();
11435                if (pkgName.equals(item.packageName)) {
11436                    iter.remove();
11437                }
11438            }
11439
11440            // Add the package's KeySets to the global KeySetManagerService
11441            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11442            ksms.addScannedPackageLPw(pkg);
11443
11444            int N = pkg.providers.size();
11445            StringBuilder r = null;
11446            int i;
11447            for (i=0; i<N; i++) {
11448                PackageParser.Provider p = pkg.providers.get(i);
11449                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11450                        p.info.processName);
11451                mProviders.addProvider(p);
11452                p.syncable = p.info.isSyncable;
11453                if (p.info.authority != null) {
11454                    String names[] = p.info.authority.split(";");
11455                    p.info.authority = null;
11456                    for (int j = 0; j < names.length; j++) {
11457                        if (j == 1 && p.syncable) {
11458                            // We only want the first authority for a provider to possibly be
11459                            // syncable, so if we already added this provider using a different
11460                            // authority clear the syncable flag. We copy the provider before
11461                            // changing it because the mProviders object contains a reference
11462                            // to a provider that we don't want to change.
11463                            // Only do this for the second authority since the resulting provider
11464                            // object can be the same for all future authorities for this provider.
11465                            p = new PackageParser.Provider(p);
11466                            p.syncable = false;
11467                        }
11468                        if (!mProvidersByAuthority.containsKey(names[j])) {
11469                            mProvidersByAuthority.put(names[j], p);
11470                            if (p.info.authority == null) {
11471                                p.info.authority = names[j];
11472                            } else {
11473                                p.info.authority = p.info.authority + ";" + names[j];
11474                            }
11475                            if (DEBUG_PACKAGE_SCANNING) {
11476                                if (chatty)
11477                                    Log.d(TAG, "Registered content provider: " + names[j]
11478                                            + ", className = " + p.info.name + ", isSyncable = "
11479                                            + p.info.isSyncable);
11480                            }
11481                        } else {
11482                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11483                            Slog.w(TAG, "Skipping provider name " + names[j] +
11484                                    " (in package " + pkg.applicationInfo.packageName +
11485                                    "): name already used by "
11486                                    + ((other != null && other.getComponentName() != null)
11487                                            ? other.getComponentName().getPackageName() : "?"));
11488                        }
11489                    }
11490                }
11491                if (chatty) {
11492                    if (r == null) {
11493                        r = new StringBuilder(256);
11494                    } else {
11495                        r.append(' ');
11496                    }
11497                    r.append(p.info.name);
11498                }
11499            }
11500            if (r != null) {
11501                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11502            }
11503
11504            N = pkg.services.size();
11505            r = null;
11506            for (i=0; i<N; i++) {
11507                PackageParser.Service s = pkg.services.get(i);
11508                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11509                        s.info.processName);
11510                mServices.addService(s);
11511                if (chatty) {
11512                    if (r == null) {
11513                        r = new StringBuilder(256);
11514                    } else {
11515                        r.append(' ');
11516                    }
11517                    r.append(s.info.name);
11518                }
11519            }
11520            if (r != null) {
11521                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11522            }
11523
11524            N = pkg.receivers.size();
11525            r = null;
11526            for (i=0; i<N; i++) {
11527                PackageParser.Activity a = pkg.receivers.get(i);
11528                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11529                        a.info.processName);
11530                mReceivers.addActivity(a, "receiver");
11531                if (chatty) {
11532                    if (r == null) {
11533                        r = new StringBuilder(256);
11534                    } else {
11535                        r.append(' ');
11536                    }
11537                    r.append(a.info.name);
11538                }
11539            }
11540            if (r != null) {
11541                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11542            }
11543
11544            N = pkg.activities.size();
11545            r = null;
11546            for (i=0; i<N; i++) {
11547                PackageParser.Activity a = pkg.activities.get(i);
11548                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11549                        a.info.processName);
11550                mActivities.addActivity(a, "activity");
11551                if (chatty) {
11552                    if (r == null) {
11553                        r = new StringBuilder(256);
11554                    } else {
11555                        r.append(' ');
11556                    }
11557                    r.append(a.info.name);
11558                }
11559            }
11560            if (r != null) {
11561                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11562            }
11563
11564            N = pkg.permissionGroups.size();
11565            r = null;
11566            for (i=0; i<N; i++) {
11567                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11568                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11569                final String curPackageName = cur == null ? null : cur.info.packageName;
11570                // Dont allow ephemeral apps to define new permission groups.
11571                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11572                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11573                            + pg.info.packageName
11574                            + " ignored: instant apps cannot define new permission groups.");
11575                    continue;
11576                }
11577                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11578                if (cur == null || isPackageUpdate) {
11579                    mPermissionGroups.put(pg.info.name, pg);
11580                    if (chatty) {
11581                        if (r == null) {
11582                            r = new StringBuilder(256);
11583                        } else {
11584                            r.append(' ');
11585                        }
11586                        if (isPackageUpdate) {
11587                            r.append("UPD:");
11588                        }
11589                        r.append(pg.info.name);
11590                    }
11591                } else {
11592                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11593                            + pg.info.packageName + " ignored: original from "
11594                            + cur.info.packageName);
11595                    if (chatty) {
11596                        if (r == null) {
11597                            r = new StringBuilder(256);
11598                        } else {
11599                            r.append(' ');
11600                        }
11601                        r.append("DUP:");
11602                        r.append(pg.info.name);
11603                    }
11604                }
11605            }
11606            if (r != null) {
11607                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11608            }
11609
11610            N = pkg.permissions.size();
11611            r = null;
11612            for (i=0; i<N; i++) {
11613                PackageParser.Permission p = pkg.permissions.get(i);
11614
11615                // Dont allow ephemeral apps to define new permissions.
11616                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11617                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11618                            + p.info.packageName
11619                            + " ignored: instant apps cannot define new permissions.");
11620                    continue;
11621                }
11622
11623                // Assume by default that we did not install this permission into the system.
11624                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11625
11626                // Now that permission groups have a special meaning, we ignore permission
11627                // groups for legacy apps to prevent unexpected behavior. In particular,
11628                // permissions for one app being granted to someone just because they happen
11629                // to be in a group defined by another app (before this had no implications).
11630                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11631                    p.group = mPermissionGroups.get(p.info.group);
11632                    // Warn for a permission in an unknown group.
11633                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11634                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11635                                + p.info.packageName + " in an unknown group " + p.info.group);
11636                    }
11637                }
11638
11639                ArrayMap<String, BasePermission> permissionMap =
11640                        p.tree ? mSettings.mPermissionTrees
11641                                : mSettings.mPermissions;
11642                BasePermission bp = permissionMap.get(p.info.name);
11643
11644                // Allow system apps to redefine non-system permissions
11645                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11646                    final boolean currentOwnerIsSystem = (bp.perm != null
11647                            && isSystemApp(bp.perm.owner));
11648                    if (isSystemApp(p.owner)) {
11649                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
11650                            // It's a built-in permission and no owner, take ownership now
11651                            bp.packageSetting = pkgSetting;
11652                            bp.perm = p;
11653                            bp.uid = pkg.applicationInfo.uid;
11654                            bp.sourcePackage = p.info.packageName;
11655                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11656                        } else if (!currentOwnerIsSystem) {
11657                            String msg = "New decl " + p.owner + " of permission  "
11658                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
11659                            reportSettingsProblem(Log.WARN, msg);
11660                            bp = null;
11661                        }
11662                    }
11663                }
11664
11665                if (bp == null) {
11666                    bp = new BasePermission(p.info.name, p.info.packageName,
11667                            BasePermission.TYPE_NORMAL);
11668                    permissionMap.put(p.info.name, bp);
11669                }
11670
11671                if (bp.perm == null) {
11672                    if (bp.sourcePackage == null
11673                            || bp.sourcePackage.equals(p.info.packageName)) {
11674                        BasePermission tree = findPermissionTreeLP(p.info.name);
11675                        if (tree == null
11676                                || tree.sourcePackage.equals(p.info.packageName)) {
11677                            bp.packageSetting = pkgSetting;
11678                            bp.perm = p;
11679                            bp.uid = pkg.applicationInfo.uid;
11680                            bp.sourcePackage = p.info.packageName;
11681                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11682                            if (chatty) {
11683                                if (r == null) {
11684                                    r = new StringBuilder(256);
11685                                } else {
11686                                    r.append(' ');
11687                                }
11688                                r.append(p.info.name);
11689                            }
11690                        } else {
11691                            Slog.w(TAG, "Permission " + p.info.name + " from package "
11692                                    + p.info.packageName + " ignored: base tree "
11693                                    + tree.name + " is from package "
11694                                    + tree.sourcePackage);
11695                        }
11696                    } else {
11697                        Slog.w(TAG, "Permission " + p.info.name + " from package "
11698                                + p.info.packageName + " ignored: original from "
11699                                + bp.sourcePackage);
11700                    }
11701                } else if (chatty) {
11702                    if (r == null) {
11703                        r = new StringBuilder(256);
11704                    } else {
11705                        r.append(' ');
11706                    }
11707                    r.append("DUP:");
11708                    r.append(p.info.name);
11709                }
11710                if (bp.perm == p) {
11711                    bp.protectionLevel = p.info.protectionLevel;
11712                }
11713            }
11714
11715            if (r != null) {
11716                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
11717            }
11718
11719            N = pkg.instrumentation.size();
11720            r = null;
11721            for (i=0; i<N; i++) {
11722                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11723                a.info.packageName = pkg.applicationInfo.packageName;
11724                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11725                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11726                a.info.splitNames = pkg.splitNames;
11727                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11728                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11729                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11730                a.info.dataDir = pkg.applicationInfo.dataDir;
11731                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11732                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11733                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11734                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11735                mInstrumentation.put(a.getComponentName(), a);
11736                if (chatty) {
11737                    if (r == null) {
11738                        r = new StringBuilder(256);
11739                    } else {
11740                        r.append(' ');
11741                    }
11742                    r.append(a.info.name);
11743                }
11744            }
11745            if (r != null) {
11746                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11747            }
11748
11749            if (pkg.protectedBroadcasts != null) {
11750                N = pkg.protectedBroadcasts.size();
11751                synchronized (mProtectedBroadcasts) {
11752                    for (i = 0; i < N; i++) {
11753                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11754                    }
11755                }
11756            }
11757        }
11758
11759        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11760    }
11761
11762    /**
11763     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11764     * is derived purely on the basis of the contents of {@code scanFile} and
11765     * {@code cpuAbiOverride}.
11766     *
11767     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11768     */
11769    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11770                                 String cpuAbiOverride, boolean extractLibs,
11771                                 File appLib32InstallDir)
11772            throws PackageManagerException {
11773        // Give ourselves some initial paths; we'll come back for another
11774        // pass once we've determined ABI below.
11775        setNativeLibraryPaths(pkg, appLib32InstallDir);
11776
11777        // We would never need to extract libs for forward-locked and external packages,
11778        // since the container service will do it for us. We shouldn't attempt to
11779        // extract libs from system app when it was not updated.
11780        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11781                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11782            extractLibs = false;
11783        }
11784
11785        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11786        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11787
11788        NativeLibraryHelper.Handle handle = null;
11789        try {
11790            handle = NativeLibraryHelper.Handle.create(pkg);
11791            // TODO(multiArch): This can be null for apps that didn't go through the
11792            // usual installation process. We can calculate it again, like we
11793            // do during install time.
11794            //
11795            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11796            // unnecessary.
11797            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11798
11799            // Null out the abis so that they can be recalculated.
11800            pkg.applicationInfo.primaryCpuAbi = null;
11801            pkg.applicationInfo.secondaryCpuAbi = null;
11802            if (isMultiArch(pkg.applicationInfo)) {
11803                // Warn if we've set an abiOverride for multi-lib packages..
11804                // By definition, we need to copy both 32 and 64 bit libraries for
11805                // such packages.
11806                if (pkg.cpuAbiOverride != null
11807                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11808                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11809                }
11810
11811                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11812                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11813                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11814                    if (extractLibs) {
11815                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11816                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11817                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11818                                useIsaSpecificSubdirs);
11819                    } else {
11820                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11821                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11822                    }
11823                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11824                }
11825
11826                // Shared library native code should be in the APK zip aligned
11827                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11828                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11829                            "Shared library native lib extraction not supported");
11830                }
11831
11832                maybeThrowExceptionForMultiArchCopy(
11833                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11834
11835                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11836                    if (extractLibs) {
11837                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11838                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11839                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11840                                useIsaSpecificSubdirs);
11841                    } else {
11842                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11843                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11844                    }
11845                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11846                }
11847
11848                maybeThrowExceptionForMultiArchCopy(
11849                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11850
11851                if (abi64 >= 0) {
11852                    // Shared library native libs should be in the APK zip aligned
11853                    if (extractLibs && pkg.isLibrary()) {
11854                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11855                                "Shared library native lib extraction not supported");
11856                    }
11857                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11858                }
11859
11860                if (abi32 >= 0) {
11861                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11862                    if (abi64 >= 0) {
11863                        if (pkg.use32bitAbi) {
11864                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11865                            pkg.applicationInfo.primaryCpuAbi = abi;
11866                        } else {
11867                            pkg.applicationInfo.secondaryCpuAbi = abi;
11868                        }
11869                    } else {
11870                        pkg.applicationInfo.primaryCpuAbi = abi;
11871                    }
11872                }
11873            } else {
11874                String[] abiList = (cpuAbiOverride != null) ?
11875                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11876
11877                // Enable gross and lame hacks for apps that are built with old
11878                // SDK tools. We must scan their APKs for renderscript bitcode and
11879                // not launch them if it's present. Don't bother checking on devices
11880                // that don't have 64 bit support.
11881                boolean needsRenderScriptOverride = false;
11882                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11883                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11884                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11885                    needsRenderScriptOverride = true;
11886                }
11887
11888                final int copyRet;
11889                if (extractLibs) {
11890                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11891                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11892                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11893                } else {
11894                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11895                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11896                }
11897                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11898
11899                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11900                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11901                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11902                }
11903
11904                if (copyRet >= 0) {
11905                    // Shared libraries that have native libs must be multi-architecture
11906                    if (pkg.isLibrary()) {
11907                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11908                                "Shared library with native libs must be multiarch");
11909                    }
11910                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11911                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11912                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11913                } else if (needsRenderScriptOverride) {
11914                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11915                }
11916            }
11917        } catch (IOException ioe) {
11918            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11919        } finally {
11920            IoUtils.closeQuietly(handle);
11921        }
11922
11923        // Now that we've calculated the ABIs and determined if it's an internal app,
11924        // we will go ahead and populate the nativeLibraryPath.
11925        setNativeLibraryPaths(pkg, appLib32InstallDir);
11926    }
11927
11928    /**
11929     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11930     * i.e, so that all packages can be run inside a single process if required.
11931     *
11932     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11933     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11934     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11935     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11936     * updating a package that belongs to a shared user.
11937     *
11938     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11939     * adds unnecessary complexity.
11940     */
11941    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11942            PackageParser.Package scannedPackage) {
11943        String requiredInstructionSet = null;
11944        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11945            requiredInstructionSet = VMRuntime.getInstructionSet(
11946                     scannedPackage.applicationInfo.primaryCpuAbi);
11947        }
11948
11949        PackageSetting requirer = null;
11950        for (PackageSetting ps : packagesForUser) {
11951            // If packagesForUser contains scannedPackage, we skip it. This will happen
11952            // when scannedPackage is an update of an existing package. Without this check,
11953            // we will never be able to change the ABI of any package belonging to a shared
11954            // user, even if it's compatible with other packages.
11955            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11956                if (ps.primaryCpuAbiString == null) {
11957                    continue;
11958                }
11959
11960                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11961                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11962                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11963                    // this but there's not much we can do.
11964                    String errorMessage = "Instruction set mismatch, "
11965                            + ((requirer == null) ? "[caller]" : requirer)
11966                            + " requires " + requiredInstructionSet + " whereas " + ps
11967                            + " requires " + instructionSet;
11968                    Slog.w(TAG, errorMessage);
11969                }
11970
11971                if (requiredInstructionSet == null) {
11972                    requiredInstructionSet = instructionSet;
11973                    requirer = ps;
11974                }
11975            }
11976        }
11977
11978        if (requiredInstructionSet != null) {
11979            String adjustedAbi;
11980            if (requirer != null) {
11981                // requirer != null implies that either scannedPackage was null or that scannedPackage
11982                // did not require an ABI, in which case we have to adjust scannedPackage to match
11983                // the ABI of the set (which is the same as requirer's ABI)
11984                adjustedAbi = requirer.primaryCpuAbiString;
11985                if (scannedPackage != null) {
11986                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11987                }
11988            } else {
11989                // requirer == null implies that we're updating all ABIs in the set to
11990                // match scannedPackage.
11991                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11992            }
11993
11994            for (PackageSetting ps : packagesForUser) {
11995                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11996                    if (ps.primaryCpuAbiString != null) {
11997                        continue;
11998                    }
11999
12000                    ps.primaryCpuAbiString = adjustedAbi;
12001                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12002                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12003                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12004                        if (DEBUG_ABI_SELECTION) {
12005                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12006                                    + " (requirer="
12007                                    + (requirer != null ? requirer.pkg : "null")
12008                                    + ", scannedPackage="
12009                                    + (scannedPackage != null ? scannedPackage : "null")
12010                                    + ")");
12011                        }
12012                        try {
12013                            mInstaller.rmdex(ps.codePathString,
12014                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
12015                        } catch (InstallerException ignored) {
12016                        }
12017                    }
12018                }
12019            }
12020        }
12021    }
12022
12023    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12024        synchronized (mPackages) {
12025            mResolverReplaced = true;
12026            // Set up information for custom user intent resolution activity.
12027            mResolveActivity.applicationInfo = pkg.applicationInfo;
12028            mResolveActivity.name = mCustomResolverComponentName.getClassName();
12029            mResolveActivity.packageName = pkg.applicationInfo.packageName;
12030            mResolveActivity.processName = pkg.applicationInfo.packageName;
12031            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12032            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12033                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12034            mResolveActivity.theme = 0;
12035            mResolveActivity.exported = true;
12036            mResolveActivity.enabled = true;
12037            mResolveInfo.activityInfo = mResolveActivity;
12038            mResolveInfo.priority = 0;
12039            mResolveInfo.preferredOrder = 0;
12040            mResolveInfo.match = 0;
12041            mResolveComponentName = mCustomResolverComponentName;
12042            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12043                    mResolveComponentName);
12044        }
12045    }
12046
12047    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12048        if (installerActivity == null) {
12049            if (DEBUG_EPHEMERAL) {
12050                Slog.d(TAG, "Clear ephemeral installer activity");
12051            }
12052            mInstantAppInstallerActivity = null;
12053            return;
12054        }
12055
12056        if (DEBUG_EPHEMERAL) {
12057            Slog.d(TAG, "Set ephemeral installer activity: "
12058                    + installerActivity.getComponentName());
12059        }
12060        // Set up information for ephemeral installer activity
12061        mInstantAppInstallerActivity = installerActivity;
12062        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12063                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12064        mInstantAppInstallerActivity.exported = true;
12065        mInstantAppInstallerActivity.enabled = true;
12066        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12067        mInstantAppInstallerInfo.priority = 0;
12068        mInstantAppInstallerInfo.preferredOrder = 1;
12069        mInstantAppInstallerInfo.isDefault = true;
12070        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12071                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12072    }
12073
12074    private static String calculateBundledApkRoot(final String codePathString) {
12075        final File codePath = new File(codePathString);
12076        final File codeRoot;
12077        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12078            codeRoot = Environment.getRootDirectory();
12079        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12080            codeRoot = Environment.getOemDirectory();
12081        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12082            codeRoot = Environment.getVendorDirectory();
12083        } else {
12084            // Unrecognized code path; take its top real segment as the apk root:
12085            // e.g. /something/app/blah.apk => /something
12086            try {
12087                File f = codePath.getCanonicalFile();
12088                File parent = f.getParentFile();    // non-null because codePath is a file
12089                File tmp;
12090                while ((tmp = parent.getParentFile()) != null) {
12091                    f = parent;
12092                    parent = tmp;
12093                }
12094                codeRoot = f;
12095                Slog.w(TAG, "Unrecognized code path "
12096                        + codePath + " - using " + codeRoot);
12097            } catch (IOException e) {
12098                // Can't canonicalize the code path -- shenanigans?
12099                Slog.w(TAG, "Can't canonicalize code path " + codePath);
12100                return Environment.getRootDirectory().getPath();
12101            }
12102        }
12103        return codeRoot.getPath();
12104    }
12105
12106    /**
12107     * Derive and set the location of native libraries for the given package,
12108     * which varies depending on where and how the package was installed.
12109     */
12110    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12111        final ApplicationInfo info = pkg.applicationInfo;
12112        final String codePath = pkg.codePath;
12113        final File codeFile = new File(codePath);
12114        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12115        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12116
12117        info.nativeLibraryRootDir = null;
12118        info.nativeLibraryRootRequiresIsa = false;
12119        info.nativeLibraryDir = null;
12120        info.secondaryNativeLibraryDir = null;
12121
12122        if (isApkFile(codeFile)) {
12123            // Monolithic install
12124            if (bundledApp) {
12125                // If "/system/lib64/apkname" exists, assume that is the per-package
12126                // native library directory to use; otherwise use "/system/lib/apkname".
12127                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12128                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12129                        getPrimaryInstructionSet(info));
12130
12131                // This is a bundled system app so choose the path based on the ABI.
12132                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12133                // is just the default path.
12134                final String apkName = deriveCodePathName(codePath);
12135                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12136                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12137                        apkName).getAbsolutePath();
12138
12139                if (info.secondaryCpuAbi != null) {
12140                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12141                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12142                            secondaryLibDir, apkName).getAbsolutePath();
12143                }
12144            } else if (asecApp) {
12145                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12146                        .getAbsolutePath();
12147            } else {
12148                final String apkName = deriveCodePathName(codePath);
12149                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12150                        .getAbsolutePath();
12151            }
12152
12153            info.nativeLibraryRootRequiresIsa = false;
12154            info.nativeLibraryDir = info.nativeLibraryRootDir;
12155        } else {
12156            // Cluster install
12157            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12158            info.nativeLibraryRootRequiresIsa = true;
12159
12160            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12161                    getPrimaryInstructionSet(info)).getAbsolutePath();
12162
12163            if (info.secondaryCpuAbi != null) {
12164                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12165                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12166            }
12167        }
12168    }
12169
12170    /**
12171     * Calculate the abis and roots for a bundled app. These can uniquely
12172     * be determined from the contents of the system partition, i.e whether
12173     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12174     * of this information, and instead assume that the system was built
12175     * sensibly.
12176     */
12177    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12178                                           PackageSetting pkgSetting) {
12179        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12180
12181        // If "/system/lib64/apkname" exists, assume that is the per-package
12182        // native library directory to use; otherwise use "/system/lib/apkname".
12183        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12184        setBundledAppAbi(pkg, apkRoot, apkName);
12185        // pkgSetting might be null during rescan following uninstall of updates
12186        // to a bundled app, so accommodate that possibility.  The settings in
12187        // that case will be established later from the parsed package.
12188        //
12189        // If the settings aren't null, sync them up with what we've just derived.
12190        // note that apkRoot isn't stored in the package settings.
12191        if (pkgSetting != null) {
12192            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12193            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12194        }
12195    }
12196
12197    /**
12198     * Deduces the ABI of a bundled app and sets the relevant fields on the
12199     * parsed pkg object.
12200     *
12201     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12202     *        under which system libraries are installed.
12203     * @param apkName the name of the installed package.
12204     */
12205    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12206        final File codeFile = new File(pkg.codePath);
12207
12208        final boolean has64BitLibs;
12209        final boolean has32BitLibs;
12210        if (isApkFile(codeFile)) {
12211            // Monolithic install
12212            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12213            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12214        } else {
12215            // Cluster install
12216            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12217            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12218                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12219                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12220                has64BitLibs = (new File(rootDir, isa)).exists();
12221            } else {
12222                has64BitLibs = false;
12223            }
12224            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12225                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12226                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12227                has32BitLibs = (new File(rootDir, isa)).exists();
12228            } else {
12229                has32BitLibs = false;
12230            }
12231        }
12232
12233        if (has64BitLibs && !has32BitLibs) {
12234            // The package has 64 bit libs, but not 32 bit libs. Its primary
12235            // ABI should be 64 bit. We can safely assume here that the bundled
12236            // native libraries correspond to the most preferred ABI in the list.
12237
12238            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12239            pkg.applicationInfo.secondaryCpuAbi = null;
12240        } else if (has32BitLibs && !has64BitLibs) {
12241            // The package has 32 bit libs but not 64 bit libs. Its primary
12242            // ABI should be 32 bit.
12243
12244            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12245            pkg.applicationInfo.secondaryCpuAbi = null;
12246        } else if (has32BitLibs && has64BitLibs) {
12247            // The application has both 64 and 32 bit bundled libraries. We check
12248            // here that the app declares multiArch support, and warn if it doesn't.
12249            //
12250            // We will be lenient here and record both ABIs. The primary will be the
12251            // ABI that's higher on the list, i.e, a device that's configured to prefer
12252            // 64 bit apps will see a 64 bit primary ABI,
12253
12254            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12255                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12256            }
12257
12258            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12259                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12260                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12261            } else {
12262                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12263                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12264            }
12265        } else {
12266            pkg.applicationInfo.primaryCpuAbi = null;
12267            pkg.applicationInfo.secondaryCpuAbi = null;
12268        }
12269    }
12270
12271    private void killApplication(String pkgName, int appId, String reason) {
12272        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12273    }
12274
12275    private void killApplication(String pkgName, int appId, int userId, String reason) {
12276        // Request the ActivityManager to kill the process(only for existing packages)
12277        // so that we do not end up in a confused state while the user is still using the older
12278        // version of the application while the new one gets installed.
12279        final long token = Binder.clearCallingIdentity();
12280        try {
12281            IActivityManager am = ActivityManager.getService();
12282            if (am != null) {
12283                try {
12284                    am.killApplication(pkgName, appId, userId, reason);
12285                } catch (RemoteException e) {
12286                }
12287            }
12288        } finally {
12289            Binder.restoreCallingIdentity(token);
12290        }
12291    }
12292
12293    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12294        // Remove the parent package setting
12295        PackageSetting ps = (PackageSetting) pkg.mExtras;
12296        if (ps != null) {
12297            removePackageLI(ps, chatty);
12298        }
12299        // Remove the child package setting
12300        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12301        for (int i = 0; i < childCount; i++) {
12302            PackageParser.Package childPkg = pkg.childPackages.get(i);
12303            ps = (PackageSetting) childPkg.mExtras;
12304            if (ps != null) {
12305                removePackageLI(ps, chatty);
12306            }
12307        }
12308    }
12309
12310    void removePackageLI(PackageSetting ps, boolean chatty) {
12311        if (DEBUG_INSTALL) {
12312            if (chatty)
12313                Log.d(TAG, "Removing package " + ps.name);
12314        }
12315
12316        // writer
12317        synchronized (mPackages) {
12318            mPackages.remove(ps.name);
12319            final PackageParser.Package pkg = ps.pkg;
12320            if (pkg != null) {
12321                cleanPackageDataStructuresLILPw(pkg, chatty);
12322            }
12323        }
12324    }
12325
12326    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12327        if (DEBUG_INSTALL) {
12328            if (chatty)
12329                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12330        }
12331
12332        // writer
12333        synchronized (mPackages) {
12334            // Remove the parent package
12335            mPackages.remove(pkg.applicationInfo.packageName);
12336            cleanPackageDataStructuresLILPw(pkg, chatty);
12337
12338            // Remove the child packages
12339            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12340            for (int i = 0; i < childCount; i++) {
12341                PackageParser.Package childPkg = pkg.childPackages.get(i);
12342                mPackages.remove(childPkg.applicationInfo.packageName);
12343                cleanPackageDataStructuresLILPw(childPkg, chatty);
12344            }
12345        }
12346    }
12347
12348    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12349        int N = pkg.providers.size();
12350        StringBuilder r = null;
12351        int i;
12352        for (i=0; i<N; i++) {
12353            PackageParser.Provider p = pkg.providers.get(i);
12354            mProviders.removeProvider(p);
12355            if (p.info.authority == null) {
12356
12357                /* There was another ContentProvider with this authority when
12358                 * this app was installed so this authority is null,
12359                 * Ignore it as we don't have to unregister the provider.
12360                 */
12361                continue;
12362            }
12363            String names[] = p.info.authority.split(";");
12364            for (int j = 0; j < names.length; j++) {
12365                if (mProvidersByAuthority.get(names[j]) == p) {
12366                    mProvidersByAuthority.remove(names[j]);
12367                    if (DEBUG_REMOVE) {
12368                        if (chatty)
12369                            Log.d(TAG, "Unregistered content provider: " + names[j]
12370                                    + ", className = " + p.info.name + ", isSyncable = "
12371                                    + p.info.isSyncable);
12372                    }
12373                }
12374            }
12375            if (DEBUG_REMOVE && chatty) {
12376                if (r == null) {
12377                    r = new StringBuilder(256);
12378                } else {
12379                    r.append(' ');
12380                }
12381                r.append(p.info.name);
12382            }
12383        }
12384        if (r != null) {
12385            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12386        }
12387
12388        N = pkg.services.size();
12389        r = null;
12390        for (i=0; i<N; i++) {
12391            PackageParser.Service s = pkg.services.get(i);
12392            mServices.removeService(s);
12393            if (chatty) {
12394                if (r == null) {
12395                    r = new StringBuilder(256);
12396                } else {
12397                    r.append(' ');
12398                }
12399                r.append(s.info.name);
12400            }
12401        }
12402        if (r != null) {
12403            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12404        }
12405
12406        N = pkg.receivers.size();
12407        r = null;
12408        for (i=0; i<N; i++) {
12409            PackageParser.Activity a = pkg.receivers.get(i);
12410            mReceivers.removeActivity(a, "receiver");
12411            if (DEBUG_REMOVE && chatty) {
12412                if (r == null) {
12413                    r = new StringBuilder(256);
12414                } else {
12415                    r.append(' ');
12416                }
12417                r.append(a.info.name);
12418            }
12419        }
12420        if (r != null) {
12421            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12422        }
12423
12424        N = pkg.activities.size();
12425        r = null;
12426        for (i=0; i<N; i++) {
12427            PackageParser.Activity a = pkg.activities.get(i);
12428            mActivities.removeActivity(a, "activity");
12429            if (DEBUG_REMOVE && chatty) {
12430                if (r == null) {
12431                    r = new StringBuilder(256);
12432                } else {
12433                    r.append(' ');
12434                }
12435                r.append(a.info.name);
12436            }
12437        }
12438        if (r != null) {
12439            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12440        }
12441
12442        N = pkg.permissions.size();
12443        r = null;
12444        for (i=0; i<N; i++) {
12445            PackageParser.Permission p = pkg.permissions.get(i);
12446            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12447            if (bp == null) {
12448                bp = mSettings.mPermissionTrees.get(p.info.name);
12449            }
12450            if (bp != null && bp.perm == p) {
12451                bp.perm = null;
12452                if (DEBUG_REMOVE && chatty) {
12453                    if (r == null) {
12454                        r = new StringBuilder(256);
12455                    } else {
12456                        r.append(' ');
12457                    }
12458                    r.append(p.info.name);
12459                }
12460            }
12461            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12462                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12463                if (appOpPkgs != null) {
12464                    appOpPkgs.remove(pkg.packageName);
12465                }
12466            }
12467        }
12468        if (r != null) {
12469            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12470        }
12471
12472        N = pkg.requestedPermissions.size();
12473        r = null;
12474        for (i=0; i<N; i++) {
12475            String perm = pkg.requestedPermissions.get(i);
12476            BasePermission bp = mSettings.mPermissions.get(perm);
12477            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12478                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12479                if (appOpPkgs != null) {
12480                    appOpPkgs.remove(pkg.packageName);
12481                    if (appOpPkgs.isEmpty()) {
12482                        mAppOpPermissionPackages.remove(perm);
12483                    }
12484                }
12485            }
12486        }
12487        if (r != null) {
12488            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12489        }
12490
12491        N = pkg.instrumentation.size();
12492        r = null;
12493        for (i=0; i<N; i++) {
12494            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12495            mInstrumentation.remove(a.getComponentName());
12496            if (DEBUG_REMOVE && chatty) {
12497                if (r == null) {
12498                    r = new StringBuilder(256);
12499                } else {
12500                    r.append(' ');
12501                }
12502                r.append(a.info.name);
12503            }
12504        }
12505        if (r != null) {
12506            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12507        }
12508
12509        r = null;
12510        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12511            // Only system apps can hold shared libraries.
12512            if (pkg.libraryNames != null) {
12513                for (i = 0; i < pkg.libraryNames.size(); i++) {
12514                    String name = pkg.libraryNames.get(i);
12515                    if (removeSharedLibraryLPw(name, 0)) {
12516                        if (DEBUG_REMOVE && chatty) {
12517                            if (r == null) {
12518                                r = new StringBuilder(256);
12519                            } else {
12520                                r.append(' ');
12521                            }
12522                            r.append(name);
12523                        }
12524                    }
12525                }
12526            }
12527        }
12528
12529        r = null;
12530
12531        // Any package can hold static shared libraries.
12532        if (pkg.staticSharedLibName != null) {
12533            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12534                if (DEBUG_REMOVE && chatty) {
12535                    if (r == null) {
12536                        r = new StringBuilder(256);
12537                    } else {
12538                        r.append(' ');
12539                    }
12540                    r.append(pkg.staticSharedLibName);
12541                }
12542            }
12543        }
12544
12545        if (r != null) {
12546            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12547        }
12548    }
12549
12550    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12551        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12552            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12553                return true;
12554            }
12555        }
12556        return false;
12557    }
12558
12559    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12560    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12561    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12562
12563    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12564        // Update the parent permissions
12565        updatePermissionsLPw(pkg.packageName, pkg, flags);
12566        // Update the child permissions
12567        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12568        for (int i = 0; i < childCount; i++) {
12569            PackageParser.Package childPkg = pkg.childPackages.get(i);
12570            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12571        }
12572    }
12573
12574    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12575            int flags) {
12576        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12577        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12578    }
12579
12580    private void updatePermissionsLPw(String changingPkg,
12581            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12582        // Make sure there are no dangling permission trees.
12583        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12584        while (it.hasNext()) {
12585            final BasePermission bp = it.next();
12586            if (bp.packageSetting == null) {
12587                // We may not yet have parsed the package, so just see if
12588                // we still know about its settings.
12589                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12590            }
12591            if (bp.packageSetting == null) {
12592                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12593                        + " from package " + bp.sourcePackage);
12594                it.remove();
12595            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12596                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12597                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12598                            + " from package " + bp.sourcePackage);
12599                    flags |= UPDATE_PERMISSIONS_ALL;
12600                    it.remove();
12601                }
12602            }
12603        }
12604
12605        // Make sure all dynamic permissions have been assigned to a package,
12606        // and make sure there are no dangling permissions.
12607        it = mSettings.mPermissions.values().iterator();
12608        while (it.hasNext()) {
12609            final BasePermission bp = it.next();
12610            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12611                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12612                        + bp.name + " pkg=" + bp.sourcePackage
12613                        + " info=" + bp.pendingInfo);
12614                if (bp.packageSetting == null && bp.pendingInfo != null) {
12615                    final BasePermission tree = findPermissionTreeLP(bp.name);
12616                    if (tree != null && tree.perm != null) {
12617                        bp.packageSetting = tree.packageSetting;
12618                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12619                                new PermissionInfo(bp.pendingInfo));
12620                        bp.perm.info.packageName = tree.perm.info.packageName;
12621                        bp.perm.info.name = bp.name;
12622                        bp.uid = tree.uid;
12623                    }
12624                }
12625            }
12626            if (bp.packageSetting == null) {
12627                // We may not yet have parsed the package, so just see if
12628                // we still know about its settings.
12629                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12630            }
12631            if (bp.packageSetting == null) {
12632                Slog.w(TAG, "Removing dangling permission: " + bp.name
12633                        + " from package " + bp.sourcePackage);
12634                it.remove();
12635            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12636                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12637                    Slog.i(TAG, "Removing old permission: " + bp.name
12638                            + " from package " + bp.sourcePackage);
12639                    flags |= UPDATE_PERMISSIONS_ALL;
12640                    it.remove();
12641                }
12642            }
12643        }
12644
12645        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12646        // Now update the permissions for all packages, in particular
12647        // replace the granted permissions of the system packages.
12648        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12649            for (PackageParser.Package pkg : mPackages.values()) {
12650                if (pkg != pkgInfo) {
12651                    // Only replace for packages on requested volume
12652                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12653                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12654                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12655                    grantPermissionsLPw(pkg, replace, changingPkg);
12656                }
12657            }
12658        }
12659
12660        if (pkgInfo != null) {
12661            // Only replace for packages on requested volume
12662            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12663            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12664                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12665            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12666        }
12667        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12668    }
12669
12670    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12671            String packageOfInterest) {
12672        // IMPORTANT: There are two types of permissions: install and runtime.
12673        // Install time permissions are granted when the app is installed to
12674        // all device users and users added in the future. Runtime permissions
12675        // are granted at runtime explicitly to specific users. Normal and signature
12676        // protected permissions are install time permissions. Dangerous permissions
12677        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12678        // otherwise they are runtime permissions. This function does not manage
12679        // runtime permissions except for the case an app targeting Lollipop MR1
12680        // being upgraded to target a newer SDK, in which case dangerous permissions
12681        // are transformed from install time to runtime ones.
12682
12683        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12684        if (ps == null) {
12685            return;
12686        }
12687
12688        PermissionsState permissionsState = ps.getPermissionsState();
12689        PermissionsState origPermissions = permissionsState;
12690
12691        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12692
12693        boolean runtimePermissionsRevoked = false;
12694        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12695
12696        boolean changedInstallPermission = false;
12697
12698        if (replace) {
12699            ps.installPermissionsFixed = false;
12700            if (!ps.isSharedUser()) {
12701                origPermissions = new PermissionsState(permissionsState);
12702                permissionsState.reset();
12703            } else {
12704                // We need to know only about runtime permission changes since the
12705                // calling code always writes the install permissions state but
12706                // the runtime ones are written only if changed. The only cases of
12707                // changed runtime permissions here are promotion of an install to
12708                // runtime and revocation of a runtime from a shared user.
12709                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12710                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12711                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12712                    runtimePermissionsRevoked = true;
12713                }
12714            }
12715        }
12716
12717        permissionsState.setGlobalGids(mGlobalGids);
12718
12719        final int N = pkg.requestedPermissions.size();
12720        for (int i=0; i<N; i++) {
12721            final String name = pkg.requestedPermissions.get(i);
12722            final BasePermission bp = mSettings.mPermissions.get(name);
12723            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12724                    >= Build.VERSION_CODES.M;
12725
12726            if (DEBUG_INSTALL) {
12727                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12728            }
12729
12730            if (bp == null || bp.packageSetting == null) {
12731                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12732                    if (DEBUG_PERMISSIONS) {
12733                        Slog.i(TAG, "Unknown permission " + name
12734                                + " in package " + pkg.packageName);
12735                    }
12736                }
12737                continue;
12738            }
12739
12740
12741            // Limit ephemeral apps to ephemeral allowed permissions.
12742            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12743                if (DEBUG_PERMISSIONS) {
12744                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
12745                            + pkg.packageName);
12746                }
12747                continue;
12748            }
12749
12750            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12751                if (DEBUG_PERMISSIONS) {
12752                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
12753                            + pkg.packageName);
12754                }
12755                continue;
12756            }
12757
12758            final String perm = bp.name;
12759            boolean allowedSig = false;
12760            int grant = GRANT_DENIED;
12761
12762            // Keep track of app op permissions.
12763            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12764                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12765                if (pkgs == null) {
12766                    pkgs = new ArraySet<>();
12767                    mAppOpPermissionPackages.put(bp.name, pkgs);
12768                }
12769                pkgs.add(pkg.packageName);
12770            }
12771
12772            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12773            switch (level) {
12774                case PermissionInfo.PROTECTION_NORMAL: {
12775                    // For all apps normal permissions are install time ones.
12776                    grant = GRANT_INSTALL;
12777                } break;
12778
12779                case PermissionInfo.PROTECTION_DANGEROUS: {
12780                    // If a permission review is required for legacy apps we represent
12781                    // their permissions as always granted runtime ones since we need
12782                    // to keep the review required permission flag per user while an
12783                    // install permission's state is shared across all users.
12784                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12785                        // For legacy apps dangerous permissions are install time ones.
12786                        grant = GRANT_INSTALL;
12787                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12788                        // For legacy apps that became modern, install becomes runtime.
12789                        grant = GRANT_UPGRADE;
12790                    } else if (mPromoteSystemApps
12791                            && isSystemApp(ps)
12792                            && mExistingSystemPackages.contains(ps.name)) {
12793                        // For legacy system apps, install becomes runtime.
12794                        // We cannot check hasInstallPermission() for system apps since those
12795                        // permissions were granted implicitly and not persisted pre-M.
12796                        grant = GRANT_UPGRADE;
12797                    } else {
12798                        // For modern apps keep runtime permissions unchanged.
12799                        grant = GRANT_RUNTIME;
12800                    }
12801                } break;
12802
12803                case PermissionInfo.PROTECTION_SIGNATURE: {
12804                    // For all apps signature permissions are install time ones.
12805                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12806                    if (allowedSig) {
12807                        grant = GRANT_INSTALL;
12808                    }
12809                } break;
12810            }
12811
12812            if (DEBUG_PERMISSIONS) {
12813                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12814            }
12815
12816            if (grant != GRANT_DENIED) {
12817                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12818                    // If this is an existing, non-system package, then
12819                    // we can't add any new permissions to it.
12820                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12821                        // Except...  if this is a permission that was added
12822                        // to the platform (note: need to only do this when
12823                        // updating the platform).
12824                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12825                            grant = GRANT_DENIED;
12826                        }
12827                    }
12828                }
12829
12830                switch (grant) {
12831                    case GRANT_INSTALL: {
12832                        // Revoke this as runtime permission to handle the case of
12833                        // a runtime permission being downgraded to an install one.
12834                        // Also in permission review mode we keep dangerous permissions
12835                        // for legacy apps
12836                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12837                            if (origPermissions.getRuntimePermissionState(
12838                                    bp.name, userId) != null) {
12839                                // Revoke the runtime permission and clear the flags.
12840                                origPermissions.revokeRuntimePermission(bp, userId);
12841                                origPermissions.updatePermissionFlags(bp, userId,
12842                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12843                                // If we revoked a permission permission, we have to write.
12844                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12845                                        changedRuntimePermissionUserIds, userId);
12846                            }
12847                        }
12848                        // Grant an install permission.
12849                        if (permissionsState.grantInstallPermission(bp) !=
12850                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12851                            changedInstallPermission = true;
12852                        }
12853                    } break;
12854
12855                    case GRANT_RUNTIME: {
12856                        // Grant previously granted runtime permissions.
12857                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12858                            PermissionState permissionState = origPermissions
12859                                    .getRuntimePermissionState(bp.name, userId);
12860                            int flags = permissionState != null
12861                                    ? permissionState.getFlags() : 0;
12862                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12863                                // Don't propagate the permission in a permission review mode if
12864                                // the former was revoked, i.e. marked to not propagate on upgrade.
12865                                // Note that in a permission review mode install permissions are
12866                                // represented as constantly granted runtime ones since we need to
12867                                // keep a per user state associated with the permission. Also the
12868                                // revoke on upgrade flag is no longer applicable and is reset.
12869                                final boolean revokeOnUpgrade = (flags & PackageManager
12870                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12871                                if (revokeOnUpgrade) {
12872                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12873                                    // Since we changed the flags, we have to write.
12874                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12875                                            changedRuntimePermissionUserIds, userId);
12876                                }
12877                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12878                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12879                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12880                                        // If we cannot put the permission as it was,
12881                                        // we have to write.
12882                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12883                                                changedRuntimePermissionUserIds, userId);
12884                                    }
12885                                }
12886
12887                                // If the app supports runtime permissions no need for a review.
12888                                if (mPermissionReviewRequired
12889                                        && appSupportsRuntimePermissions
12890                                        && (flags & PackageManager
12891                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12892                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12893                                    // Since we changed the flags, we have to write.
12894                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12895                                            changedRuntimePermissionUserIds, userId);
12896                                }
12897                            } else if (mPermissionReviewRequired
12898                                    && !appSupportsRuntimePermissions) {
12899                                // For legacy apps that need a permission review, every new
12900                                // runtime permission is granted but it is pending a review.
12901                                // We also need to review only platform defined runtime
12902                                // permissions as these are the only ones the platform knows
12903                                // how to disable the API to simulate revocation as legacy
12904                                // apps don't expect to run with revoked permissions.
12905                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12906                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12907                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12908                                        // We changed the flags, hence have to write.
12909                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12910                                                changedRuntimePermissionUserIds, userId);
12911                                    }
12912                                }
12913                                if (permissionsState.grantRuntimePermission(bp, userId)
12914                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12915                                    // We changed the permission, hence have to write.
12916                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12917                                            changedRuntimePermissionUserIds, userId);
12918                                }
12919                            }
12920                            // Propagate the permission flags.
12921                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12922                        }
12923                    } break;
12924
12925                    case GRANT_UPGRADE: {
12926                        // Grant runtime permissions for a previously held install permission.
12927                        PermissionState permissionState = origPermissions
12928                                .getInstallPermissionState(bp.name);
12929                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12930
12931                        if (origPermissions.revokeInstallPermission(bp)
12932                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12933                            // We will be transferring the permission flags, so clear them.
12934                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12935                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12936                            changedInstallPermission = true;
12937                        }
12938
12939                        // If the permission is not to be promoted to runtime we ignore it and
12940                        // also its other flags as they are not applicable to install permissions.
12941                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12942                            for (int userId : currentUserIds) {
12943                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12944                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12945                                    // Transfer the permission flags.
12946                                    permissionsState.updatePermissionFlags(bp, userId,
12947                                            flags, flags);
12948                                    // If we granted the permission, we have to write.
12949                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12950                                            changedRuntimePermissionUserIds, userId);
12951                                }
12952                            }
12953                        }
12954                    } break;
12955
12956                    default: {
12957                        if (packageOfInterest == null
12958                                || packageOfInterest.equals(pkg.packageName)) {
12959                            if (DEBUG_PERMISSIONS) {
12960                                Slog.i(TAG, "Not granting permission " + perm
12961                                        + " to package " + pkg.packageName
12962                                        + " because it was previously installed without");
12963                            }
12964                        }
12965                    } break;
12966                }
12967            } else {
12968                if (permissionsState.revokeInstallPermission(bp) !=
12969                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12970                    // Also drop the permission flags.
12971                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12972                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12973                    changedInstallPermission = true;
12974                    Slog.i(TAG, "Un-granting permission " + perm
12975                            + " from package " + pkg.packageName
12976                            + " (protectionLevel=" + bp.protectionLevel
12977                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12978                            + ")");
12979                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12980                    // Don't print warning for app op permissions, since it is fine for them
12981                    // not to be granted, there is a UI for the user to decide.
12982                    if (DEBUG_PERMISSIONS
12983                            && (packageOfInterest == null
12984                                    || packageOfInterest.equals(pkg.packageName))) {
12985                        Slog.i(TAG, "Not granting permission " + perm
12986                                + " to package " + pkg.packageName
12987                                + " (protectionLevel=" + bp.protectionLevel
12988                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12989                                + ")");
12990                    }
12991                }
12992            }
12993        }
12994
12995        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12996                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12997            // This is the first that we have heard about this package, so the
12998            // permissions we have now selected are fixed until explicitly
12999            // changed.
13000            ps.installPermissionsFixed = true;
13001        }
13002
13003        // Persist the runtime permissions state for users with changes. If permissions
13004        // were revoked because no app in the shared user declares them we have to
13005        // write synchronously to avoid losing runtime permissions state.
13006        for (int userId : changedRuntimePermissionUserIds) {
13007            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13008        }
13009    }
13010
13011    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13012        boolean allowed = false;
13013        final int NP = PackageParser.NEW_PERMISSIONS.length;
13014        for (int ip=0; ip<NP; ip++) {
13015            final PackageParser.NewPermissionInfo npi
13016                    = PackageParser.NEW_PERMISSIONS[ip];
13017            if (npi.name.equals(perm)
13018                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13019                allowed = true;
13020                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13021                        + pkg.packageName);
13022                break;
13023            }
13024        }
13025        return allowed;
13026    }
13027
13028    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13029            BasePermission bp, PermissionsState origPermissions) {
13030        boolean privilegedPermission = (bp.protectionLevel
13031                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13032        boolean privappPermissionsDisable =
13033                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13034        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13035        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13036        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13037                && !platformPackage && platformPermission) {
13038            ArraySet<String> wlPermissions = SystemConfig.getInstance()
13039                    .getPrivAppPermissions(pkg.packageName);
13040            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
13041            if (!whitelisted) {
13042                Slog.w(TAG, "Privileged permission " + perm + " for package "
13043                        + pkg.packageName + " - not in privapp-permissions whitelist");
13044                // Only report violations for apps on system image
13045                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13046                    if (mPrivappPermissionsViolations == null) {
13047                        mPrivappPermissionsViolations = new ArraySet<>();
13048                    }
13049                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13050                }
13051                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13052                    return false;
13053                }
13054            }
13055        }
13056        boolean allowed = (compareSignatures(
13057                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13058                        == PackageManager.SIGNATURE_MATCH)
13059                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13060                        == PackageManager.SIGNATURE_MATCH);
13061        if (!allowed && privilegedPermission) {
13062            if (isSystemApp(pkg)) {
13063                // For updated system applications, a system permission
13064                // is granted only if it had been defined by the original application.
13065                if (pkg.isUpdatedSystemApp()) {
13066                    final PackageSetting sysPs = mSettings
13067                            .getDisabledSystemPkgLPr(pkg.packageName);
13068                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13069                        // If the original was granted this permission, we take
13070                        // that grant decision as read and propagate it to the
13071                        // update.
13072                        if (sysPs.isPrivileged()) {
13073                            allowed = true;
13074                        }
13075                    } else {
13076                        // The system apk may have been updated with an older
13077                        // version of the one on the data partition, but which
13078                        // granted a new system permission that it didn't have
13079                        // before.  In this case we do want to allow the app to
13080                        // now get the new permission if the ancestral apk is
13081                        // privileged to get it.
13082                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13083                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13084                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13085                                    allowed = true;
13086                                    break;
13087                                }
13088                            }
13089                        }
13090                        // Also if a privileged parent package on the system image or any of
13091                        // its children requested a privileged permission, the updated child
13092                        // packages can also get the permission.
13093                        if (pkg.parentPackage != null) {
13094                            final PackageSetting disabledSysParentPs = mSettings
13095                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13096                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13097                                    && disabledSysParentPs.isPrivileged()) {
13098                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13099                                    allowed = true;
13100                                } else if (disabledSysParentPs.pkg.childPackages != null) {
13101                                    final int count = disabledSysParentPs.pkg.childPackages.size();
13102                                    for (int i = 0; i < count; i++) {
13103                                        PackageParser.Package disabledSysChildPkg =
13104                                                disabledSysParentPs.pkg.childPackages.get(i);
13105                                        if (isPackageRequestingPermission(disabledSysChildPkg,
13106                                                perm)) {
13107                                            allowed = true;
13108                                            break;
13109                                        }
13110                                    }
13111                                }
13112                            }
13113                        }
13114                    }
13115                } else {
13116                    allowed = isPrivilegedApp(pkg);
13117                }
13118            }
13119        }
13120        if (!allowed) {
13121            if (!allowed && (bp.protectionLevel
13122                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13123                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13124                // If this was a previously normal/dangerous permission that got moved
13125                // to a system permission as part of the runtime permission redesign, then
13126                // we still want to blindly grant it to old apps.
13127                allowed = true;
13128            }
13129            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13130                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
13131                // If this permission is to be granted to the system installer and
13132                // this app is an installer, then it gets the permission.
13133                allowed = true;
13134            }
13135            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13136                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
13137                // If this permission is to be granted to the system verifier and
13138                // this app is a verifier, then it gets the permission.
13139                allowed = true;
13140            }
13141            if (!allowed && (bp.protectionLevel
13142                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13143                    && isSystemApp(pkg)) {
13144                // Any pre-installed system app is allowed to get this permission.
13145                allowed = true;
13146            }
13147            if (!allowed && (bp.protectionLevel
13148                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13149                // For development permissions, a development permission
13150                // is granted only if it was already granted.
13151                allowed = origPermissions.hasInstallPermission(perm);
13152            }
13153            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13154                    && pkg.packageName.equals(mSetupWizardPackage)) {
13155                // If this permission is to be granted to the system setup wizard and
13156                // this app is a setup wizard, then it gets the permission.
13157                allowed = true;
13158            }
13159        }
13160        return allowed;
13161    }
13162
13163    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13164        final int permCount = pkg.requestedPermissions.size();
13165        for (int j = 0; j < permCount; j++) {
13166            String requestedPermission = pkg.requestedPermissions.get(j);
13167            if (permission.equals(requestedPermission)) {
13168                return true;
13169            }
13170        }
13171        return false;
13172    }
13173
13174    final class ActivityIntentResolver
13175            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13176        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13177                boolean defaultOnly, int userId) {
13178            if (!sUserManager.exists(userId)) return null;
13179            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13180            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13181        }
13182
13183        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13184                int userId) {
13185            if (!sUserManager.exists(userId)) return null;
13186            mFlags = flags;
13187            return super.queryIntent(intent, resolvedType,
13188                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13189                    userId);
13190        }
13191
13192        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13193                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13194            if (!sUserManager.exists(userId)) return null;
13195            if (packageActivities == null) {
13196                return null;
13197            }
13198            mFlags = flags;
13199            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13200            final int N = packageActivities.size();
13201            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13202                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13203
13204            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13205            for (int i = 0; i < N; ++i) {
13206                intentFilters = packageActivities.get(i).intents;
13207                if (intentFilters != null && intentFilters.size() > 0) {
13208                    PackageParser.ActivityIntentInfo[] array =
13209                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
13210                    intentFilters.toArray(array);
13211                    listCut.add(array);
13212                }
13213            }
13214            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13215        }
13216
13217        /**
13218         * Finds a privileged activity that matches the specified activity names.
13219         */
13220        private PackageParser.Activity findMatchingActivity(
13221                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13222            for (PackageParser.Activity sysActivity : activityList) {
13223                if (sysActivity.info.name.equals(activityInfo.name)) {
13224                    return sysActivity;
13225                }
13226                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13227                    return sysActivity;
13228                }
13229                if (sysActivity.info.targetActivity != null) {
13230                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13231                        return sysActivity;
13232                    }
13233                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13234                        return sysActivity;
13235                    }
13236                }
13237            }
13238            return null;
13239        }
13240
13241        public class IterGenerator<E> {
13242            public Iterator<E> generate(ActivityIntentInfo info) {
13243                return null;
13244            }
13245        }
13246
13247        public class ActionIterGenerator extends IterGenerator<String> {
13248            @Override
13249            public Iterator<String> generate(ActivityIntentInfo info) {
13250                return info.actionsIterator();
13251            }
13252        }
13253
13254        public class CategoriesIterGenerator extends IterGenerator<String> {
13255            @Override
13256            public Iterator<String> generate(ActivityIntentInfo info) {
13257                return info.categoriesIterator();
13258            }
13259        }
13260
13261        public class SchemesIterGenerator extends IterGenerator<String> {
13262            @Override
13263            public Iterator<String> generate(ActivityIntentInfo info) {
13264                return info.schemesIterator();
13265            }
13266        }
13267
13268        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13269            @Override
13270            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13271                return info.authoritiesIterator();
13272            }
13273        }
13274
13275        /**
13276         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13277         * MODIFIED. Do not pass in a list that should not be changed.
13278         */
13279        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13280                IterGenerator<T> generator, Iterator<T> searchIterator) {
13281            // loop through the set of actions; every one must be found in the intent filter
13282            while (searchIterator.hasNext()) {
13283                // we must have at least one filter in the list to consider a match
13284                if (intentList.size() == 0) {
13285                    break;
13286                }
13287
13288                final T searchAction = searchIterator.next();
13289
13290                // loop through the set of intent filters
13291                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13292                while (intentIter.hasNext()) {
13293                    final ActivityIntentInfo intentInfo = intentIter.next();
13294                    boolean selectionFound = false;
13295
13296                    // loop through the intent filter's selection criteria; at least one
13297                    // of them must match the searched criteria
13298                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13299                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13300                        final T intentSelection = intentSelectionIter.next();
13301                        if (intentSelection != null && intentSelection.equals(searchAction)) {
13302                            selectionFound = true;
13303                            break;
13304                        }
13305                    }
13306
13307                    // the selection criteria wasn't found in this filter's set; this filter
13308                    // is not a potential match
13309                    if (!selectionFound) {
13310                        intentIter.remove();
13311                    }
13312                }
13313            }
13314        }
13315
13316        private boolean isProtectedAction(ActivityIntentInfo filter) {
13317            final Iterator<String> actionsIter = filter.actionsIterator();
13318            while (actionsIter != null && actionsIter.hasNext()) {
13319                final String filterAction = actionsIter.next();
13320                if (PROTECTED_ACTIONS.contains(filterAction)) {
13321                    return true;
13322                }
13323            }
13324            return false;
13325        }
13326
13327        /**
13328         * Adjusts the priority of the given intent filter according to policy.
13329         * <p>
13330         * <ul>
13331         * <li>The priority for non privileged applications is capped to '0'</li>
13332         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13333         * <li>The priority for unbundled updates to privileged applications is capped to the
13334         *      priority defined on the system partition</li>
13335         * </ul>
13336         * <p>
13337         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13338         * allowed to obtain any priority on any action.
13339         */
13340        private void adjustPriority(
13341                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13342            // nothing to do; priority is fine as-is
13343            if (intent.getPriority() <= 0) {
13344                return;
13345            }
13346
13347            final ActivityInfo activityInfo = intent.activity.info;
13348            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13349
13350            final boolean privilegedApp =
13351                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13352            if (!privilegedApp) {
13353                // non-privileged applications can never define a priority >0
13354                if (DEBUG_FILTERS) {
13355                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13356                            + " package: " + applicationInfo.packageName
13357                            + " activity: " + intent.activity.className
13358                            + " origPrio: " + intent.getPriority());
13359                }
13360                intent.setPriority(0);
13361                return;
13362            }
13363
13364            if (systemActivities == null) {
13365                // the system package is not disabled; we're parsing the system partition
13366                if (isProtectedAction(intent)) {
13367                    if (mDeferProtectedFilters) {
13368                        // We can't deal with these just yet. No component should ever obtain a
13369                        // >0 priority for a protected actions, with ONE exception -- the setup
13370                        // wizard. The setup wizard, however, cannot be known until we're able to
13371                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13372                        // until all intent filters have been processed. Chicken, meet egg.
13373                        // Let the filter temporarily have a high priority and rectify the
13374                        // priorities after all system packages have been scanned.
13375                        mProtectedFilters.add(intent);
13376                        if (DEBUG_FILTERS) {
13377                            Slog.i(TAG, "Protected action; save for later;"
13378                                    + " package: " + applicationInfo.packageName
13379                                    + " activity: " + intent.activity.className
13380                                    + " origPrio: " + intent.getPriority());
13381                        }
13382                        return;
13383                    } else {
13384                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13385                            Slog.i(TAG, "No setup wizard;"
13386                                + " All protected intents capped to priority 0");
13387                        }
13388                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13389                            if (DEBUG_FILTERS) {
13390                                Slog.i(TAG, "Found setup wizard;"
13391                                    + " allow priority " + intent.getPriority() + ";"
13392                                    + " package: " + intent.activity.info.packageName
13393                                    + " activity: " + intent.activity.className
13394                                    + " priority: " + intent.getPriority());
13395                            }
13396                            // setup wizard gets whatever it wants
13397                            return;
13398                        }
13399                        if (DEBUG_FILTERS) {
13400                            Slog.i(TAG, "Protected action; cap priority to 0;"
13401                                    + " package: " + intent.activity.info.packageName
13402                                    + " activity: " + intent.activity.className
13403                                    + " origPrio: " + intent.getPriority());
13404                        }
13405                        intent.setPriority(0);
13406                        return;
13407                    }
13408                }
13409                // privileged apps on the system image get whatever priority they request
13410                return;
13411            }
13412
13413            // privileged app unbundled update ... try to find the same activity
13414            final PackageParser.Activity foundActivity =
13415                    findMatchingActivity(systemActivities, activityInfo);
13416            if (foundActivity == null) {
13417                // this is a new activity; it cannot obtain >0 priority
13418                if (DEBUG_FILTERS) {
13419                    Slog.i(TAG, "New activity; cap priority to 0;"
13420                            + " package: " + applicationInfo.packageName
13421                            + " activity: " + intent.activity.className
13422                            + " origPrio: " + intent.getPriority());
13423                }
13424                intent.setPriority(0);
13425                return;
13426            }
13427
13428            // found activity, now check for filter equivalence
13429
13430            // a shallow copy is enough; we modify the list, not its contents
13431            final List<ActivityIntentInfo> intentListCopy =
13432                    new ArrayList<>(foundActivity.intents);
13433            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13434
13435            // find matching action subsets
13436            final Iterator<String> actionsIterator = intent.actionsIterator();
13437            if (actionsIterator != null) {
13438                getIntentListSubset(
13439                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13440                if (intentListCopy.size() == 0) {
13441                    // no more intents to match; we're not equivalent
13442                    if (DEBUG_FILTERS) {
13443                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13444                                + " package: " + applicationInfo.packageName
13445                                + " activity: " + intent.activity.className
13446                                + " origPrio: " + intent.getPriority());
13447                    }
13448                    intent.setPriority(0);
13449                    return;
13450                }
13451            }
13452
13453            // find matching category subsets
13454            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13455            if (categoriesIterator != null) {
13456                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13457                        categoriesIterator);
13458                if (intentListCopy.size() == 0) {
13459                    // no more intents to match; we're not equivalent
13460                    if (DEBUG_FILTERS) {
13461                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13462                                + " package: " + applicationInfo.packageName
13463                                + " activity: " + intent.activity.className
13464                                + " origPrio: " + intent.getPriority());
13465                    }
13466                    intent.setPriority(0);
13467                    return;
13468                }
13469            }
13470
13471            // find matching schemes subsets
13472            final Iterator<String> schemesIterator = intent.schemesIterator();
13473            if (schemesIterator != null) {
13474                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13475                        schemesIterator);
13476                if (intentListCopy.size() == 0) {
13477                    // no more intents to match; we're not equivalent
13478                    if (DEBUG_FILTERS) {
13479                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13480                                + " package: " + applicationInfo.packageName
13481                                + " activity: " + intent.activity.className
13482                                + " origPrio: " + intent.getPriority());
13483                    }
13484                    intent.setPriority(0);
13485                    return;
13486                }
13487            }
13488
13489            // find matching authorities subsets
13490            final Iterator<IntentFilter.AuthorityEntry>
13491                    authoritiesIterator = intent.authoritiesIterator();
13492            if (authoritiesIterator != null) {
13493                getIntentListSubset(intentListCopy,
13494                        new AuthoritiesIterGenerator(),
13495                        authoritiesIterator);
13496                if (intentListCopy.size() == 0) {
13497                    // no more intents to match; we're not equivalent
13498                    if (DEBUG_FILTERS) {
13499                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13500                                + " package: " + applicationInfo.packageName
13501                                + " activity: " + intent.activity.className
13502                                + " origPrio: " + intent.getPriority());
13503                    }
13504                    intent.setPriority(0);
13505                    return;
13506                }
13507            }
13508
13509            // we found matching filter(s); app gets the max priority of all intents
13510            int cappedPriority = 0;
13511            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13512                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13513            }
13514            if (intent.getPriority() > cappedPriority) {
13515                if (DEBUG_FILTERS) {
13516                    Slog.i(TAG, "Found matching filter(s);"
13517                            + " cap priority to " + cappedPriority + ";"
13518                            + " package: " + applicationInfo.packageName
13519                            + " activity: " + intent.activity.className
13520                            + " origPrio: " + intent.getPriority());
13521                }
13522                intent.setPriority(cappedPriority);
13523                return;
13524            }
13525            // all this for nothing; the requested priority was <= what was on the system
13526        }
13527
13528        public final void addActivity(PackageParser.Activity a, String type) {
13529            mActivities.put(a.getComponentName(), a);
13530            if (DEBUG_SHOW_INFO)
13531                Log.v(
13532                TAG, "  " + type + " " +
13533                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13534            if (DEBUG_SHOW_INFO)
13535                Log.v(TAG, "    Class=" + a.info.name);
13536            final int NI = a.intents.size();
13537            for (int j=0; j<NI; j++) {
13538                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13539                if ("activity".equals(type)) {
13540                    final PackageSetting ps =
13541                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13542                    final List<PackageParser.Activity> systemActivities =
13543                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13544                    adjustPriority(systemActivities, intent);
13545                }
13546                if (DEBUG_SHOW_INFO) {
13547                    Log.v(TAG, "    IntentFilter:");
13548                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13549                }
13550                if (!intent.debugCheck()) {
13551                    Log.w(TAG, "==> For Activity " + a.info.name);
13552                }
13553                addFilter(intent);
13554            }
13555        }
13556
13557        public final void removeActivity(PackageParser.Activity a, String type) {
13558            mActivities.remove(a.getComponentName());
13559            if (DEBUG_SHOW_INFO) {
13560                Log.v(TAG, "  " + type + " "
13561                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13562                                : a.info.name) + ":");
13563                Log.v(TAG, "    Class=" + a.info.name);
13564            }
13565            final int NI = a.intents.size();
13566            for (int j=0; j<NI; j++) {
13567                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13568                if (DEBUG_SHOW_INFO) {
13569                    Log.v(TAG, "    IntentFilter:");
13570                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13571                }
13572                removeFilter(intent);
13573            }
13574        }
13575
13576        @Override
13577        protected boolean allowFilterResult(
13578                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13579            ActivityInfo filterAi = filter.activity.info;
13580            for (int i=dest.size()-1; i>=0; i--) {
13581                ActivityInfo destAi = dest.get(i).activityInfo;
13582                if (destAi.name == filterAi.name
13583                        && destAi.packageName == filterAi.packageName) {
13584                    return false;
13585                }
13586            }
13587            return true;
13588        }
13589
13590        @Override
13591        protected ActivityIntentInfo[] newArray(int size) {
13592            return new ActivityIntentInfo[size];
13593        }
13594
13595        @Override
13596        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13597            if (!sUserManager.exists(userId)) return true;
13598            PackageParser.Package p = filter.activity.owner;
13599            if (p != null) {
13600                PackageSetting ps = (PackageSetting)p.mExtras;
13601                if (ps != null) {
13602                    // System apps are never considered stopped for purposes of
13603                    // filtering, because there may be no way for the user to
13604                    // actually re-launch them.
13605                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13606                            && ps.getStopped(userId);
13607                }
13608            }
13609            return false;
13610        }
13611
13612        @Override
13613        protected boolean isPackageForFilter(String packageName,
13614                PackageParser.ActivityIntentInfo info) {
13615            return packageName.equals(info.activity.owner.packageName);
13616        }
13617
13618        @Override
13619        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13620                int match, int userId) {
13621            if (!sUserManager.exists(userId)) return null;
13622            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13623                return null;
13624            }
13625            final PackageParser.Activity activity = info.activity;
13626            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13627            if (ps == null) {
13628                return null;
13629            }
13630            final PackageUserState userState = ps.readUserState(userId);
13631            ActivityInfo ai =
13632                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13633            if (ai == null) {
13634                return null;
13635            }
13636            final boolean matchExplicitlyVisibleOnly =
13637                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13638            final boolean matchVisibleToInstantApp =
13639                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13640            final boolean componentVisible =
13641                    matchVisibleToInstantApp
13642                    && info.isVisibleToInstantApp()
13643                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13644            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13645            // throw out filters that aren't visible to ephemeral apps
13646            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13647                return null;
13648            }
13649            // throw out instant app filters if we're not explicitly requesting them
13650            if (!matchInstantApp && userState.instantApp) {
13651                return null;
13652            }
13653            // throw out instant app filters if updates are available; will trigger
13654            // instant app resolution
13655            if (userState.instantApp && ps.isUpdateAvailable()) {
13656                return null;
13657            }
13658            final ResolveInfo res = new ResolveInfo();
13659            res.activityInfo = ai;
13660            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13661                res.filter = info;
13662            }
13663            if (info != null) {
13664                res.handleAllWebDataURI = info.handleAllWebDataURI();
13665            }
13666            res.priority = info.getPriority();
13667            res.preferredOrder = activity.owner.mPreferredOrder;
13668            //System.out.println("Result: " + res.activityInfo.className +
13669            //                   " = " + res.priority);
13670            res.match = match;
13671            res.isDefault = info.hasDefault;
13672            res.labelRes = info.labelRes;
13673            res.nonLocalizedLabel = info.nonLocalizedLabel;
13674            if (userNeedsBadging(userId)) {
13675                res.noResourceId = true;
13676            } else {
13677                res.icon = info.icon;
13678            }
13679            res.iconResourceId = info.icon;
13680            res.system = res.activityInfo.applicationInfo.isSystemApp();
13681            res.isInstantAppAvailable = userState.instantApp;
13682            return res;
13683        }
13684
13685        @Override
13686        protected void sortResults(List<ResolveInfo> results) {
13687            Collections.sort(results, mResolvePrioritySorter);
13688        }
13689
13690        @Override
13691        protected void dumpFilter(PrintWriter out, String prefix,
13692                PackageParser.ActivityIntentInfo filter) {
13693            out.print(prefix); out.print(
13694                    Integer.toHexString(System.identityHashCode(filter.activity)));
13695                    out.print(' ');
13696                    filter.activity.printComponentShortName(out);
13697                    out.print(" filter ");
13698                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13699        }
13700
13701        @Override
13702        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13703            return filter.activity;
13704        }
13705
13706        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13707            PackageParser.Activity activity = (PackageParser.Activity)label;
13708            out.print(prefix); out.print(
13709                    Integer.toHexString(System.identityHashCode(activity)));
13710                    out.print(' ');
13711                    activity.printComponentShortName(out);
13712            if (count > 1) {
13713                out.print(" ("); out.print(count); out.print(" filters)");
13714            }
13715            out.println();
13716        }
13717
13718        // Keys are String (activity class name), values are Activity.
13719        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13720                = new ArrayMap<ComponentName, PackageParser.Activity>();
13721        private int mFlags;
13722    }
13723
13724    private final class ServiceIntentResolver
13725            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13726        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13727                boolean defaultOnly, int userId) {
13728            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13729            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13730        }
13731
13732        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13733                int userId) {
13734            if (!sUserManager.exists(userId)) return null;
13735            mFlags = flags;
13736            return super.queryIntent(intent, resolvedType,
13737                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13738                    userId);
13739        }
13740
13741        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13742                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13743            if (!sUserManager.exists(userId)) return null;
13744            if (packageServices == null) {
13745                return null;
13746            }
13747            mFlags = flags;
13748            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13749            final int N = packageServices.size();
13750            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13751                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13752
13753            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13754            for (int i = 0; i < N; ++i) {
13755                intentFilters = packageServices.get(i).intents;
13756                if (intentFilters != null && intentFilters.size() > 0) {
13757                    PackageParser.ServiceIntentInfo[] array =
13758                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13759                    intentFilters.toArray(array);
13760                    listCut.add(array);
13761                }
13762            }
13763            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13764        }
13765
13766        public final void addService(PackageParser.Service s) {
13767            mServices.put(s.getComponentName(), s);
13768            if (DEBUG_SHOW_INFO) {
13769                Log.v(TAG, "  "
13770                        + (s.info.nonLocalizedLabel != null
13771                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13772                Log.v(TAG, "    Class=" + s.info.name);
13773            }
13774            final int NI = s.intents.size();
13775            int j;
13776            for (j=0; j<NI; j++) {
13777                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13778                if (DEBUG_SHOW_INFO) {
13779                    Log.v(TAG, "    IntentFilter:");
13780                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13781                }
13782                if (!intent.debugCheck()) {
13783                    Log.w(TAG, "==> For Service " + s.info.name);
13784                }
13785                addFilter(intent);
13786            }
13787        }
13788
13789        public final void removeService(PackageParser.Service s) {
13790            mServices.remove(s.getComponentName());
13791            if (DEBUG_SHOW_INFO) {
13792                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13793                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13794                Log.v(TAG, "    Class=" + s.info.name);
13795            }
13796            final int NI = s.intents.size();
13797            int j;
13798            for (j=0; j<NI; j++) {
13799                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13800                if (DEBUG_SHOW_INFO) {
13801                    Log.v(TAG, "    IntentFilter:");
13802                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13803                }
13804                removeFilter(intent);
13805            }
13806        }
13807
13808        @Override
13809        protected boolean allowFilterResult(
13810                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13811            ServiceInfo filterSi = filter.service.info;
13812            for (int i=dest.size()-1; i>=0; i--) {
13813                ServiceInfo destAi = dest.get(i).serviceInfo;
13814                if (destAi.name == filterSi.name
13815                        && destAi.packageName == filterSi.packageName) {
13816                    return false;
13817                }
13818            }
13819            return true;
13820        }
13821
13822        @Override
13823        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13824            return new PackageParser.ServiceIntentInfo[size];
13825        }
13826
13827        @Override
13828        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13829            if (!sUserManager.exists(userId)) return true;
13830            PackageParser.Package p = filter.service.owner;
13831            if (p != null) {
13832                PackageSetting ps = (PackageSetting)p.mExtras;
13833                if (ps != null) {
13834                    // System apps are never considered stopped for purposes of
13835                    // filtering, because there may be no way for the user to
13836                    // actually re-launch them.
13837                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13838                            && ps.getStopped(userId);
13839                }
13840            }
13841            return false;
13842        }
13843
13844        @Override
13845        protected boolean isPackageForFilter(String packageName,
13846                PackageParser.ServiceIntentInfo info) {
13847            return packageName.equals(info.service.owner.packageName);
13848        }
13849
13850        @Override
13851        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13852                int match, int userId) {
13853            if (!sUserManager.exists(userId)) return null;
13854            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13855            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13856                return null;
13857            }
13858            final PackageParser.Service service = info.service;
13859            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13860            if (ps == null) {
13861                return null;
13862            }
13863            final PackageUserState userState = ps.readUserState(userId);
13864            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13865                    userState, userId);
13866            if (si == null) {
13867                return null;
13868            }
13869            final boolean matchVisibleToInstantApp =
13870                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13871            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13872            // throw out filters that aren't visible to ephemeral apps
13873            if (matchVisibleToInstantApp
13874                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13875                return null;
13876            }
13877            // throw out ephemeral filters if we're not explicitly requesting them
13878            if (!isInstantApp && userState.instantApp) {
13879                return null;
13880            }
13881            // throw out instant app filters if updates are available; will trigger
13882            // instant app resolution
13883            if (userState.instantApp && ps.isUpdateAvailable()) {
13884                return null;
13885            }
13886            final ResolveInfo res = new ResolveInfo();
13887            res.serviceInfo = si;
13888            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13889                res.filter = filter;
13890            }
13891            res.priority = info.getPriority();
13892            res.preferredOrder = service.owner.mPreferredOrder;
13893            res.match = match;
13894            res.isDefault = info.hasDefault;
13895            res.labelRes = info.labelRes;
13896            res.nonLocalizedLabel = info.nonLocalizedLabel;
13897            res.icon = info.icon;
13898            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13899            return res;
13900        }
13901
13902        @Override
13903        protected void sortResults(List<ResolveInfo> results) {
13904            Collections.sort(results, mResolvePrioritySorter);
13905        }
13906
13907        @Override
13908        protected void dumpFilter(PrintWriter out, String prefix,
13909                PackageParser.ServiceIntentInfo filter) {
13910            out.print(prefix); out.print(
13911                    Integer.toHexString(System.identityHashCode(filter.service)));
13912                    out.print(' ');
13913                    filter.service.printComponentShortName(out);
13914                    out.print(" filter ");
13915                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13916        }
13917
13918        @Override
13919        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13920            return filter.service;
13921        }
13922
13923        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13924            PackageParser.Service service = (PackageParser.Service)label;
13925            out.print(prefix); out.print(
13926                    Integer.toHexString(System.identityHashCode(service)));
13927                    out.print(' ');
13928                    service.printComponentShortName(out);
13929            if (count > 1) {
13930                out.print(" ("); out.print(count); out.print(" filters)");
13931            }
13932            out.println();
13933        }
13934
13935//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13936//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13937//            final List<ResolveInfo> retList = Lists.newArrayList();
13938//            while (i.hasNext()) {
13939//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13940//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13941//                    retList.add(resolveInfo);
13942//                }
13943//            }
13944//            return retList;
13945//        }
13946
13947        // Keys are String (activity class name), values are Activity.
13948        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13949                = new ArrayMap<ComponentName, PackageParser.Service>();
13950        private int mFlags;
13951    }
13952
13953    private final class ProviderIntentResolver
13954            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13955        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13956                boolean defaultOnly, int userId) {
13957            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13958            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13959        }
13960
13961        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13962                int userId) {
13963            if (!sUserManager.exists(userId))
13964                return null;
13965            mFlags = flags;
13966            return super.queryIntent(intent, resolvedType,
13967                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13968                    userId);
13969        }
13970
13971        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13972                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13973            if (!sUserManager.exists(userId))
13974                return null;
13975            if (packageProviders == null) {
13976                return null;
13977            }
13978            mFlags = flags;
13979            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13980            final int N = packageProviders.size();
13981            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13982                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13983
13984            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13985            for (int i = 0; i < N; ++i) {
13986                intentFilters = packageProviders.get(i).intents;
13987                if (intentFilters != null && intentFilters.size() > 0) {
13988                    PackageParser.ProviderIntentInfo[] array =
13989                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13990                    intentFilters.toArray(array);
13991                    listCut.add(array);
13992                }
13993            }
13994            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13995        }
13996
13997        public final void addProvider(PackageParser.Provider p) {
13998            if (mProviders.containsKey(p.getComponentName())) {
13999                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14000                return;
14001            }
14002
14003            mProviders.put(p.getComponentName(), p);
14004            if (DEBUG_SHOW_INFO) {
14005                Log.v(TAG, "  "
14006                        + (p.info.nonLocalizedLabel != null
14007                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
14008                Log.v(TAG, "    Class=" + p.info.name);
14009            }
14010            final int NI = p.intents.size();
14011            int j;
14012            for (j = 0; j < NI; j++) {
14013                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14014                if (DEBUG_SHOW_INFO) {
14015                    Log.v(TAG, "    IntentFilter:");
14016                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14017                }
14018                if (!intent.debugCheck()) {
14019                    Log.w(TAG, "==> For Provider " + p.info.name);
14020                }
14021                addFilter(intent);
14022            }
14023        }
14024
14025        public final void removeProvider(PackageParser.Provider p) {
14026            mProviders.remove(p.getComponentName());
14027            if (DEBUG_SHOW_INFO) {
14028                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14029                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
14030                Log.v(TAG, "    Class=" + p.info.name);
14031            }
14032            final int NI = p.intents.size();
14033            int j;
14034            for (j = 0; j < NI; j++) {
14035                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14036                if (DEBUG_SHOW_INFO) {
14037                    Log.v(TAG, "    IntentFilter:");
14038                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14039                }
14040                removeFilter(intent);
14041            }
14042        }
14043
14044        @Override
14045        protected boolean allowFilterResult(
14046                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14047            ProviderInfo filterPi = filter.provider.info;
14048            for (int i = dest.size() - 1; i >= 0; i--) {
14049                ProviderInfo destPi = dest.get(i).providerInfo;
14050                if (destPi.name == filterPi.name
14051                        && destPi.packageName == filterPi.packageName) {
14052                    return false;
14053                }
14054            }
14055            return true;
14056        }
14057
14058        @Override
14059        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14060            return new PackageParser.ProviderIntentInfo[size];
14061        }
14062
14063        @Override
14064        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14065            if (!sUserManager.exists(userId))
14066                return true;
14067            PackageParser.Package p = filter.provider.owner;
14068            if (p != null) {
14069                PackageSetting ps = (PackageSetting) p.mExtras;
14070                if (ps != null) {
14071                    // System apps are never considered stopped for purposes of
14072                    // filtering, because there may be no way for the user to
14073                    // actually re-launch them.
14074                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14075                            && ps.getStopped(userId);
14076                }
14077            }
14078            return false;
14079        }
14080
14081        @Override
14082        protected boolean isPackageForFilter(String packageName,
14083                PackageParser.ProviderIntentInfo info) {
14084            return packageName.equals(info.provider.owner.packageName);
14085        }
14086
14087        @Override
14088        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14089                int match, int userId) {
14090            if (!sUserManager.exists(userId))
14091                return null;
14092            final PackageParser.ProviderIntentInfo info = filter;
14093            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14094                return null;
14095            }
14096            final PackageParser.Provider provider = info.provider;
14097            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14098            if (ps == null) {
14099                return null;
14100            }
14101            final PackageUserState userState = ps.readUserState(userId);
14102            final boolean matchVisibleToInstantApp =
14103                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14104            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14105            // throw out filters that aren't visible to instant applications
14106            if (matchVisibleToInstantApp
14107                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14108                return null;
14109            }
14110            // throw out instant application filters if we're not explicitly requesting them
14111            if (!isInstantApp && userState.instantApp) {
14112                return null;
14113            }
14114            // throw out instant application filters if updates are available; will trigger
14115            // instant application resolution
14116            if (userState.instantApp && ps.isUpdateAvailable()) {
14117                return null;
14118            }
14119            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14120                    userState, userId);
14121            if (pi == null) {
14122                return null;
14123            }
14124            final ResolveInfo res = new ResolveInfo();
14125            res.providerInfo = pi;
14126            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14127                res.filter = filter;
14128            }
14129            res.priority = info.getPriority();
14130            res.preferredOrder = provider.owner.mPreferredOrder;
14131            res.match = match;
14132            res.isDefault = info.hasDefault;
14133            res.labelRes = info.labelRes;
14134            res.nonLocalizedLabel = info.nonLocalizedLabel;
14135            res.icon = info.icon;
14136            res.system = res.providerInfo.applicationInfo.isSystemApp();
14137            return res;
14138        }
14139
14140        @Override
14141        protected void sortResults(List<ResolveInfo> results) {
14142            Collections.sort(results, mResolvePrioritySorter);
14143        }
14144
14145        @Override
14146        protected void dumpFilter(PrintWriter out, String prefix,
14147                PackageParser.ProviderIntentInfo filter) {
14148            out.print(prefix);
14149            out.print(
14150                    Integer.toHexString(System.identityHashCode(filter.provider)));
14151            out.print(' ');
14152            filter.provider.printComponentShortName(out);
14153            out.print(" filter ");
14154            out.println(Integer.toHexString(System.identityHashCode(filter)));
14155        }
14156
14157        @Override
14158        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14159            return filter.provider;
14160        }
14161
14162        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14163            PackageParser.Provider provider = (PackageParser.Provider)label;
14164            out.print(prefix); out.print(
14165                    Integer.toHexString(System.identityHashCode(provider)));
14166                    out.print(' ');
14167                    provider.printComponentShortName(out);
14168            if (count > 1) {
14169                out.print(" ("); out.print(count); out.print(" filters)");
14170            }
14171            out.println();
14172        }
14173
14174        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14175                = new ArrayMap<ComponentName, PackageParser.Provider>();
14176        private int mFlags;
14177    }
14178
14179    static final class EphemeralIntentResolver
14180            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14181        /**
14182         * The result that has the highest defined order. Ordering applies on a
14183         * per-package basis. Mapping is from package name to Pair of order and
14184         * EphemeralResolveInfo.
14185         * <p>
14186         * NOTE: This is implemented as a field variable for convenience and efficiency.
14187         * By having a field variable, we're able to track filter ordering as soon as
14188         * a non-zero order is defined. Otherwise, multiple loops across the result set
14189         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14190         * this needs to be contained entirely within {@link #filterResults}.
14191         */
14192        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14193
14194        @Override
14195        protected AuxiliaryResolveInfo[] newArray(int size) {
14196            return new AuxiliaryResolveInfo[size];
14197        }
14198
14199        @Override
14200        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14201            return true;
14202        }
14203
14204        @Override
14205        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14206                int userId) {
14207            if (!sUserManager.exists(userId)) {
14208                return null;
14209            }
14210            final String packageName = responseObj.resolveInfo.getPackageName();
14211            final Integer order = responseObj.getOrder();
14212            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14213                    mOrderResult.get(packageName);
14214            // ordering is enabled and this item's order isn't high enough
14215            if (lastOrderResult != null && lastOrderResult.first >= order) {
14216                return null;
14217            }
14218            final InstantAppResolveInfo res = responseObj.resolveInfo;
14219            if (order > 0) {
14220                // non-zero order, enable ordering
14221                mOrderResult.put(packageName, new Pair<>(order, res));
14222            }
14223            return responseObj;
14224        }
14225
14226        @Override
14227        protected void filterResults(List<AuxiliaryResolveInfo> results) {
14228            // only do work if ordering is enabled [most of the time it won't be]
14229            if (mOrderResult.size() == 0) {
14230                return;
14231            }
14232            int resultSize = results.size();
14233            for (int i = 0; i < resultSize; i++) {
14234                final InstantAppResolveInfo info = results.get(i).resolveInfo;
14235                final String packageName = info.getPackageName();
14236                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14237                if (savedInfo == null) {
14238                    // package doesn't having ordering
14239                    continue;
14240                }
14241                if (savedInfo.second == info) {
14242                    // circled back to the highest ordered item; remove from order list
14243                    mOrderResult.remove(savedInfo);
14244                    if (mOrderResult.size() == 0) {
14245                        // no more ordered items
14246                        break;
14247                    }
14248                    continue;
14249                }
14250                // item has a worse order, remove it from the result list
14251                results.remove(i);
14252                resultSize--;
14253                i--;
14254            }
14255        }
14256    }
14257
14258    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14259            new Comparator<ResolveInfo>() {
14260        public int compare(ResolveInfo r1, ResolveInfo r2) {
14261            int v1 = r1.priority;
14262            int v2 = r2.priority;
14263            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14264            if (v1 != v2) {
14265                return (v1 > v2) ? -1 : 1;
14266            }
14267            v1 = r1.preferredOrder;
14268            v2 = r2.preferredOrder;
14269            if (v1 != v2) {
14270                return (v1 > v2) ? -1 : 1;
14271            }
14272            if (r1.isDefault != r2.isDefault) {
14273                return r1.isDefault ? -1 : 1;
14274            }
14275            v1 = r1.match;
14276            v2 = r2.match;
14277            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14278            if (v1 != v2) {
14279                return (v1 > v2) ? -1 : 1;
14280            }
14281            if (r1.system != r2.system) {
14282                return r1.system ? -1 : 1;
14283            }
14284            if (r1.activityInfo != null) {
14285                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14286            }
14287            if (r1.serviceInfo != null) {
14288                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14289            }
14290            if (r1.providerInfo != null) {
14291                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14292            }
14293            return 0;
14294        }
14295    };
14296
14297    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14298            new Comparator<ProviderInfo>() {
14299        public int compare(ProviderInfo p1, ProviderInfo p2) {
14300            final int v1 = p1.initOrder;
14301            final int v2 = p2.initOrder;
14302            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14303        }
14304    };
14305
14306    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14307            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14308            final int[] userIds) {
14309        mHandler.post(new Runnable() {
14310            @Override
14311            public void run() {
14312                try {
14313                    final IActivityManager am = ActivityManager.getService();
14314                    if (am == null) return;
14315                    final int[] resolvedUserIds;
14316                    if (userIds == null) {
14317                        resolvedUserIds = am.getRunningUserIds();
14318                    } else {
14319                        resolvedUserIds = userIds;
14320                    }
14321                    for (int id : resolvedUserIds) {
14322                        final Intent intent = new Intent(action,
14323                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14324                        if (extras != null) {
14325                            intent.putExtras(extras);
14326                        }
14327                        if (targetPkg != null) {
14328                            intent.setPackage(targetPkg);
14329                        }
14330                        // Modify the UID when posting to other users
14331                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14332                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14333                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14334                            intent.putExtra(Intent.EXTRA_UID, uid);
14335                        }
14336                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14337                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14338                        if (DEBUG_BROADCASTS) {
14339                            RuntimeException here = new RuntimeException("here");
14340                            here.fillInStackTrace();
14341                            Slog.d(TAG, "Sending to user " + id + ": "
14342                                    + intent.toShortString(false, true, false, false)
14343                                    + " " + intent.getExtras(), here);
14344                        }
14345                        am.broadcastIntent(null, intent, null, finishedReceiver,
14346                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14347                                null, finishedReceiver != null, false, id);
14348                    }
14349                } catch (RemoteException ex) {
14350                }
14351            }
14352        });
14353    }
14354
14355    /**
14356     * Check if the external storage media is available. This is true if there
14357     * is a mounted external storage medium or if the external storage is
14358     * emulated.
14359     */
14360    private boolean isExternalMediaAvailable() {
14361        return mMediaMounted || Environment.isExternalStorageEmulated();
14362    }
14363
14364    @Override
14365    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14366        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14367            return null;
14368        }
14369        // writer
14370        synchronized (mPackages) {
14371            if (!isExternalMediaAvailable()) {
14372                // If the external storage is no longer mounted at this point,
14373                // the caller may not have been able to delete all of this
14374                // packages files and can not delete any more.  Bail.
14375                return null;
14376            }
14377            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14378            if (lastPackage != null) {
14379                pkgs.remove(lastPackage);
14380            }
14381            if (pkgs.size() > 0) {
14382                return pkgs.get(0);
14383            }
14384        }
14385        return null;
14386    }
14387
14388    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14389        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14390                userId, andCode ? 1 : 0, packageName);
14391        if (mSystemReady) {
14392            msg.sendToTarget();
14393        } else {
14394            if (mPostSystemReadyMessages == null) {
14395                mPostSystemReadyMessages = new ArrayList<>();
14396            }
14397            mPostSystemReadyMessages.add(msg);
14398        }
14399    }
14400
14401    void startCleaningPackages() {
14402        // reader
14403        if (!isExternalMediaAvailable()) {
14404            return;
14405        }
14406        synchronized (mPackages) {
14407            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14408                return;
14409            }
14410        }
14411        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14412        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14413        IActivityManager am = ActivityManager.getService();
14414        if (am != null) {
14415            int dcsUid = -1;
14416            synchronized (mPackages) {
14417                if (!mDefaultContainerWhitelisted) {
14418                    mDefaultContainerWhitelisted = true;
14419                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14420                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14421                }
14422            }
14423            try {
14424                if (dcsUid > 0) {
14425                    am.backgroundWhitelistUid(dcsUid);
14426                }
14427                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14428                        UserHandle.USER_SYSTEM);
14429            } catch (RemoteException e) {
14430            }
14431        }
14432    }
14433
14434    @Override
14435    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14436            int installFlags, String installerPackageName, int userId) {
14437        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14438
14439        final int callingUid = Binder.getCallingUid();
14440        enforceCrossUserPermission(callingUid, userId,
14441                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14442
14443        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14444            try {
14445                if (observer != null) {
14446                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14447                }
14448            } catch (RemoteException re) {
14449            }
14450            return;
14451        }
14452
14453        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14454            installFlags |= PackageManager.INSTALL_FROM_ADB;
14455
14456        } else {
14457            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14458            // about installerPackageName.
14459
14460            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14461            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14462        }
14463
14464        UserHandle user;
14465        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14466            user = UserHandle.ALL;
14467        } else {
14468            user = new UserHandle(userId);
14469        }
14470
14471        // Only system components can circumvent runtime permissions when installing.
14472        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14473                && mContext.checkCallingOrSelfPermission(Manifest.permission
14474                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14475            throw new SecurityException("You need the "
14476                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14477                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14478        }
14479
14480        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14481                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14482            throw new IllegalArgumentException(
14483                    "New installs into ASEC containers no longer supported");
14484        }
14485
14486        final File originFile = new File(originPath);
14487        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14488
14489        final Message msg = mHandler.obtainMessage(INIT_COPY);
14490        final VerificationInfo verificationInfo = new VerificationInfo(
14491                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14492        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14493                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14494                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14495                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14496        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14497        msg.obj = params;
14498
14499        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14500                System.identityHashCode(msg.obj));
14501        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14502                System.identityHashCode(msg.obj));
14503
14504        mHandler.sendMessage(msg);
14505    }
14506
14507
14508    /**
14509     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14510     * it is acting on behalf on an enterprise or the user).
14511     *
14512     * Note that the ordering of the conditionals in this method is important. The checks we perform
14513     * are as follows, in this order:
14514     *
14515     * 1) If the install is being performed by a system app, we can trust the app to have set the
14516     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14517     *    what it is.
14518     * 2) If the install is being performed by a device or profile owner app, the install reason
14519     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14520     *    set the install reason correctly. If the app targets an older SDK version where install
14521     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14522     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14523     * 3) In all other cases, the install is being performed by a regular app that is neither part
14524     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14525     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14526     *    set to enterprise policy and if so, change it to unknown instead.
14527     */
14528    private int fixUpInstallReason(String installerPackageName, int installerUid,
14529            int installReason) {
14530        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14531                == PERMISSION_GRANTED) {
14532            // If the install is being performed by a system app, we trust that app to have set the
14533            // install reason correctly.
14534            return installReason;
14535        }
14536
14537        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14538            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14539        if (dpm != null) {
14540            ComponentName owner = null;
14541            try {
14542                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14543                if (owner == null) {
14544                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14545                }
14546            } catch (RemoteException e) {
14547            }
14548            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14549                // If the install is being performed by a device or profile owner, the install
14550                // reason should be enterprise policy.
14551                return PackageManager.INSTALL_REASON_POLICY;
14552            }
14553        }
14554
14555        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14556            // If the install is being performed by a regular app (i.e. neither system app nor
14557            // device or profile owner), we have no reason to believe that the app is acting on
14558            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14559            // change it to unknown instead.
14560            return PackageManager.INSTALL_REASON_UNKNOWN;
14561        }
14562
14563        // If the install is being performed by a regular app and the install reason was set to any
14564        // value but enterprise policy, leave the install reason unchanged.
14565        return installReason;
14566    }
14567
14568    void installStage(String packageName, File stagedDir, String stagedCid,
14569            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14570            String installerPackageName, int installerUid, UserHandle user,
14571            Certificate[][] certificates) {
14572        if (DEBUG_EPHEMERAL) {
14573            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14574                Slog.d(TAG, "Ephemeral install of " + packageName);
14575            }
14576        }
14577        final VerificationInfo verificationInfo = new VerificationInfo(
14578                sessionParams.originatingUri, sessionParams.referrerUri,
14579                sessionParams.originatingUid, installerUid);
14580
14581        final OriginInfo origin;
14582        if (stagedDir != null) {
14583            origin = OriginInfo.fromStagedFile(stagedDir);
14584        } else {
14585            origin = OriginInfo.fromStagedContainer(stagedCid);
14586        }
14587
14588        final Message msg = mHandler.obtainMessage(INIT_COPY);
14589        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14590                sessionParams.installReason);
14591        final InstallParams params = new InstallParams(origin, null, observer,
14592                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14593                verificationInfo, user, sessionParams.abiOverride,
14594                sessionParams.grantedRuntimePermissions, certificates, installReason);
14595        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14596        msg.obj = params;
14597
14598        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14599                System.identityHashCode(msg.obj));
14600        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14601                System.identityHashCode(msg.obj));
14602
14603        mHandler.sendMessage(msg);
14604    }
14605
14606    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14607            int userId) {
14608        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14609        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14610                false /*startReceiver*/, pkgSetting.appId, userId);
14611
14612        // Send a session commit broadcast
14613        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14614        info.installReason = pkgSetting.getInstallReason(userId);
14615        info.appPackageName = packageName;
14616        sendSessionCommitBroadcast(info, userId);
14617    }
14618
14619    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14620            boolean includeStopped, int appId, int... userIds) {
14621        if (ArrayUtils.isEmpty(userIds)) {
14622            return;
14623        }
14624        Bundle extras = new Bundle(1);
14625        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14626        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14627
14628        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14629                packageName, extras, 0, null, null, userIds);
14630        if (sendBootCompleted) {
14631            mHandler.post(() -> {
14632                        for (int userId : userIds) {
14633                            sendBootCompletedBroadcastToSystemApp(
14634                                    packageName, includeStopped, userId);
14635                        }
14636                    }
14637            );
14638        }
14639    }
14640
14641    /**
14642     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14643     * automatically without needing an explicit launch.
14644     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14645     */
14646    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
14647            int userId) {
14648        // If user is not running, the app didn't miss any broadcast
14649        if (!mUserManagerInternal.isUserRunning(userId)) {
14650            return;
14651        }
14652        final IActivityManager am = ActivityManager.getService();
14653        try {
14654            // Deliver LOCKED_BOOT_COMPLETED first
14655            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14656                    .setPackage(packageName);
14657            if (includeStopped) {
14658                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14659            }
14660            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14661            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14662                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14663
14664            // Deliver BOOT_COMPLETED only if user is unlocked
14665            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14666                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14667                if (includeStopped) {
14668                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14669                }
14670                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14671                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14672            }
14673        } catch (RemoteException e) {
14674            throw e.rethrowFromSystemServer();
14675        }
14676    }
14677
14678    @Override
14679    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14680            int userId) {
14681        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14682        PackageSetting pkgSetting;
14683        final int callingUid = Binder.getCallingUid();
14684        enforceCrossUserPermission(callingUid, userId,
14685                true /* requireFullPermission */, true /* checkShell */,
14686                "setApplicationHiddenSetting for user " + userId);
14687
14688        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14689            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14690            return false;
14691        }
14692
14693        long callingId = Binder.clearCallingIdentity();
14694        try {
14695            boolean sendAdded = false;
14696            boolean sendRemoved = false;
14697            // writer
14698            synchronized (mPackages) {
14699                pkgSetting = mSettings.mPackages.get(packageName);
14700                if (pkgSetting == null) {
14701                    return false;
14702                }
14703                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14704                    return false;
14705                }
14706                // Do not allow "android" is being disabled
14707                if ("android".equals(packageName)) {
14708                    Slog.w(TAG, "Cannot hide package: android");
14709                    return false;
14710                }
14711                // Cannot hide static shared libs as they are considered
14712                // a part of the using app (emulating static linking). Also
14713                // static libs are installed always on internal storage.
14714                PackageParser.Package pkg = mPackages.get(packageName);
14715                if (pkg != null && pkg.staticSharedLibName != null) {
14716                    Slog.w(TAG, "Cannot hide package: " + packageName
14717                            + " providing static shared library: "
14718                            + pkg.staticSharedLibName);
14719                    return false;
14720                }
14721                // Only allow protected packages to hide themselves.
14722                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
14723                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14724                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14725                    return false;
14726                }
14727
14728                if (pkgSetting.getHidden(userId) != hidden) {
14729                    pkgSetting.setHidden(hidden, userId);
14730                    mSettings.writePackageRestrictionsLPr(userId);
14731                    if (hidden) {
14732                        sendRemoved = true;
14733                    } else {
14734                        sendAdded = true;
14735                    }
14736                }
14737            }
14738            if (sendAdded) {
14739                sendPackageAddedForUser(packageName, pkgSetting, userId);
14740                return true;
14741            }
14742            if (sendRemoved) {
14743                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14744                        "hiding pkg");
14745                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14746                return true;
14747            }
14748        } finally {
14749            Binder.restoreCallingIdentity(callingId);
14750        }
14751        return false;
14752    }
14753
14754    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14755            int userId) {
14756        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14757        info.removedPackage = packageName;
14758        info.installerPackageName = pkgSetting.installerPackageName;
14759        info.removedUsers = new int[] {userId};
14760        info.broadcastUsers = new int[] {userId};
14761        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14762        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14763    }
14764
14765    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14766        if (pkgList.length > 0) {
14767            Bundle extras = new Bundle(1);
14768            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14769
14770            sendPackageBroadcast(
14771                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14772                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14773                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14774                    new int[] {userId});
14775        }
14776    }
14777
14778    /**
14779     * Returns true if application is not found or there was an error. Otherwise it returns
14780     * the hidden state of the package for the given user.
14781     */
14782    @Override
14783    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14784        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14785        final int callingUid = Binder.getCallingUid();
14786        enforceCrossUserPermission(callingUid, userId,
14787                true /* requireFullPermission */, false /* checkShell */,
14788                "getApplicationHidden for user " + userId);
14789        PackageSetting ps;
14790        long callingId = Binder.clearCallingIdentity();
14791        try {
14792            // writer
14793            synchronized (mPackages) {
14794                ps = mSettings.mPackages.get(packageName);
14795                if (ps == null) {
14796                    return true;
14797                }
14798                if (filterAppAccessLPr(ps, callingUid, userId)) {
14799                    return true;
14800                }
14801                return ps.getHidden(userId);
14802            }
14803        } finally {
14804            Binder.restoreCallingIdentity(callingId);
14805        }
14806    }
14807
14808    /**
14809     * @hide
14810     */
14811    @Override
14812    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14813            int installReason) {
14814        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14815                null);
14816        PackageSetting pkgSetting;
14817        final int callingUid = Binder.getCallingUid();
14818        enforceCrossUserPermission(callingUid, userId,
14819                true /* requireFullPermission */, true /* checkShell */,
14820                "installExistingPackage for user " + userId);
14821        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14822            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14823        }
14824
14825        long callingId = Binder.clearCallingIdentity();
14826        try {
14827            boolean installed = false;
14828            final boolean instantApp =
14829                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14830            final boolean fullApp =
14831                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14832
14833            // writer
14834            synchronized (mPackages) {
14835                pkgSetting = mSettings.mPackages.get(packageName);
14836                if (pkgSetting == null) {
14837                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14838                }
14839                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14840                    // only allow the existing package to be used if it's installed as a full
14841                    // application for at least one user
14842                    boolean installAllowed = false;
14843                    for (int checkUserId : sUserManager.getUserIds()) {
14844                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
14845                        if (installAllowed) {
14846                            break;
14847                        }
14848                    }
14849                    if (!installAllowed) {
14850                        return PackageManager.INSTALL_FAILED_INVALID_URI;
14851                    }
14852                }
14853                if (!pkgSetting.getInstalled(userId)) {
14854                    pkgSetting.setInstalled(true, userId);
14855                    pkgSetting.setHidden(false, userId);
14856                    pkgSetting.setInstallReason(installReason, userId);
14857                    mSettings.writePackageRestrictionsLPr(userId);
14858                    mSettings.writeKernelMappingLPr(pkgSetting);
14859                    installed = true;
14860                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14861                    // upgrade app from instant to full; we don't allow app downgrade
14862                    installed = true;
14863                }
14864                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14865            }
14866
14867            if (installed) {
14868                if (pkgSetting.pkg != null) {
14869                    synchronized (mInstallLock) {
14870                        // We don't need to freeze for a brand new install
14871                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14872                    }
14873                }
14874                sendPackageAddedForUser(packageName, pkgSetting, userId);
14875                synchronized (mPackages) {
14876                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14877                }
14878            }
14879        } finally {
14880            Binder.restoreCallingIdentity(callingId);
14881        }
14882
14883        return PackageManager.INSTALL_SUCCEEDED;
14884    }
14885
14886    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14887            boolean instantApp, boolean fullApp) {
14888        // no state specified; do nothing
14889        if (!instantApp && !fullApp) {
14890            return;
14891        }
14892        if (userId != UserHandle.USER_ALL) {
14893            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14894                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14895            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14896                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14897            }
14898        } else {
14899            for (int currentUserId : sUserManager.getUserIds()) {
14900                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14901                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14902                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14903                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14904                }
14905            }
14906        }
14907    }
14908
14909    boolean isUserRestricted(int userId, String restrictionKey) {
14910        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14911        if (restrictions.getBoolean(restrictionKey, false)) {
14912            Log.w(TAG, "User is restricted: " + restrictionKey);
14913            return true;
14914        }
14915        return false;
14916    }
14917
14918    @Override
14919    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14920            int userId) {
14921        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14922        final int callingUid = Binder.getCallingUid();
14923        enforceCrossUserPermission(callingUid, userId,
14924                true /* requireFullPermission */, true /* checkShell */,
14925                "setPackagesSuspended for user " + userId);
14926
14927        if (ArrayUtils.isEmpty(packageNames)) {
14928            return packageNames;
14929        }
14930
14931        // List of package names for whom the suspended state has changed.
14932        List<String> changedPackages = new ArrayList<>(packageNames.length);
14933        // List of package names for whom the suspended state is not set as requested in this
14934        // method.
14935        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14936        long callingId = Binder.clearCallingIdentity();
14937        try {
14938            for (int i = 0; i < packageNames.length; i++) {
14939                String packageName = packageNames[i];
14940                boolean changed = false;
14941                final int appId;
14942                synchronized (mPackages) {
14943                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14944                    if (pkgSetting == null
14945                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14946                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14947                                + "\". Skipping suspending/un-suspending.");
14948                        unactionedPackages.add(packageName);
14949                        continue;
14950                    }
14951                    appId = pkgSetting.appId;
14952                    if (pkgSetting.getSuspended(userId) != suspended) {
14953                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14954                            unactionedPackages.add(packageName);
14955                            continue;
14956                        }
14957                        pkgSetting.setSuspended(suspended, userId);
14958                        mSettings.writePackageRestrictionsLPr(userId);
14959                        changed = true;
14960                        changedPackages.add(packageName);
14961                    }
14962                }
14963
14964                if (changed && suspended) {
14965                    killApplication(packageName, UserHandle.getUid(userId, appId),
14966                            "suspending package");
14967                }
14968            }
14969        } finally {
14970            Binder.restoreCallingIdentity(callingId);
14971        }
14972
14973        if (!changedPackages.isEmpty()) {
14974            sendPackagesSuspendedForUser(changedPackages.toArray(
14975                    new String[changedPackages.size()]), userId, suspended);
14976        }
14977
14978        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14979    }
14980
14981    @Override
14982    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14983        final int callingUid = Binder.getCallingUid();
14984        enforceCrossUserPermission(callingUid, userId,
14985                true /* requireFullPermission */, false /* checkShell */,
14986                "isPackageSuspendedForUser for user " + userId);
14987        synchronized (mPackages) {
14988            final PackageSetting ps = mSettings.mPackages.get(packageName);
14989            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14990                throw new IllegalArgumentException("Unknown target package: " + packageName);
14991            }
14992            return ps.getSuspended(userId);
14993        }
14994    }
14995
14996    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14997        if (isPackageDeviceAdmin(packageName, userId)) {
14998            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14999                    + "\": has an active device admin");
15000            return false;
15001        }
15002
15003        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15004        if (packageName.equals(activeLauncherPackageName)) {
15005            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15006                    + "\": contains the active launcher");
15007            return false;
15008        }
15009
15010        if (packageName.equals(mRequiredInstallerPackage)) {
15011            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15012                    + "\": required for package installation");
15013            return false;
15014        }
15015
15016        if (packageName.equals(mRequiredUninstallerPackage)) {
15017            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15018                    + "\": required for package uninstallation");
15019            return false;
15020        }
15021
15022        if (packageName.equals(mRequiredVerifierPackage)) {
15023            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15024                    + "\": required for package verification");
15025            return false;
15026        }
15027
15028        if (packageName.equals(getDefaultDialerPackageName(userId))) {
15029            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15030                    + "\": is the default dialer");
15031            return false;
15032        }
15033
15034        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15035            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15036                    + "\": protected package");
15037            return false;
15038        }
15039
15040        // Cannot suspend static shared libs as they are considered
15041        // a part of the using app (emulating static linking). Also
15042        // static libs are installed always on internal storage.
15043        PackageParser.Package pkg = mPackages.get(packageName);
15044        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15045            Slog.w(TAG, "Cannot suspend package: " + packageName
15046                    + " providing static shared library: "
15047                    + pkg.staticSharedLibName);
15048            return false;
15049        }
15050
15051        return true;
15052    }
15053
15054    private String getActiveLauncherPackageName(int userId) {
15055        Intent intent = new Intent(Intent.ACTION_MAIN);
15056        intent.addCategory(Intent.CATEGORY_HOME);
15057        ResolveInfo resolveInfo = resolveIntent(
15058                intent,
15059                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15060                PackageManager.MATCH_DEFAULT_ONLY,
15061                userId);
15062
15063        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15064    }
15065
15066    private String getDefaultDialerPackageName(int userId) {
15067        synchronized (mPackages) {
15068            return mSettings.getDefaultDialerPackageNameLPw(userId);
15069        }
15070    }
15071
15072    @Override
15073    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15074        mContext.enforceCallingOrSelfPermission(
15075                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15076                "Only package verification agents can verify applications");
15077
15078        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15079        final PackageVerificationResponse response = new PackageVerificationResponse(
15080                verificationCode, Binder.getCallingUid());
15081        msg.arg1 = id;
15082        msg.obj = response;
15083        mHandler.sendMessage(msg);
15084    }
15085
15086    @Override
15087    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15088            long millisecondsToDelay) {
15089        mContext.enforceCallingOrSelfPermission(
15090                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15091                "Only package verification agents can extend verification timeouts");
15092
15093        final PackageVerificationState state = mPendingVerification.get(id);
15094        final PackageVerificationResponse response = new PackageVerificationResponse(
15095                verificationCodeAtTimeout, Binder.getCallingUid());
15096
15097        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15098            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15099        }
15100        if (millisecondsToDelay < 0) {
15101            millisecondsToDelay = 0;
15102        }
15103        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15104                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15105            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15106        }
15107
15108        if ((state != null) && !state.timeoutExtended()) {
15109            state.extendTimeout();
15110
15111            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15112            msg.arg1 = id;
15113            msg.obj = response;
15114            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15115        }
15116    }
15117
15118    private void broadcastPackageVerified(int verificationId, Uri packageUri,
15119            int verificationCode, UserHandle user) {
15120        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15121        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15122        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15123        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15124        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15125
15126        mContext.sendBroadcastAsUser(intent, user,
15127                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15128    }
15129
15130    private ComponentName matchComponentForVerifier(String packageName,
15131            List<ResolveInfo> receivers) {
15132        ActivityInfo targetReceiver = null;
15133
15134        final int NR = receivers.size();
15135        for (int i = 0; i < NR; i++) {
15136            final ResolveInfo info = receivers.get(i);
15137            if (info.activityInfo == null) {
15138                continue;
15139            }
15140
15141            if (packageName.equals(info.activityInfo.packageName)) {
15142                targetReceiver = info.activityInfo;
15143                break;
15144            }
15145        }
15146
15147        if (targetReceiver == null) {
15148            return null;
15149        }
15150
15151        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15152    }
15153
15154    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15155            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15156        if (pkgInfo.verifiers.length == 0) {
15157            return null;
15158        }
15159
15160        final int N = pkgInfo.verifiers.length;
15161        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15162        for (int i = 0; i < N; i++) {
15163            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15164
15165            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15166                    receivers);
15167            if (comp == null) {
15168                continue;
15169            }
15170
15171            final int verifierUid = getUidForVerifier(verifierInfo);
15172            if (verifierUid == -1) {
15173                continue;
15174            }
15175
15176            if (DEBUG_VERIFY) {
15177                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15178                        + " with the correct signature");
15179            }
15180            sufficientVerifiers.add(comp);
15181            verificationState.addSufficientVerifier(verifierUid);
15182        }
15183
15184        return sufficientVerifiers;
15185    }
15186
15187    private int getUidForVerifier(VerifierInfo verifierInfo) {
15188        synchronized (mPackages) {
15189            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15190            if (pkg == null) {
15191                return -1;
15192            } else if (pkg.mSignatures.length != 1) {
15193                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15194                        + " has more than one signature; ignoring");
15195                return -1;
15196            }
15197
15198            /*
15199             * If the public key of the package's signature does not match
15200             * our expected public key, then this is a different package and
15201             * we should skip.
15202             */
15203
15204            final byte[] expectedPublicKey;
15205            try {
15206                final Signature verifierSig = pkg.mSignatures[0];
15207                final PublicKey publicKey = verifierSig.getPublicKey();
15208                expectedPublicKey = publicKey.getEncoded();
15209            } catch (CertificateException e) {
15210                return -1;
15211            }
15212
15213            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15214
15215            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15216                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15217                        + " does not have the expected public key; ignoring");
15218                return -1;
15219            }
15220
15221            return pkg.applicationInfo.uid;
15222        }
15223    }
15224
15225    @Override
15226    public void finishPackageInstall(int token, boolean didLaunch) {
15227        enforceSystemOrRoot("Only the system is allowed to finish installs");
15228
15229        if (DEBUG_INSTALL) {
15230            Slog.v(TAG, "BM finishing package install for " + token);
15231        }
15232        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15233
15234        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15235        mHandler.sendMessage(msg);
15236    }
15237
15238    /**
15239     * Get the verification agent timeout.  Used for both the APK verifier and the
15240     * intent filter verifier.
15241     *
15242     * @return verification timeout in milliseconds
15243     */
15244    private long getVerificationTimeout() {
15245        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15246                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15247                DEFAULT_VERIFICATION_TIMEOUT);
15248    }
15249
15250    /**
15251     * Get the default verification agent response code.
15252     *
15253     * @return default verification response code
15254     */
15255    private int getDefaultVerificationResponse(UserHandle user) {
15256        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15257            return PackageManager.VERIFICATION_REJECT;
15258        }
15259        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15260                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15261                DEFAULT_VERIFICATION_RESPONSE);
15262    }
15263
15264    /**
15265     * Check whether or not package verification has been enabled.
15266     *
15267     * @return true if verification should be performed
15268     */
15269    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15270        if (!DEFAULT_VERIFY_ENABLE) {
15271            return false;
15272        }
15273
15274        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15275
15276        // Check if installing from ADB
15277        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15278            // Do not run verification in a test harness environment
15279            if (ActivityManager.isRunningInTestHarness()) {
15280                return false;
15281            }
15282            if (ensureVerifyAppsEnabled) {
15283                return true;
15284            }
15285            // Check if the developer does not want package verification for ADB installs
15286            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15287                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15288                return false;
15289            }
15290        } else {
15291            // only when not installed from ADB, skip verification for instant apps when
15292            // the installer and verifier are the same.
15293            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15294                if (mInstantAppInstallerActivity != null
15295                        && mInstantAppInstallerActivity.packageName.equals(
15296                                mRequiredVerifierPackage)) {
15297                    try {
15298                        mContext.getSystemService(AppOpsManager.class)
15299                                .checkPackage(installerUid, mRequiredVerifierPackage);
15300                        if (DEBUG_VERIFY) {
15301                            Slog.i(TAG, "disable verification for instant app");
15302                        }
15303                        return false;
15304                    } catch (SecurityException ignore) { }
15305                }
15306            }
15307        }
15308
15309        if (ensureVerifyAppsEnabled) {
15310            return true;
15311        }
15312
15313        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15314                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15315    }
15316
15317    @Override
15318    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15319            throws RemoteException {
15320        mContext.enforceCallingOrSelfPermission(
15321                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15322                "Only intentfilter verification agents can verify applications");
15323
15324        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15325        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15326                Binder.getCallingUid(), verificationCode, failedDomains);
15327        msg.arg1 = id;
15328        msg.obj = response;
15329        mHandler.sendMessage(msg);
15330    }
15331
15332    @Override
15333    public int getIntentVerificationStatus(String packageName, int userId) {
15334        final int callingUid = Binder.getCallingUid();
15335        if (UserHandle.getUserId(callingUid) != userId) {
15336            mContext.enforceCallingOrSelfPermission(
15337                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15338                    "getIntentVerificationStatus" + userId);
15339        }
15340        if (getInstantAppPackageName(callingUid) != null) {
15341            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15342        }
15343        synchronized (mPackages) {
15344            final PackageSetting ps = mSettings.mPackages.get(packageName);
15345            if (ps == null
15346                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15347                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15348            }
15349            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15350        }
15351    }
15352
15353    @Override
15354    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15355        mContext.enforceCallingOrSelfPermission(
15356                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15357
15358        boolean result = false;
15359        synchronized (mPackages) {
15360            final PackageSetting ps = mSettings.mPackages.get(packageName);
15361            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15362                return false;
15363            }
15364            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15365        }
15366        if (result) {
15367            scheduleWritePackageRestrictionsLocked(userId);
15368        }
15369        return result;
15370    }
15371
15372    @Override
15373    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15374            String packageName) {
15375        final int callingUid = Binder.getCallingUid();
15376        if (getInstantAppPackageName(callingUid) != null) {
15377            return ParceledListSlice.emptyList();
15378        }
15379        synchronized (mPackages) {
15380            final PackageSetting ps = mSettings.mPackages.get(packageName);
15381            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15382                return ParceledListSlice.emptyList();
15383            }
15384            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15385        }
15386    }
15387
15388    @Override
15389    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15390        if (TextUtils.isEmpty(packageName)) {
15391            return ParceledListSlice.emptyList();
15392        }
15393        final int callingUid = Binder.getCallingUid();
15394        final int callingUserId = UserHandle.getUserId(callingUid);
15395        synchronized (mPackages) {
15396            PackageParser.Package pkg = mPackages.get(packageName);
15397            if (pkg == null || pkg.activities == null) {
15398                return ParceledListSlice.emptyList();
15399            }
15400            if (pkg.mExtras == null) {
15401                return ParceledListSlice.emptyList();
15402            }
15403            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15404            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15405                return ParceledListSlice.emptyList();
15406            }
15407            final int count = pkg.activities.size();
15408            ArrayList<IntentFilter> result = new ArrayList<>();
15409            for (int n=0; n<count; n++) {
15410                PackageParser.Activity activity = pkg.activities.get(n);
15411                if (activity.intents != null && activity.intents.size() > 0) {
15412                    result.addAll(activity.intents);
15413                }
15414            }
15415            return new ParceledListSlice<>(result);
15416        }
15417    }
15418
15419    @Override
15420    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15421        mContext.enforceCallingOrSelfPermission(
15422                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15423        if (UserHandle.getCallingUserId() != userId) {
15424            mContext.enforceCallingOrSelfPermission(
15425                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15426        }
15427
15428        synchronized (mPackages) {
15429            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15430            if (packageName != null) {
15431                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15432                        packageName, userId);
15433            }
15434            return result;
15435        }
15436    }
15437
15438    @Override
15439    public String getDefaultBrowserPackageName(int userId) {
15440        if (UserHandle.getCallingUserId() != userId) {
15441            mContext.enforceCallingOrSelfPermission(
15442                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15443        }
15444        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15445            return null;
15446        }
15447        synchronized (mPackages) {
15448            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15449        }
15450    }
15451
15452    /**
15453     * Get the "allow unknown sources" setting.
15454     *
15455     * @return the current "allow unknown sources" setting
15456     */
15457    private int getUnknownSourcesSettings() {
15458        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15459                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15460                -1);
15461    }
15462
15463    @Override
15464    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15465        final int callingUid = Binder.getCallingUid();
15466        if (getInstantAppPackageName(callingUid) != null) {
15467            return;
15468        }
15469        // writer
15470        synchronized (mPackages) {
15471            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15472            if (targetPackageSetting == null
15473                    || filterAppAccessLPr(
15474                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15475                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15476            }
15477
15478            PackageSetting installerPackageSetting;
15479            if (installerPackageName != null) {
15480                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15481                if (installerPackageSetting == null) {
15482                    throw new IllegalArgumentException("Unknown installer package: "
15483                            + installerPackageName);
15484                }
15485            } else {
15486                installerPackageSetting = null;
15487            }
15488
15489            Signature[] callerSignature;
15490            Object obj = mSettings.getUserIdLPr(callingUid);
15491            if (obj != null) {
15492                if (obj instanceof SharedUserSetting) {
15493                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15494                } else if (obj instanceof PackageSetting) {
15495                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15496                } else {
15497                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15498                }
15499            } else {
15500                throw new SecurityException("Unknown calling UID: " + callingUid);
15501            }
15502
15503            // Verify: can't set installerPackageName to a package that is
15504            // not signed with the same cert as the caller.
15505            if (installerPackageSetting != null) {
15506                if (compareSignatures(callerSignature,
15507                        installerPackageSetting.signatures.mSignatures)
15508                        != PackageManager.SIGNATURE_MATCH) {
15509                    throw new SecurityException(
15510                            "Caller does not have same cert as new installer package "
15511                            + installerPackageName);
15512                }
15513            }
15514
15515            // Verify: if target already has an installer package, it must
15516            // be signed with the same cert as the caller.
15517            if (targetPackageSetting.installerPackageName != null) {
15518                PackageSetting setting = mSettings.mPackages.get(
15519                        targetPackageSetting.installerPackageName);
15520                // If the currently set package isn't valid, then it's always
15521                // okay to change it.
15522                if (setting != null) {
15523                    if (compareSignatures(callerSignature,
15524                            setting.signatures.mSignatures)
15525                            != PackageManager.SIGNATURE_MATCH) {
15526                        throw new SecurityException(
15527                                "Caller does not have same cert as old installer package "
15528                                + targetPackageSetting.installerPackageName);
15529                    }
15530                }
15531            }
15532
15533            // Okay!
15534            targetPackageSetting.installerPackageName = installerPackageName;
15535            if (installerPackageName != null) {
15536                mSettings.mInstallerPackages.add(installerPackageName);
15537            }
15538            scheduleWriteSettingsLocked();
15539        }
15540    }
15541
15542    @Override
15543    public void setApplicationCategoryHint(String packageName, int categoryHint,
15544            String callerPackageName) {
15545        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15546            throw new SecurityException("Instant applications don't have access to this method");
15547        }
15548        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15549                callerPackageName);
15550        synchronized (mPackages) {
15551            PackageSetting ps = mSettings.mPackages.get(packageName);
15552            if (ps == null) {
15553                throw new IllegalArgumentException("Unknown target package " + packageName);
15554            }
15555            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15556                throw new IllegalArgumentException("Unknown target package " + packageName);
15557            }
15558            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15559                throw new IllegalArgumentException("Calling package " + callerPackageName
15560                        + " is not installer for " + packageName);
15561            }
15562
15563            if (ps.categoryHint != categoryHint) {
15564                ps.categoryHint = categoryHint;
15565                scheduleWriteSettingsLocked();
15566            }
15567        }
15568    }
15569
15570    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15571        // Queue up an async operation since the package installation may take a little while.
15572        mHandler.post(new Runnable() {
15573            public void run() {
15574                mHandler.removeCallbacks(this);
15575                 // Result object to be returned
15576                PackageInstalledInfo res = new PackageInstalledInfo();
15577                res.setReturnCode(currentStatus);
15578                res.uid = -1;
15579                res.pkg = null;
15580                res.removedInfo = null;
15581                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15582                    args.doPreInstall(res.returnCode);
15583                    synchronized (mInstallLock) {
15584                        installPackageTracedLI(args, res);
15585                    }
15586                    args.doPostInstall(res.returnCode, res.uid);
15587                }
15588
15589                // A restore should be performed at this point if (a) the install
15590                // succeeded, (b) the operation is not an update, and (c) the new
15591                // package has not opted out of backup participation.
15592                final boolean update = res.removedInfo != null
15593                        && res.removedInfo.removedPackage != null;
15594                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15595                boolean doRestore = !update
15596                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15597
15598                // Set up the post-install work request bookkeeping.  This will be used
15599                // and cleaned up by the post-install event handling regardless of whether
15600                // there's a restore pass performed.  Token values are >= 1.
15601                int token;
15602                if (mNextInstallToken < 0) mNextInstallToken = 1;
15603                token = mNextInstallToken++;
15604
15605                PostInstallData data = new PostInstallData(args, res);
15606                mRunningInstalls.put(token, data);
15607                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15608
15609                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15610                    // Pass responsibility to the Backup Manager.  It will perform a
15611                    // restore if appropriate, then pass responsibility back to the
15612                    // Package Manager to run the post-install observer callbacks
15613                    // and broadcasts.
15614                    IBackupManager bm = IBackupManager.Stub.asInterface(
15615                            ServiceManager.getService(Context.BACKUP_SERVICE));
15616                    if (bm != null) {
15617                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15618                                + " to BM for possible restore");
15619                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15620                        try {
15621                            // TODO: http://b/22388012
15622                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15623                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15624                            } else {
15625                                doRestore = false;
15626                            }
15627                        } catch (RemoteException e) {
15628                            // can't happen; the backup manager is local
15629                        } catch (Exception e) {
15630                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15631                            doRestore = false;
15632                        }
15633                    } else {
15634                        Slog.e(TAG, "Backup Manager not found!");
15635                        doRestore = false;
15636                    }
15637                }
15638
15639                if (!doRestore) {
15640                    // No restore possible, or the Backup Manager was mysteriously not
15641                    // available -- just fire the post-install work request directly.
15642                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15643
15644                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15645
15646                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15647                    mHandler.sendMessage(msg);
15648                }
15649            }
15650        });
15651    }
15652
15653    /**
15654     * Callback from PackageSettings whenever an app is first transitioned out of the
15655     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15656     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15657     * here whether the app is the target of an ongoing install, and only send the
15658     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15659     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15660     * handling.
15661     */
15662    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15663        // Serialize this with the rest of the install-process message chain.  In the
15664        // restore-at-install case, this Runnable will necessarily run before the
15665        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15666        // are coherent.  In the non-restore case, the app has already completed install
15667        // and been launched through some other means, so it is not in a problematic
15668        // state for observers to see the FIRST_LAUNCH signal.
15669        mHandler.post(new Runnable() {
15670            @Override
15671            public void run() {
15672                for (int i = 0; i < mRunningInstalls.size(); i++) {
15673                    final PostInstallData data = mRunningInstalls.valueAt(i);
15674                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15675                        continue;
15676                    }
15677                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15678                        // right package; but is it for the right user?
15679                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15680                            if (userId == data.res.newUsers[uIndex]) {
15681                                if (DEBUG_BACKUP) {
15682                                    Slog.i(TAG, "Package " + pkgName
15683                                            + " being restored so deferring FIRST_LAUNCH");
15684                                }
15685                                return;
15686                            }
15687                        }
15688                    }
15689                }
15690                // didn't find it, so not being restored
15691                if (DEBUG_BACKUP) {
15692                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15693                }
15694                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15695            }
15696        });
15697    }
15698
15699    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15700        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15701                installerPkg, null, userIds);
15702    }
15703
15704    private abstract class HandlerParams {
15705        private static final int MAX_RETRIES = 4;
15706
15707        /**
15708         * Number of times startCopy() has been attempted and had a non-fatal
15709         * error.
15710         */
15711        private int mRetries = 0;
15712
15713        /** User handle for the user requesting the information or installation. */
15714        private final UserHandle mUser;
15715        String traceMethod;
15716        int traceCookie;
15717
15718        HandlerParams(UserHandle user) {
15719            mUser = user;
15720        }
15721
15722        UserHandle getUser() {
15723            return mUser;
15724        }
15725
15726        HandlerParams setTraceMethod(String traceMethod) {
15727            this.traceMethod = traceMethod;
15728            return this;
15729        }
15730
15731        HandlerParams setTraceCookie(int traceCookie) {
15732            this.traceCookie = traceCookie;
15733            return this;
15734        }
15735
15736        final boolean startCopy() {
15737            boolean res;
15738            try {
15739                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15740
15741                if (++mRetries > MAX_RETRIES) {
15742                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15743                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15744                    handleServiceError();
15745                    return false;
15746                } else {
15747                    handleStartCopy();
15748                    res = true;
15749                }
15750            } catch (RemoteException e) {
15751                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15752                mHandler.sendEmptyMessage(MCS_RECONNECT);
15753                res = false;
15754            }
15755            handleReturnCode();
15756            return res;
15757        }
15758
15759        final void serviceError() {
15760            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15761            handleServiceError();
15762            handleReturnCode();
15763        }
15764
15765        abstract void handleStartCopy() throws RemoteException;
15766        abstract void handleServiceError();
15767        abstract void handleReturnCode();
15768    }
15769
15770    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15771        for (File path : paths) {
15772            try {
15773                mcs.clearDirectory(path.getAbsolutePath());
15774            } catch (RemoteException e) {
15775            }
15776        }
15777    }
15778
15779    static class OriginInfo {
15780        /**
15781         * Location where install is coming from, before it has been
15782         * copied/renamed into place. This could be a single monolithic APK
15783         * file, or a cluster directory. This location may be untrusted.
15784         */
15785        final File file;
15786        final String cid;
15787
15788        /**
15789         * Flag indicating that {@link #file} or {@link #cid} has already been
15790         * staged, meaning downstream users don't need to defensively copy the
15791         * contents.
15792         */
15793        final boolean staged;
15794
15795        /**
15796         * Flag indicating that {@link #file} or {@link #cid} is an already
15797         * installed app that is being moved.
15798         */
15799        final boolean existing;
15800
15801        final String resolvedPath;
15802        final File resolvedFile;
15803
15804        static OriginInfo fromNothing() {
15805            return new OriginInfo(null, null, false, false);
15806        }
15807
15808        static OriginInfo fromUntrustedFile(File file) {
15809            return new OriginInfo(file, null, false, false);
15810        }
15811
15812        static OriginInfo fromExistingFile(File file) {
15813            return new OriginInfo(file, null, false, true);
15814        }
15815
15816        static OriginInfo fromStagedFile(File file) {
15817            return new OriginInfo(file, null, true, false);
15818        }
15819
15820        static OriginInfo fromStagedContainer(String cid) {
15821            return new OriginInfo(null, cid, true, false);
15822        }
15823
15824        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
15825            this.file = file;
15826            this.cid = cid;
15827            this.staged = staged;
15828            this.existing = existing;
15829
15830            if (cid != null) {
15831                resolvedPath = PackageHelper.getSdDir(cid);
15832                resolvedFile = new File(resolvedPath);
15833            } else if (file != null) {
15834                resolvedPath = file.getAbsolutePath();
15835                resolvedFile = file;
15836            } else {
15837                resolvedPath = null;
15838                resolvedFile = null;
15839            }
15840        }
15841    }
15842
15843    static class MoveInfo {
15844        final int moveId;
15845        final String fromUuid;
15846        final String toUuid;
15847        final String packageName;
15848        final String dataAppName;
15849        final int appId;
15850        final String seinfo;
15851        final int targetSdkVersion;
15852
15853        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15854                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15855            this.moveId = moveId;
15856            this.fromUuid = fromUuid;
15857            this.toUuid = toUuid;
15858            this.packageName = packageName;
15859            this.dataAppName = dataAppName;
15860            this.appId = appId;
15861            this.seinfo = seinfo;
15862            this.targetSdkVersion = targetSdkVersion;
15863        }
15864    }
15865
15866    static class VerificationInfo {
15867        /** A constant used to indicate that a uid value is not present. */
15868        public static final int NO_UID = -1;
15869
15870        /** URI referencing where the package was downloaded from. */
15871        final Uri originatingUri;
15872
15873        /** HTTP referrer URI associated with the originatingURI. */
15874        final Uri referrer;
15875
15876        /** UID of the application that the install request originated from. */
15877        final int originatingUid;
15878
15879        /** UID of application requesting the install */
15880        final int installerUid;
15881
15882        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15883            this.originatingUri = originatingUri;
15884            this.referrer = referrer;
15885            this.originatingUid = originatingUid;
15886            this.installerUid = installerUid;
15887        }
15888    }
15889
15890    class InstallParams extends HandlerParams {
15891        final OriginInfo origin;
15892        final MoveInfo move;
15893        final IPackageInstallObserver2 observer;
15894        int installFlags;
15895        final String installerPackageName;
15896        final String volumeUuid;
15897        private InstallArgs mArgs;
15898        private int mRet;
15899        final String packageAbiOverride;
15900        final String[] grantedRuntimePermissions;
15901        final VerificationInfo verificationInfo;
15902        final Certificate[][] certificates;
15903        final int installReason;
15904
15905        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15906                int installFlags, String installerPackageName, String volumeUuid,
15907                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15908                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15909            super(user);
15910            this.origin = origin;
15911            this.move = move;
15912            this.observer = observer;
15913            this.installFlags = installFlags;
15914            this.installerPackageName = installerPackageName;
15915            this.volumeUuid = volumeUuid;
15916            this.verificationInfo = verificationInfo;
15917            this.packageAbiOverride = packageAbiOverride;
15918            this.grantedRuntimePermissions = grantedPermissions;
15919            this.certificates = certificates;
15920            this.installReason = installReason;
15921        }
15922
15923        @Override
15924        public String toString() {
15925            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15926                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15927        }
15928
15929        private int installLocationPolicy(PackageInfoLite pkgLite) {
15930            String packageName = pkgLite.packageName;
15931            int installLocation = pkgLite.installLocation;
15932            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15933            // reader
15934            synchronized (mPackages) {
15935                // Currently installed package which the new package is attempting to replace or
15936                // null if no such package is installed.
15937                PackageParser.Package installedPkg = mPackages.get(packageName);
15938                // Package which currently owns the data which the new package will own if installed.
15939                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15940                // will be null whereas dataOwnerPkg will contain information about the package
15941                // which was uninstalled while keeping its data.
15942                PackageParser.Package dataOwnerPkg = installedPkg;
15943                if (dataOwnerPkg  == null) {
15944                    PackageSetting ps = mSettings.mPackages.get(packageName);
15945                    if (ps != null) {
15946                        dataOwnerPkg = ps.pkg;
15947                    }
15948                }
15949
15950                if (dataOwnerPkg != null) {
15951                    // If installed, the package will get access to data left on the device by its
15952                    // predecessor. As a security measure, this is permited only if this is not a
15953                    // version downgrade or if the predecessor package is marked as debuggable and
15954                    // a downgrade is explicitly requested.
15955                    //
15956                    // On debuggable platform builds, downgrades are permitted even for
15957                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15958                    // not offer security guarantees and thus it's OK to disable some security
15959                    // mechanisms to make debugging/testing easier on those builds. However, even on
15960                    // debuggable builds downgrades of packages are permitted only if requested via
15961                    // installFlags. This is because we aim to keep the behavior of debuggable
15962                    // platform builds as close as possible to the behavior of non-debuggable
15963                    // platform builds.
15964                    final boolean downgradeRequested =
15965                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15966                    final boolean packageDebuggable =
15967                                (dataOwnerPkg.applicationInfo.flags
15968                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15969                    final boolean downgradePermitted =
15970                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15971                    if (!downgradePermitted) {
15972                        try {
15973                            checkDowngrade(dataOwnerPkg, pkgLite);
15974                        } catch (PackageManagerException e) {
15975                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15976                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15977                        }
15978                    }
15979                }
15980
15981                if (installedPkg != null) {
15982                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15983                        // Check for updated system application.
15984                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15985                            if (onSd) {
15986                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15987                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15988                            }
15989                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15990                        } else {
15991                            if (onSd) {
15992                                // Install flag overrides everything.
15993                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15994                            }
15995                            // If current upgrade specifies particular preference
15996                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15997                                // Application explicitly specified internal.
15998                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15999                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16000                                // App explictly prefers external. Let policy decide
16001                            } else {
16002                                // Prefer previous location
16003                                if (isExternal(installedPkg)) {
16004                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16005                                }
16006                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16007                            }
16008                        }
16009                    } else {
16010                        // Invalid install. Return error code
16011                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16012                    }
16013                }
16014            }
16015            // All the special cases have been taken care of.
16016            // Return result based on recommended install location.
16017            if (onSd) {
16018                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16019            }
16020            return pkgLite.recommendedInstallLocation;
16021        }
16022
16023        /*
16024         * Invoke remote method to get package information and install
16025         * location values. Override install location based on default
16026         * policy if needed and then create install arguments based
16027         * on the install location.
16028         */
16029        public void handleStartCopy() throws RemoteException {
16030            int ret = PackageManager.INSTALL_SUCCEEDED;
16031
16032            // If we're already staged, we've firmly committed to an install location
16033            if (origin.staged) {
16034                if (origin.file != null) {
16035                    installFlags |= PackageManager.INSTALL_INTERNAL;
16036                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16037                } else if (origin.cid != null) {
16038                    installFlags |= PackageManager.INSTALL_EXTERNAL;
16039                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
16040                } else {
16041                    throw new IllegalStateException("Invalid stage location");
16042                }
16043            }
16044
16045            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16046            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16047            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16048            PackageInfoLite pkgLite = null;
16049
16050            if (onInt && onSd) {
16051                // Check if both bits are set.
16052                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16053                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16054            } else if (onSd && ephemeral) {
16055                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16056                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16057            } else {
16058                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16059                        packageAbiOverride);
16060
16061                if (DEBUG_EPHEMERAL && ephemeral) {
16062                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
16063                }
16064
16065                /*
16066                 * If we have too little free space, try to free cache
16067                 * before giving up.
16068                 */
16069                if (!origin.staged && pkgLite.recommendedInstallLocation
16070                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16071                    // TODO: focus freeing disk space on the target device
16072                    final StorageManager storage = StorageManager.from(mContext);
16073                    final long lowThreshold = storage.getStorageLowBytes(
16074                            Environment.getDataDirectory());
16075
16076                    final long sizeBytes = mContainerService.calculateInstalledSize(
16077                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16078
16079                    try {
16080                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16081                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16082                                installFlags, packageAbiOverride);
16083                    } catch (InstallerException e) {
16084                        Slog.w(TAG, "Failed to free cache", e);
16085                    }
16086
16087                    /*
16088                     * The cache free must have deleted the file we
16089                     * downloaded to install.
16090                     *
16091                     * TODO: fix the "freeCache" call to not delete
16092                     *       the file we care about.
16093                     */
16094                    if (pkgLite.recommendedInstallLocation
16095                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16096                        pkgLite.recommendedInstallLocation
16097                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16098                    }
16099                }
16100            }
16101
16102            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16103                int loc = pkgLite.recommendedInstallLocation;
16104                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16105                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16106                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16107                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16108                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16109                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16110                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16111                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16112                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16113                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16114                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16115                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16116                } else {
16117                    // Override with defaults if needed.
16118                    loc = installLocationPolicy(pkgLite);
16119                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16120                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16121                    } else if (!onSd && !onInt) {
16122                        // Override install location with flags
16123                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16124                            // Set the flag to install on external media.
16125                            installFlags |= PackageManager.INSTALL_EXTERNAL;
16126                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
16127                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16128                            if (DEBUG_EPHEMERAL) {
16129                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16130                            }
16131                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
16132                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16133                                    |PackageManager.INSTALL_INTERNAL);
16134                        } else {
16135                            // Make sure the flag for installing on external
16136                            // media is unset
16137                            installFlags |= PackageManager.INSTALL_INTERNAL;
16138                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16139                        }
16140                    }
16141                }
16142            }
16143
16144            final InstallArgs args = createInstallArgs(this);
16145            mArgs = args;
16146
16147            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16148                // TODO: http://b/22976637
16149                // Apps installed for "all" users use the device owner to verify the app
16150                UserHandle verifierUser = getUser();
16151                if (verifierUser == UserHandle.ALL) {
16152                    verifierUser = UserHandle.SYSTEM;
16153                }
16154
16155                /*
16156                 * Determine if we have any installed package verifiers. If we
16157                 * do, then we'll defer to them to verify the packages.
16158                 */
16159                final int requiredUid = mRequiredVerifierPackage == null ? -1
16160                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16161                                verifierUser.getIdentifier());
16162                final int installerUid =
16163                        verificationInfo == null ? -1 : verificationInfo.installerUid;
16164                if (!origin.existing && requiredUid != -1
16165                        && isVerificationEnabled(
16166                                verifierUser.getIdentifier(), installFlags, installerUid)) {
16167                    final Intent verification = new Intent(
16168                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16169                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16170                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16171                            PACKAGE_MIME_TYPE);
16172                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16173
16174                    // Query all live verifiers based on current user state
16175                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16176                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
16177
16178                    if (DEBUG_VERIFY) {
16179                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16180                                + verification.toString() + " with " + pkgLite.verifiers.length
16181                                + " optional verifiers");
16182                    }
16183
16184                    final int verificationId = mPendingVerificationToken++;
16185
16186                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16187
16188                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16189                            installerPackageName);
16190
16191                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16192                            installFlags);
16193
16194                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16195                            pkgLite.packageName);
16196
16197                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16198                            pkgLite.versionCode);
16199
16200                    if (verificationInfo != null) {
16201                        if (verificationInfo.originatingUri != null) {
16202                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16203                                    verificationInfo.originatingUri);
16204                        }
16205                        if (verificationInfo.referrer != null) {
16206                            verification.putExtra(Intent.EXTRA_REFERRER,
16207                                    verificationInfo.referrer);
16208                        }
16209                        if (verificationInfo.originatingUid >= 0) {
16210                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16211                                    verificationInfo.originatingUid);
16212                        }
16213                        if (verificationInfo.installerUid >= 0) {
16214                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16215                                    verificationInfo.installerUid);
16216                        }
16217                    }
16218
16219                    final PackageVerificationState verificationState = new PackageVerificationState(
16220                            requiredUid, args);
16221
16222                    mPendingVerification.append(verificationId, verificationState);
16223
16224                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16225                            receivers, verificationState);
16226
16227                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
16228                    final long idleDuration = getVerificationTimeout();
16229
16230                    /*
16231                     * If any sufficient verifiers were listed in the package
16232                     * manifest, attempt to ask them.
16233                     */
16234                    if (sufficientVerifiers != null) {
16235                        final int N = sufficientVerifiers.size();
16236                        if (N == 0) {
16237                            Slog.i(TAG, "Additional verifiers required, but none installed.");
16238                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16239                        } else {
16240                            for (int i = 0; i < N; i++) {
16241                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
16242                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16243                                        verifierComponent.getPackageName(), idleDuration,
16244                                        verifierUser.getIdentifier(), false, "package verifier");
16245
16246                                final Intent sufficientIntent = new Intent(verification);
16247                                sufficientIntent.setComponent(verifierComponent);
16248                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16249                            }
16250                        }
16251                    }
16252
16253                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16254                            mRequiredVerifierPackage, receivers);
16255                    if (ret == PackageManager.INSTALL_SUCCEEDED
16256                            && mRequiredVerifierPackage != null) {
16257                        Trace.asyncTraceBegin(
16258                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16259                        /*
16260                         * Send the intent to the required verification agent,
16261                         * but only start the verification timeout after the
16262                         * target BroadcastReceivers have run.
16263                         */
16264                        verification.setComponent(requiredVerifierComponent);
16265                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16266                                mRequiredVerifierPackage, idleDuration,
16267                                verifierUser.getIdentifier(), false, "package verifier");
16268                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16269                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16270                                new BroadcastReceiver() {
16271                                    @Override
16272                                    public void onReceive(Context context, Intent intent) {
16273                                        final Message msg = mHandler
16274                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
16275                                        msg.arg1 = verificationId;
16276                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16277                                    }
16278                                }, null, 0, null, null);
16279
16280                        /*
16281                         * We don't want the copy to proceed until verification
16282                         * succeeds, so null out this field.
16283                         */
16284                        mArgs = null;
16285                    }
16286                } else {
16287                    /*
16288                     * No package verification is enabled, so immediately start
16289                     * the remote call to initiate copy using temporary file.
16290                     */
16291                    ret = args.copyApk(mContainerService, true);
16292                }
16293            }
16294
16295            mRet = ret;
16296        }
16297
16298        @Override
16299        void handleReturnCode() {
16300            // If mArgs is null, then MCS couldn't be reached. When it
16301            // reconnects, it will try again to install. At that point, this
16302            // will succeed.
16303            if (mArgs != null) {
16304                processPendingInstall(mArgs, mRet);
16305            }
16306        }
16307
16308        @Override
16309        void handleServiceError() {
16310            mArgs = createInstallArgs(this);
16311            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16312        }
16313
16314        public boolean isForwardLocked() {
16315            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16316        }
16317    }
16318
16319    /**
16320     * Used during creation of InstallArgs
16321     *
16322     * @param installFlags package installation flags
16323     * @return true if should be installed on external storage
16324     */
16325    private static boolean installOnExternalAsec(int installFlags) {
16326        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16327            return false;
16328        }
16329        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16330            return true;
16331        }
16332        return false;
16333    }
16334
16335    /**
16336     * Used during creation of InstallArgs
16337     *
16338     * @param installFlags package installation flags
16339     * @return true if should be installed as forward locked
16340     */
16341    private static boolean installForwardLocked(int installFlags) {
16342        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16343    }
16344
16345    private InstallArgs createInstallArgs(InstallParams params) {
16346        if (params.move != null) {
16347            return new MoveInstallArgs(params);
16348        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16349            return new AsecInstallArgs(params);
16350        } else {
16351            return new FileInstallArgs(params);
16352        }
16353    }
16354
16355    /**
16356     * Create args that describe an existing installed package. Typically used
16357     * when cleaning up old installs, or used as a move source.
16358     */
16359    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16360            String resourcePath, String[] instructionSets) {
16361        final boolean isInAsec;
16362        if (installOnExternalAsec(installFlags)) {
16363            /* Apps on SD card are always in ASEC containers. */
16364            isInAsec = true;
16365        } else if (installForwardLocked(installFlags)
16366                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16367            /*
16368             * Forward-locked apps are only in ASEC containers if they're the
16369             * new style
16370             */
16371            isInAsec = true;
16372        } else {
16373            isInAsec = false;
16374        }
16375
16376        if (isInAsec) {
16377            return new AsecInstallArgs(codePath, instructionSets,
16378                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16379        } else {
16380            return new FileInstallArgs(codePath, resourcePath, instructionSets);
16381        }
16382    }
16383
16384    static abstract class InstallArgs {
16385        /** @see InstallParams#origin */
16386        final OriginInfo origin;
16387        /** @see InstallParams#move */
16388        final MoveInfo move;
16389
16390        final IPackageInstallObserver2 observer;
16391        // Always refers to PackageManager flags only
16392        final int installFlags;
16393        final String installerPackageName;
16394        final String volumeUuid;
16395        final UserHandle user;
16396        final String abiOverride;
16397        final String[] installGrantPermissions;
16398        /** If non-null, drop an async trace when the install completes */
16399        final String traceMethod;
16400        final int traceCookie;
16401        final Certificate[][] certificates;
16402        final int installReason;
16403
16404        // The list of instruction sets supported by this app. This is currently
16405        // only used during the rmdex() phase to clean up resources. We can get rid of this
16406        // if we move dex files under the common app path.
16407        /* nullable */ String[] instructionSets;
16408
16409        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16410                int installFlags, String installerPackageName, String volumeUuid,
16411                UserHandle user, String[] instructionSets,
16412                String abiOverride, String[] installGrantPermissions,
16413                String traceMethod, int traceCookie, Certificate[][] certificates,
16414                int installReason) {
16415            this.origin = origin;
16416            this.move = move;
16417            this.installFlags = installFlags;
16418            this.observer = observer;
16419            this.installerPackageName = installerPackageName;
16420            this.volumeUuid = volumeUuid;
16421            this.user = user;
16422            this.instructionSets = instructionSets;
16423            this.abiOverride = abiOverride;
16424            this.installGrantPermissions = installGrantPermissions;
16425            this.traceMethod = traceMethod;
16426            this.traceCookie = traceCookie;
16427            this.certificates = certificates;
16428            this.installReason = installReason;
16429        }
16430
16431        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16432        abstract int doPreInstall(int status);
16433
16434        /**
16435         * Rename package into final resting place. All paths on the given
16436         * scanned package should be updated to reflect the rename.
16437         */
16438        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16439        abstract int doPostInstall(int status, int uid);
16440
16441        /** @see PackageSettingBase#codePathString */
16442        abstract String getCodePath();
16443        /** @see PackageSettingBase#resourcePathString */
16444        abstract String getResourcePath();
16445
16446        // Need installer lock especially for dex file removal.
16447        abstract void cleanUpResourcesLI();
16448        abstract boolean doPostDeleteLI(boolean delete);
16449
16450        /**
16451         * Called before the source arguments are copied. This is used mostly
16452         * for MoveParams when it needs to read the source file to put it in the
16453         * destination.
16454         */
16455        int doPreCopy() {
16456            return PackageManager.INSTALL_SUCCEEDED;
16457        }
16458
16459        /**
16460         * Called after the source arguments are copied. This is used mostly for
16461         * MoveParams when it needs to read the source file to put it in the
16462         * destination.
16463         */
16464        int doPostCopy(int uid) {
16465            return PackageManager.INSTALL_SUCCEEDED;
16466        }
16467
16468        protected boolean isFwdLocked() {
16469            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16470        }
16471
16472        protected boolean isExternalAsec() {
16473            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16474        }
16475
16476        protected boolean isEphemeral() {
16477            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16478        }
16479
16480        UserHandle getUser() {
16481            return user;
16482        }
16483    }
16484
16485    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16486        if (!allCodePaths.isEmpty()) {
16487            if (instructionSets == null) {
16488                throw new IllegalStateException("instructionSet == null");
16489            }
16490            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16491            for (String codePath : allCodePaths) {
16492                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16493                    try {
16494                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16495                    } catch (InstallerException ignored) {
16496                    }
16497                }
16498            }
16499        }
16500    }
16501
16502    /**
16503     * Logic to handle installation of non-ASEC applications, including copying
16504     * and renaming logic.
16505     */
16506    class FileInstallArgs extends InstallArgs {
16507        private File codeFile;
16508        private File resourceFile;
16509
16510        // Example topology:
16511        // /data/app/com.example/base.apk
16512        // /data/app/com.example/split_foo.apk
16513        // /data/app/com.example/lib/arm/libfoo.so
16514        // /data/app/com.example/lib/arm64/libfoo.so
16515        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16516
16517        /** New install */
16518        FileInstallArgs(InstallParams params) {
16519            super(params.origin, params.move, params.observer, params.installFlags,
16520                    params.installerPackageName, params.volumeUuid,
16521                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16522                    params.grantedRuntimePermissions,
16523                    params.traceMethod, params.traceCookie, params.certificates,
16524                    params.installReason);
16525            if (isFwdLocked()) {
16526                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16527            }
16528        }
16529
16530        /** Existing install */
16531        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16532            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16533                    null, null, null, 0, null /*certificates*/,
16534                    PackageManager.INSTALL_REASON_UNKNOWN);
16535            this.codeFile = (codePath != null) ? new File(codePath) : null;
16536            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16537        }
16538
16539        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16540            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16541            try {
16542                return doCopyApk(imcs, temp);
16543            } finally {
16544                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16545            }
16546        }
16547
16548        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16549            if (origin.staged) {
16550                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16551                codeFile = origin.file;
16552                resourceFile = origin.file;
16553                return PackageManager.INSTALL_SUCCEEDED;
16554            }
16555
16556            try {
16557                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16558                final File tempDir =
16559                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16560                codeFile = tempDir;
16561                resourceFile = tempDir;
16562            } catch (IOException e) {
16563                Slog.w(TAG, "Failed to create copy file: " + e);
16564                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16565            }
16566
16567            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16568                @Override
16569                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16570                    if (!FileUtils.isValidExtFilename(name)) {
16571                        throw new IllegalArgumentException("Invalid filename: " + name);
16572                    }
16573                    try {
16574                        final File file = new File(codeFile, name);
16575                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16576                                O_RDWR | O_CREAT, 0644);
16577                        Os.chmod(file.getAbsolutePath(), 0644);
16578                        return new ParcelFileDescriptor(fd);
16579                    } catch (ErrnoException e) {
16580                        throw new RemoteException("Failed to open: " + e.getMessage());
16581                    }
16582                }
16583            };
16584
16585            int ret = PackageManager.INSTALL_SUCCEEDED;
16586            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16587            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16588                Slog.e(TAG, "Failed to copy package");
16589                return ret;
16590            }
16591
16592            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16593            NativeLibraryHelper.Handle handle = null;
16594            try {
16595                handle = NativeLibraryHelper.Handle.create(codeFile);
16596                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16597                        abiOverride);
16598            } catch (IOException e) {
16599                Slog.e(TAG, "Copying native libraries failed", e);
16600                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16601            } finally {
16602                IoUtils.closeQuietly(handle);
16603            }
16604
16605            return ret;
16606        }
16607
16608        int doPreInstall(int status) {
16609            if (status != PackageManager.INSTALL_SUCCEEDED) {
16610                cleanUp();
16611            }
16612            return status;
16613        }
16614
16615        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16616            if (status != PackageManager.INSTALL_SUCCEEDED) {
16617                cleanUp();
16618                return false;
16619            }
16620
16621            final File targetDir = codeFile.getParentFile();
16622            final File beforeCodeFile = codeFile;
16623            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16624
16625            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16626            try {
16627                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16628            } catch (ErrnoException e) {
16629                Slog.w(TAG, "Failed to rename", e);
16630                return false;
16631            }
16632
16633            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16634                Slog.w(TAG, "Failed to restorecon");
16635                return false;
16636            }
16637
16638            // Reflect the rename internally
16639            codeFile = afterCodeFile;
16640            resourceFile = afterCodeFile;
16641
16642            // Reflect the rename in scanned details
16643            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16644            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16645                    afterCodeFile, pkg.baseCodePath));
16646            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16647                    afterCodeFile, pkg.splitCodePaths));
16648
16649            // Reflect the rename in app info
16650            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16651            pkg.setApplicationInfoCodePath(pkg.codePath);
16652            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16653            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16654            pkg.setApplicationInfoResourcePath(pkg.codePath);
16655            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16656            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16657
16658            return true;
16659        }
16660
16661        int doPostInstall(int status, int uid) {
16662            if (status != PackageManager.INSTALL_SUCCEEDED) {
16663                cleanUp();
16664            }
16665            return status;
16666        }
16667
16668        @Override
16669        String getCodePath() {
16670            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16671        }
16672
16673        @Override
16674        String getResourcePath() {
16675            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16676        }
16677
16678        private boolean cleanUp() {
16679            if (codeFile == null || !codeFile.exists()) {
16680                return false;
16681            }
16682
16683            removeCodePathLI(codeFile);
16684
16685            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16686                resourceFile.delete();
16687            }
16688
16689            return true;
16690        }
16691
16692        void cleanUpResourcesLI() {
16693            // Try enumerating all code paths before deleting
16694            List<String> allCodePaths = Collections.EMPTY_LIST;
16695            if (codeFile != null && codeFile.exists()) {
16696                try {
16697                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16698                    allCodePaths = pkg.getAllCodePaths();
16699                } catch (PackageParserException e) {
16700                    // Ignored; we tried our best
16701                }
16702            }
16703
16704            cleanUp();
16705            removeDexFiles(allCodePaths, instructionSets);
16706        }
16707
16708        boolean doPostDeleteLI(boolean delete) {
16709            // XXX err, shouldn't we respect the delete flag?
16710            cleanUpResourcesLI();
16711            return true;
16712        }
16713    }
16714
16715    private boolean isAsecExternal(String cid) {
16716        final String asecPath = PackageHelper.getSdFilesystem(cid);
16717        return !asecPath.startsWith(mAsecInternalPath);
16718    }
16719
16720    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16721            PackageManagerException {
16722        if (copyRet < 0) {
16723            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16724                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16725                throw new PackageManagerException(copyRet, message);
16726            }
16727        }
16728    }
16729
16730    /**
16731     * Extract the StorageManagerService "container ID" from the full code path of an
16732     * .apk.
16733     */
16734    static String cidFromCodePath(String fullCodePath) {
16735        int eidx = fullCodePath.lastIndexOf("/");
16736        String subStr1 = fullCodePath.substring(0, eidx);
16737        int sidx = subStr1.lastIndexOf("/");
16738        return subStr1.substring(sidx+1, eidx);
16739    }
16740
16741    /**
16742     * Logic to handle installation of ASEC applications, including copying and
16743     * renaming logic.
16744     */
16745    class AsecInstallArgs extends InstallArgs {
16746        static final String RES_FILE_NAME = "pkg.apk";
16747        static final String PUBLIC_RES_FILE_NAME = "res.zip";
16748
16749        String cid;
16750        String packagePath;
16751        String resourcePath;
16752
16753        /** New install */
16754        AsecInstallArgs(InstallParams params) {
16755            super(params.origin, params.move, params.observer, params.installFlags,
16756                    params.installerPackageName, params.volumeUuid,
16757                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16758                    params.grantedRuntimePermissions,
16759                    params.traceMethod, params.traceCookie, params.certificates,
16760                    params.installReason);
16761        }
16762
16763        /** Existing install */
16764        AsecInstallArgs(String fullCodePath, String[] instructionSets,
16765                        boolean isExternal, boolean isForwardLocked) {
16766            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
16767                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16768                    instructionSets, null, null, null, 0, null /*certificates*/,
16769                    PackageManager.INSTALL_REASON_UNKNOWN);
16770            // Hackily pretend we're still looking at a full code path
16771            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
16772                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
16773            }
16774
16775            // Extract cid from fullCodePath
16776            int eidx = fullCodePath.lastIndexOf("/");
16777            String subStr1 = fullCodePath.substring(0, eidx);
16778            int sidx = subStr1.lastIndexOf("/");
16779            cid = subStr1.substring(sidx+1, eidx);
16780            setMountPath(subStr1);
16781        }
16782
16783        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
16784            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
16785                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16786                    instructionSets, null, null, null, 0, null /*certificates*/,
16787                    PackageManager.INSTALL_REASON_UNKNOWN);
16788            this.cid = cid;
16789            setMountPath(PackageHelper.getSdDir(cid));
16790        }
16791
16792        void createCopyFile() {
16793            cid = mInstallerService.allocateExternalStageCidLegacy();
16794        }
16795
16796        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16797            if (origin.staged && origin.cid != null) {
16798                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
16799                cid = origin.cid;
16800                setMountPath(PackageHelper.getSdDir(cid));
16801                return PackageManager.INSTALL_SUCCEEDED;
16802            }
16803
16804            if (temp) {
16805                createCopyFile();
16806            } else {
16807                /*
16808                 * Pre-emptively destroy the container since it's destroyed if
16809                 * copying fails due to it existing anyway.
16810                 */
16811                PackageHelper.destroySdDir(cid);
16812            }
16813
16814            final String newMountPath = imcs.copyPackageToContainer(
16815                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
16816                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
16817
16818            if (newMountPath != null) {
16819                setMountPath(newMountPath);
16820                return PackageManager.INSTALL_SUCCEEDED;
16821            } else {
16822                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16823            }
16824        }
16825
16826        @Override
16827        String getCodePath() {
16828            return packagePath;
16829        }
16830
16831        @Override
16832        String getResourcePath() {
16833            return resourcePath;
16834        }
16835
16836        int doPreInstall(int status) {
16837            if (status != PackageManager.INSTALL_SUCCEEDED) {
16838                // Destroy container
16839                PackageHelper.destroySdDir(cid);
16840            } else {
16841                boolean mounted = PackageHelper.isContainerMounted(cid);
16842                if (!mounted) {
16843                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
16844                            Process.SYSTEM_UID);
16845                    if (newMountPath != null) {
16846                        setMountPath(newMountPath);
16847                    } else {
16848                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16849                    }
16850                }
16851            }
16852            return status;
16853        }
16854
16855        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16856            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
16857            String newMountPath = null;
16858            if (PackageHelper.isContainerMounted(cid)) {
16859                // Unmount the container
16860                if (!PackageHelper.unMountSdDir(cid)) {
16861                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
16862                    return false;
16863                }
16864            }
16865            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16866                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
16867                        " which might be stale. Will try to clean up.");
16868                // Clean up the stale container and proceed to recreate.
16869                if (!PackageHelper.destroySdDir(newCacheId)) {
16870                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
16871                    return false;
16872                }
16873                // Successfully cleaned up stale container. Try to rename again.
16874                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16875                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
16876                            + " inspite of cleaning it up.");
16877                    return false;
16878                }
16879            }
16880            if (!PackageHelper.isContainerMounted(newCacheId)) {
16881                Slog.w(TAG, "Mounting container " + newCacheId);
16882                newMountPath = PackageHelper.mountSdDir(newCacheId,
16883                        getEncryptKey(), Process.SYSTEM_UID);
16884            } else {
16885                newMountPath = PackageHelper.getSdDir(newCacheId);
16886            }
16887            if (newMountPath == null) {
16888                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
16889                return false;
16890            }
16891            Log.i(TAG, "Succesfully renamed " + cid +
16892                    " to " + newCacheId +
16893                    " at new path: " + newMountPath);
16894            cid = newCacheId;
16895
16896            final File beforeCodeFile = new File(packagePath);
16897            setMountPath(newMountPath);
16898            final File afterCodeFile = new File(packagePath);
16899
16900            // Reflect the rename in scanned details
16901            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16902            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16903                    afterCodeFile, pkg.baseCodePath));
16904            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16905                    afterCodeFile, pkg.splitCodePaths));
16906
16907            // Reflect the rename in app info
16908            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16909            pkg.setApplicationInfoCodePath(pkg.codePath);
16910            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16911            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16912            pkg.setApplicationInfoResourcePath(pkg.codePath);
16913            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16914            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16915
16916            return true;
16917        }
16918
16919        private void setMountPath(String mountPath) {
16920            final File mountFile = new File(mountPath);
16921
16922            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16923            if (monolithicFile.exists()) {
16924                packagePath = monolithicFile.getAbsolutePath();
16925                if (isFwdLocked()) {
16926                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16927                } else {
16928                    resourcePath = packagePath;
16929                }
16930            } else {
16931                packagePath = mountFile.getAbsolutePath();
16932                resourcePath = packagePath;
16933            }
16934        }
16935
16936        int doPostInstall(int status, int uid) {
16937            if (status != PackageManager.INSTALL_SUCCEEDED) {
16938                cleanUp();
16939            } else {
16940                final int groupOwner;
16941                final String protectedFile;
16942                if (isFwdLocked()) {
16943                    groupOwner = UserHandle.getSharedAppGid(uid);
16944                    protectedFile = RES_FILE_NAME;
16945                } else {
16946                    groupOwner = -1;
16947                    protectedFile = null;
16948                }
16949
16950                if (uid < Process.FIRST_APPLICATION_UID
16951                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16952                    Slog.e(TAG, "Failed to finalize " + cid);
16953                    PackageHelper.destroySdDir(cid);
16954                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16955                }
16956
16957                boolean mounted = PackageHelper.isContainerMounted(cid);
16958                if (!mounted) {
16959                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16960                }
16961            }
16962            return status;
16963        }
16964
16965        private void cleanUp() {
16966            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16967
16968            // Destroy secure container
16969            PackageHelper.destroySdDir(cid);
16970        }
16971
16972        private List<String> getAllCodePaths() {
16973            final File codeFile = new File(getCodePath());
16974            if (codeFile != null && codeFile.exists()) {
16975                try {
16976                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16977                    return pkg.getAllCodePaths();
16978                } catch (PackageParserException e) {
16979                    // Ignored; we tried our best
16980                }
16981            }
16982            return Collections.EMPTY_LIST;
16983        }
16984
16985        void cleanUpResourcesLI() {
16986            // Enumerate all code paths before deleting
16987            cleanUpResourcesLI(getAllCodePaths());
16988        }
16989
16990        private void cleanUpResourcesLI(List<String> allCodePaths) {
16991            cleanUp();
16992            removeDexFiles(allCodePaths, instructionSets);
16993        }
16994
16995        String getPackageName() {
16996            return getAsecPackageName(cid);
16997        }
16998
16999        boolean doPostDeleteLI(boolean delete) {
17000            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17001            final List<String> allCodePaths = getAllCodePaths();
17002            boolean mounted = PackageHelper.isContainerMounted(cid);
17003            if (mounted) {
17004                // Unmount first
17005                if (PackageHelper.unMountSdDir(cid)) {
17006                    mounted = false;
17007                }
17008            }
17009            if (!mounted && delete) {
17010                cleanUpResourcesLI(allCodePaths);
17011            }
17012            return !mounted;
17013        }
17014
17015        @Override
17016        int doPreCopy() {
17017            if (isFwdLocked()) {
17018                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17019                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17020                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17021                }
17022            }
17023
17024            return PackageManager.INSTALL_SUCCEEDED;
17025        }
17026
17027        @Override
17028        int doPostCopy(int uid) {
17029            if (isFwdLocked()) {
17030                if (uid < Process.FIRST_APPLICATION_UID
17031                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17032                                RES_FILE_NAME)) {
17033                    Slog.e(TAG, "Failed to finalize " + cid);
17034                    PackageHelper.destroySdDir(cid);
17035                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17036                }
17037            }
17038
17039            return PackageManager.INSTALL_SUCCEEDED;
17040        }
17041    }
17042
17043    /**
17044     * Logic to handle movement of existing installed applications.
17045     */
17046    class MoveInstallArgs extends InstallArgs {
17047        private File codeFile;
17048        private File resourceFile;
17049
17050        /** New install */
17051        MoveInstallArgs(InstallParams params) {
17052            super(params.origin, params.move, params.observer, params.installFlags,
17053                    params.installerPackageName, params.volumeUuid,
17054                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17055                    params.grantedRuntimePermissions,
17056                    params.traceMethod, params.traceCookie, params.certificates,
17057                    params.installReason);
17058        }
17059
17060        int copyApk(IMediaContainerService imcs, boolean temp) {
17061            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17062                    + move.fromUuid + " to " + move.toUuid);
17063            synchronized (mInstaller) {
17064                try {
17065                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17066                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17067                } catch (InstallerException e) {
17068                    Slog.w(TAG, "Failed to move app", e);
17069                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17070                }
17071            }
17072
17073            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17074            resourceFile = codeFile;
17075            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17076
17077            return PackageManager.INSTALL_SUCCEEDED;
17078        }
17079
17080        int doPreInstall(int status) {
17081            if (status != PackageManager.INSTALL_SUCCEEDED) {
17082                cleanUp(move.toUuid);
17083            }
17084            return status;
17085        }
17086
17087        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17088            if (status != PackageManager.INSTALL_SUCCEEDED) {
17089                cleanUp(move.toUuid);
17090                return false;
17091            }
17092
17093            // Reflect the move in app info
17094            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17095            pkg.setApplicationInfoCodePath(pkg.codePath);
17096            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17097            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17098            pkg.setApplicationInfoResourcePath(pkg.codePath);
17099            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17100            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17101
17102            return true;
17103        }
17104
17105        int doPostInstall(int status, int uid) {
17106            if (status == PackageManager.INSTALL_SUCCEEDED) {
17107                cleanUp(move.fromUuid);
17108            } else {
17109                cleanUp(move.toUuid);
17110            }
17111            return status;
17112        }
17113
17114        @Override
17115        String getCodePath() {
17116            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17117        }
17118
17119        @Override
17120        String getResourcePath() {
17121            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17122        }
17123
17124        private boolean cleanUp(String volumeUuid) {
17125            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17126                    move.dataAppName);
17127            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17128            final int[] userIds = sUserManager.getUserIds();
17129            synchronized (mInstallLock) {
17130                // Clean up both app data and code
17131                // All package moves are frozen until finished
17132                for (int userId : userIds) {
17133                    try {
17134                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17135                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17136                    } catch (InstallerException e) {
17137                        Slog.w(TAG, String.valueOf(e));
17138                    }
17139                }
17140                removeCodePathLI(codeFile);
17141            }
17142            return true;
17143        }
17144
17145        void cleanUpResourcesLI() {
17146            throw new UnsupportedOperationException();
17147        }
17148
17149        boolean doPostDeleteLI(boolean delete) {
17150            throw new UnsupportedOperationException();
17151        }
17152    }
17153
17154    static String getAsecPackageName(String packageCid) {
17155        int idx = packageCid.lastIndexOf("-");
17156        if (idx == -1) {
17157            return packageCid;
17158        }
17159        return packageCid.substring(0, idx);
17160    }
17161
17162    // Utility method used to create code paths based on package name and available index.
17163    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17164        String idxStr = "";
17165        int idx = 1;
17166        // Fall back to default value of idx=1 if prefix is not
17167        // part of oldCodePath
17168        if (oldCodePath != null) {
17169            String subStr = oldCodePath;
17170            // Drop the suffix right away
17171            if (suffix != null && subStr.endsWith(suffix)) {
17172                subStr = subStr.substring(0, subStr.length() - suffix.length());
17173            }
17174            // If oldCodePath already contains prefix find out the
17175            // ending index to either increment or decrement.
17176            int sidx = subStr.lastIndexOf(prefix);
17177            if (sidx != -1) {
17178                subStr = subStr.substring(sidx + prefix.length());
17179                if (subStr != null) {
17180                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17181                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17182                    }
17183                    try {
17184                        idx = Integer.parseInt(subStr);
17185                        if (idx <= 1) {
17186                            idx++;
17187                        } else {
17188                            idx--;
17189                        }
17190                    } catch(NumberFormatException e) {
17191                    }
17192                }
17193            }
17194        }
17195        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17196        return prefix + idxStr;
17197    }
17198
17199    private File getNextCodePath(File targetDir, String packageName) {
17200        File result;
17201        SecureRandom random = new SecureRandom();
17202        byte[] bytes = new byte[16];
17203        do {
17204            random.nextBytes(bytes);
17205            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17206            result = new File(targetDir, packageName + "-" + suffix);
17207        } while (result.exists());
17208        return result;
17209    }
17210
17211    // Utility method that returns the relative package path with respect
17212    // to the installation directory. Like say for /data/data/com.test-1.apk
17213    // string com.test-1 is returned.
17214    static String deriveCodePathName(String codePath) {
17215        if (codePath == null) {
17216            return null;
17217        }
17218        final File codeFile = new File(codePath);
17219        final String name = codeFile.getName();
17220        if (codeFile.isDirectory()) {
17221            return name;
17222        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17223            final int lastDot = name.lastIndexOf('.');
17224            return name.substring(0, lastDot);
17225        } else {
17226            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17227            return null;
17228        }
17229    }
17230
17231    static class PackageInstalledInfo {
17232        String name;
17233        int uid;
17234        // The set of users that originally had this package installed.
17235        int[] origUsers;
17236        // The set of users that now have this package installed.
17237        int[] newUsers;
17238        PackageParser.Package pkg;
17239        int returnCode;
17240        String returnMsg;
17241        PackageRemovedInfo removedInfo;
17242        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17243
17244        public void setError(int code, String msg) {
17245            setReturnCode(code);
17246            setReturnMessage(msg);
17247            Slog.w(TAG, msg);
17248        }
17249
17250        public void setError(String msg, PackageParserException e) {
17251            setReturnCode(e.error);
17252            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17253            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17254            for (int i = 0; i < childCount; i++) {
17255                addedChildPackages.valueAt(i).setError(msg, e);
17256            }
17257            Slog.w(TAG, msg, e);
17258        }
17259
17260        public void setError(String msg, PackageManagerException e) {
17261            returnCode = e.error;
17262            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17263            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17264            for (int i = 0; i < childCount; i++) {
17265                addedChildPackages.valueAt(i).setError(msg, e);
17266            }
17267            Slog.w(TAG, msg, e);
17268        }
17269
17270        public void setReturnCode(int returnCode) {
17271            this.returnCode = returnCode;
17272            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17273            for (int i = 0; i < childCount; i++) {
17274                addedChildPackages.valueAt(i).returnCode = returnCode;
17275            }
17276        }
17277
17278        private void setReturnMessage(String returnMsg) {
17279            this.returnMsg = returnMsg;
17280            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17281            for (int i = 0; i < childCount; i++) {
17282                addedChildPackages.valueAt(i).returnMsg = returnMsg;
17283            }
17284        }
17285
17286        // In some error cases we want to convey more info back to the observer
17287        String origPackage;
17288        String origPermission;
17289    }
17290
17291    /*
17292     * Install a non-existing package.
17293     */
17294    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17295            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17296            PackageInstalledInfo res, int installReason) {
17297        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17298
17299        // Remember this for later, in case we need to rollback this install
17300        String pkgName = pkg.packageName;
17301
17302        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17303
17304        synchronized(mPackages) {
17305            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17306            if (renamedPackage != null) {
17307                // A package with the same name is already installed, though
17308                // it has been renamed to an older name.  The package we
17309                // are trying to install should be installed as an update to
17310                // the existing one, but that has not been requested, so bail.
17311                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17312                        + " without first uninstalling package running as "
17313                        + renamedPackage);
17314                return;
17315            }
17316            if (mPackages.containsKey(pkgName)) {
17317                // Don't allow installation over an existing package with the same name.
17318                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17319                        + " without first uninstalling.");
17320                return;
17321            }
17322        }
17323
17324        try {
17325            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17326                    System.currentTimeMillis(), user);
17327
17328            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17329
17330            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17331                prepareAppDataAfterInstallLIF(newPackage);
17332
17333            } else {
17334                // Remove package from internal structures, but keep around any
17335                // data that might have already existed
17336                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17337                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17338            }
17339        } catch (PackageManagerException e) {
17340            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17341        }
17342
17343        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17344    }
17345
17346    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17347        // Can't rotate keys during boot or if sharedUser.
17348        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17349                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17350            return false;
17351        }
17352        // app is using upgradeKeySets; make sure all are valid
17353        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17354        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17355        for (int i = 0; i < upgradeKeySets.length; i++) {
17356            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17357                Slog.wtf(TAG, "Package "
17358                         + (oldPs.name != null ? oldPs.name : "<null>")
17359                         + " contains upgrade-key-set reference to unknown key-set: "
17360                         + upgradeKeySets[i]
17361                         + " reverting to signatures check.");
17362                return false;
17363            }
17364        }
17365        return true;
17366    }
17367
17368    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17369        // Upgrade keysets are being used.  Determine if new package has a superset of the
17370        // required keys.
17371        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17372        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17373        for (int i = 0; i < upgradeKeySets.length; i++) {
17374            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17375            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17376                return true;
17377            }
17378        }
17379        return false;
17380    }
17381
17382    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17383        try (DigestInputStream digestStream =
17384                new DigestInputStream(new FileInputStream(file), digest)) {
17385            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17386        }
17387    }
17388
17389    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17390            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17391            int installReason) {
17392        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17393
17394        final PackageParser.Package oldPackage;
17395        final PackageSetting ps;
17396        final String pkgName = pkg.packageName;
17397        final int[] allUsers;
17398        final int[] installedUsers;
17399
17400        synchronized(mPackages) {
17401            oldPackage = mPackages.get(pkgName);
17402            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17403
17404            // don't allow upgrade to target a release SDK from a pre-release SDK
17405            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17406                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17407            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17408                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17409            if (oldTargetsPreRelease
17410                    && !newTargetsPreRelease
17411                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17412                Slog.w(TAG, "Can't install package targeting released sdk");
17413                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17414                return;
17415            }
17416
17417            ps = mSettings.mPackages.get(pkgName);
17418
17419            // verify signatures are valid
17420            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17421                if (!checkUpgradeKeySetLP(ps, pkg)) {
17422                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17423                            "New package not signed by keys specified by upgrade-keysets: "
17424                                    + pkgName);
17425                    return;
17426                }
17427            } else {
17428                // default to original signature matching
17429                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17430                        != PackageManager.SIGNATURE_MATCH) {
17431                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17432                            "New package has a different signature: " + pkgName);
17433                    return;
17434                }
17435            }
17436
17437            // don't allow a system upgrade unless the upgrade hash matches
17438            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17439                byte[] digestBytes = null;
17440                try {
17441                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17442                    updateDigest(digest, new File(pkg.baseCodePath));
17443                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17444                        for (String path : pkg.splitCodePaths) {
17445                            updateDigest(digest, new File(path));
17446                        }
17447                    }
17448                    digestBytes = digest.digest();
17449                } catch (NoSuchAlgorithmException | IOException e) {
17450                    res.setError(INSTALL_FAILED_INVALID_APK,
17451                            "Could not compute hash: " + pkgName);
17452                    return;
17453                }
17454                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17455                    res.setError(INSTALL_FAILED_INVALID_APK,
17456                            "New package fails restrict-update check: " + pkgName);
17457                    return;
17458                }
17459                // retain upgrade restriction
17460                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17461            }
17462
17463            // Check for shared user id changes
17464            String invalidPackageName =
17465                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17466            if (invalidPackageName != null) {
17467                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17468                        "Package " + invalidPackageName + " tried to change user "
17469                                + oldPackage.mSharedUserId);
17470                return;
17471            }
17472
17473            // In case of rollback, remember per-user/profile install state
17474            allUsers = sUserManager.getUserIds();
17475            installedUsers = ps.queryInstalledUsers(allUsers, true);
17476
17477            // don't allow an upgrade from full to ephemeral
17478            if (isInstantApp) {
17479                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17480                    for (int currentUser : allUsers) {
17481                        if (!ps.getInstantApp(currentUser)) {
17482                            // can't downgrade from full to instant
17483                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17484                                    + " for user: " + currentUser);
17485                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17486                            return;
17487                        }
17488                    }
17489                } else if (!ps.getInstantApp(user.getIdentifier())) {
17490                    // can't downgrade from full to instant
17491                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17492                            + " for user: " + user.getIdentifier());
17493                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17494                    return;
17495                }
17496            }
17497        }
17498
17499        // Update what is removed
17500        res.removedInfo = new PackageRemovedInfo(this);
17501        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17502        res.removedInfo.removedPackage = oldPackage.packageName;
17503        res.removedInfo.installerPackageName = ps.installerPackageName;
17504        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17505        res.removedInfo.isUpdate = true;
17506        res.removedInfo.origUsers = installedUsers;
17507        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17508        for (int i = 0; i < installedUsers.length; i++) {
17509            final int userId = installedUsers[i];
17510            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17511        }
17512
17513        final int childCount = (oldPackage.childPackages != null)
17514                ? oldPackage.childPackages.size() : 0;
17515        for (int i = 0; i < childCount; i++) {
17516            boolean childPackageUpdated = false;
17517            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17518            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17519            if (res.addedChildPackages != null) {
17520                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17521                if (childRes != null) {
17522                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17523                    childRes.removedInfo.removedPackage = childPkg.packageName;
17524                    if (childPs != null) {
17525                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17526                    }
17527                    childRes.removedInfo.isUpdate = true;
17528                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17529                    childPackageUpdated = true;
17530                }
17531            }
17532            if (!childPackageUpdated) {
17533                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17534                childRemovedRes.removedPackage = childPkg.packageName;
17535                if (childPs != null) {
17536                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17537                }
17538                childRemovedRes.isUpdate = false;
17539                childRemovedRes.dataRemoved = true;
17540                synchronized (mPackages) {
17541                    if (childPs != null) {
17542                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17543                    }
17544                }
17545                if (res.removedInfo.removedChildPackages == null) {
17546                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17547                }
17548                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17549            }
17550        }
17551
17552        boolean sysPkg = (isSystemApp(oldPackage));
17553        if (sysPkg) {
17554            // Set the system/privileged flags as needed
17555            final boolean privileged =
17556                    (oldPackage.applicationInfo.privateFlags
17557                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17558            final int systemPolicyFlags = policyFlags
17559                    | PackageParser.PARSE_IS_SYSTEM
17560                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17561
17562            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17563                    user, allUsers, installerPackageName, res, installReason);
17564        } else {
17565            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17566                    user, allUsers, installerPackageName, res, installReason);
17567        }
17568    }
17569
17570    @Override
17571    public List<String> getPreviousCodePaths(String packageName) {
17572        final int callingUid = Binder.getCallingUid();
17573        final List<String> result = new ArrayList<>();
17574        if (getInstantAppPackageName(callingUid) != null) {
17575            return result;
17576        }
17577        final PackageSetting ps = mSettings.mPackages.get(packageName);
17578        if (ps != null
17579                && ps.oldCodePaths != null
17580                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17581            result.addAll(ps.oldCodePaths);
17582        }
17583        return result;
17584    }
17585
17586    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17587            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17588            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17589            int installReason) {
17590        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17591                + deletedPackage);
17592
17593        String pkgName = deletedPackage.packageName;
17594        boolean deletedPkg = true;
17595        boolean addedPkg = false;
17596        boolean updatedSettings = false;
17597        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17598        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17599                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17600
17601        final long origUpdateTime = (pkg.mExtras != null)
17602                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17603
17604        // First delete the existing package while retaining the data directory
17605        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17606                res.removedInfo, true, pkg)) {
17607            // If the existing package wasn't successfully deleted
17608            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17609            deletedPkg = false;
17610        } else {
17611            // Successfully deleted the old package; proceed with replace.
17612
17613            // If deleted package lived in a container, give users a chance to
17614            // relinquish resources before killing.
17615            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17616                if (DEBUG_INSTALL) {
17617                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17618                }
17619                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17620                final ArrayList<String> pkgList = new ArrayList<String>(1);
17621                pkgList.add(deletedPackage.applicationInfo.packageName);
17622                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17623            }
17624
17625            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17626                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17627            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17628
17629            try {
17630                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17631                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17632                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17633                        installReason);
17634
17635                // Update the in-memory copy of the previous code paths.
17636                PackageSetting ps = mSettings.mPackages.get(pkgName);
17637                if (!killApp) {
17638                    if (ps.oldCodePaths == null) {
17639                        ps.oldCodePaths = new ArraySet<>();
17640                    }
17641                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17642                    if (deletedPackage.splitCodePaths != null) {
17643                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17644                    }
17645                } else {
17646                    ps.oldCodePaths = null;
17647                }
17648                if (ps.childPackageNames != null) {
17649                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17650                        final String childPkgName = ps.childPackageNames.get(i);
17651                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17652                        childPs.oldCodePaths = ps.oldCodePaths;
17653                    }
17654                }
17655                // set instant app status, but, only if it's explicitly specified
17656                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17657                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17658                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17659                prepareAppDataAfterInstallLIF(newPackage);
17660                addedPkg = true;
17661                mDexManager.notifyPackageUpdated(newPackage.packageName,
17662                        newPackage.baseCodePath, newPackage.splitCodePaths);
17663            } catch (PackageManagerException e) {
17664                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17665            }
17666        }
17667
17668        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17669            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17670
17671            // Revert all internal state mutations and added folders for the failed install
17672            if (addedPkg) {
17673                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17674                        res.removedInfo, true, null);
17675            }
17676
17677            // Restore the old package
17678            if (deletedPkg) {
17679                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17680                File restoreFile = new File(deletedPackage.codePath);
17681                // Parse old package
17682                boolean oldExternal = isExternal(deletedPackage);
17683                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17684                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17685                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17686                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17687                try {
17688                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17689                            null);
17690                } catch (PackageManagerException e) {
17691                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17692                            + e.getMessage());
17693                    return;
17694                }
17695
17696                synchronized (mPackages) {
17697                    // Ensure the installer package name up to date
17698                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17699
17700                    // Update permissions for restored package
17701                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17702
17703                    mSettings.writeLPr();
17704                }
17705
17706                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17707            }
17708        } else {
17709            synchronized (mPackages) {
17710                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17711                if (ps != null) {
17712                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17713                    if (res.removedInfo.removedChildPackages != null) {
17714                        final int childCount = res.removedInfo.removedChildPackages.size();
17715                        // Iterate in reverse as we may modify the collection
17716                        for (int i = childCount - 1; i >= 0; i--) {
17717                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17718                            if (res.addedChildPackages.containsKey(childPackageName)) {
17719                                res.removedInfo.removedChildPackages.removeAt(i);
17720                            } else {
17721                                PackageRemovedInfo childInfo = res.removedInfo
17722                                        .removedChildPackages.valueAt(i);
17723                                childInfo.removedForAllUsers = mPackages.get(
17724                                        childInfo.removedPackage) == null;
17725                            }
17726                        }
17727                    }
17728                }
17729            }
17730        }
17731    }
17732
17733    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17734            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17735            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17736            int installReason) {
17737        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17738                + ", old=" + deletedPackage);
17739
17740        final boolean disabledSystem;
17741
17742        // Remove existing system package
17743        removePackageLI(deletedPackage, true);
17744
17745        synchronized (mPackages) {
17746            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17747        }
17748        if (!disabledSystem) {
17749            // We didn't need to disable the .apk as a current system package,
17750            // which means we are replacing another update that is already
17751            // installed.  We need to make sure to delete the older one's .apk.
17752            res.removedInfo.args = createInstallArgsForExisting(0,
17753                    deletedPackage.applicationInfo.getCodePath(),
17754                    deletedPackage.applicationInfo.getResourcePath(),
17755                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17756        } else {
17757            res.removedInfo.args = null;
17758        }
17759
17760        // Successfully disabled the old package. Now proceed with re-installation
17761        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17762                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17763        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17764
17765        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17766        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17767                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17768
17769        PackageParser.Package newPackage = null;
17770        try {
17771            // Add the package to the internal data structures
17772            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17773
17774            // Set the update and install times
17775            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17776            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17777                    System.currentTimeMillis());
17778
17779            // Update the package dynamic state if succeeded
17780            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17781                // Now that the install succeeded make sure we remove data
17782                // directories for any child package the update removed.
17783                final int deletedChildCount = (deletedPackage.childPackages != null)
17784                        ? deletedPackage.childPackages.size() : 0;
17785                final int newChildCount = (newPackage.childPackages != null)
17786                        ? newPackage.childPackages.size() : 0;
17787                for (int i = 0; i < deletedChildCount; i++) {
17788                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
17789                    boolean childPackageDeleted = true;
17790                    for (int j = 0; j < newChildCount; j++) {
17791                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
17792                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
17793                            childPackageDeleted = false;
17794                            break;
17795                        }
17796                    }
17797                    if (childPackageDeleted) {
17798                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
17799                                deletedChildPkg.packageName);
17800                        if (ps != null && res.removedInfo.removedChildPackages != null) {
17801                            PackageRemovedInfo removedChildRes = res.removedInfo
17802                                    .removedChildPackages.get(deletedChildPkg.packageName);
17803                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
17804                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
17805                        }
17806                    }
17807                }
17808
17809                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17810                        installReason);
17811                prepareAppDataAfterInstallLIF(newPackage);
17812
17813                mDexManager.notifyPackageUpdated(newPackage.packageName,
17814                            newPackage.baseCodePath, newPackage.splitCodePaths);
17815            }
17816        } catch (PackageManagerException e) {
17817            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
17818            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17819        }
17820
17821        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17822            // Re installation failed. Restore old information
17823            // Remove new pkg information
17824            if (newPackage != null) {
17825                removeInstalledPackageLI(newPackage, true);
17826            }
17827            // Add back the old system package
17828            try {
17829                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
17830            } catch (PackageManagerException e) {
17831                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
17832            }
17833
17834            synchronized (mPackages) {
17835                if (disabledSystem) {
17836                    enableSystemPackageLPw(deletedPackage);
17837                }
17838
17839                // Ensure the installer package name up to date
17840                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17841
17842                // Update permissions for restored package
17843                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17844
17845                mSettings.writeLPr();
17846            }
17847
17848            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
17849                    + " after failed upgrade");
17850        }
17851    }
17852
17853    /**
17854     * Checks whether the parent or any of the child packages have a change shared
17855     * user. For a package to be a valid update the shred users of the parent and
17856     * the children should match. We may later support changing child shared users.
17857     * @param oldPkg The updated package.
17858     * @param newPkg The update package.
17859     * @return The shared user that change between the versions.
17860     */
17861    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
17862            PackageParser.Package newPkg) {
17863        // Check parent shared user
17864        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
17865            return newPkg.packageName;
17866        }
17867        // Check child shared users
17868        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17869        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17870        for (int i = 0; i < newChildCount; i++) {
17871            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17872            // If this child was present, did it have the same shared user?
17873            for (int j = 0; j < oldChildCount; j++) {
17874                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17875                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17876                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17877                    return newChildPkg.packageName;
17878                }
17879            }
17880        }
17881        return null;
17882    }
17883
17884    private void removeNativeBinariesLI(PackageSetting ps) {
17885        // Remove the lib path for the parent package
17886        if (ps != null) {
17887            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17888            // Remove the lib path for the child packages
17889            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17890            for (int i = 0; i < childCount; i++) {
17891                PackageSetting childPs = null;
17892                synchronized (mPackages) {
17893                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17894                }
17895                if (childPs != null) {
17896                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17897                            .legacyNativeLibraryPathString);
17898                }
17899            }
17900        }
17901    }
17902
17903    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17904        // Enable the parent package
17905        mSettings.enableSystemPackageLPw(pkg.packageName);
17906        // Enable the child packages
17907        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17908        for (int i = 0; i < childCount; i++) {
17909            PackageParser.Package childPkg = pkg.childPackages.get(i);
17910            mSettings.enableSystemPackageLPw(childPkg.packageName);
17911        }
17912    }
17913
17914    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17915            PackageParser.Package newPkg) {
17916        // Disable the parent package (parent always replaced)
17917        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17918        // Disable the child packages
17919        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17920        for (int i = 0; i < childCount; i++) {
17921            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17922            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17923            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17924        }
17925        return disabled;
17926    }
17927
17928    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17929            String installerPackageName) {
17930        // Enable the parent package
17931        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17932        // Enable the child packages
17933        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17934        for (int i = 0; i < childCount; i++) {
17935            PackageParser.Package childPkg = pkg.childPackages.get(i);
17936            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17937        }
17938    }
17939
17940    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17941        // Collect all used permissions in the UID
17942        ArraySet<String> usedPermissions = new ArraySet<>();
17943        final int packageCount = su.packages.size();
17944        for (int i = 0; i < packageCount; i++) {
17945            PackageSetting ps = su.packages.valueAt(i);
17946            if (ps.pkg == null) {
17947                continue;
17948            }
17949            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17950            for (int j = 0; j < requestedPermCount; j++) {
17951                String permission = ps.pkg.requestedPermissions.get(j);
17952                BasePermission bp = mSettings.mPermissions.get(permission);
17953                if (bp != null) {
17954                    usedPermissions.add(permission);
17955                }
17956            }
17957        }
17958
17959        PermissionsState permissionsState = su.getPermissionsState();
17960        // Prune install permissions
17961        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17962        final int installPermCount = installPermStates.size();
17963        for (int i = installPermCount - 1; i >= 0;  i--) {
17964            PermissionState permissionState = installPermStates.get(i);
17965            if (!usedPermissions.contains(permissionState.getName())) {
17966                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17967                if (bp != null) {
17968                    permissionsState.revokeInstallPermission(bp);
17969                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17970                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17971                }
17972            }
17973        }
17974
17975        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17976
17977        // Prune runtime permissions
17978        for (int userId : allUserIds) {
17979            List<PermissionState> runtimePermStates = permissionsState
17980                    .getRuntimePermissionStates(userId);
17981            final int runtimePermCount = runtimePermStates.size();
17982            for (int i = runtimePermCount - 1; i >= 0; i--) {
17983                PermissionState permissionState = runtimePermStates.get(i);
17984                if (!usedPermissions.contains(permissionState.getName())) {
17985                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17986                    if (bp != null) {
17987                        permissionsState.revokeRuntimePermission(bp, userId);
17988                        permissionsState.updatePermissionFlags(bp, userId,
17989                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17990                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17991                                runtimePermissionChangedUserIds, userId);
17992                    }
17993                }
17994            }
17995        }
17996
17997        return runtimePermissionChangedUserIds;
17998    }
17999
18000    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18001            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18002        // Update the parent package setting
18003        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18004                res, user, installReason);
18005        // Update the child packages setting
18006        final int childCount = (newPackage.childPackages != null)
18007                ? newPackage.childPackages.size() : 0;
18008        for (int i = 0; i < childCount; i++) {
18009            PackageParser.Package childPackage = newPackage.childPackages.get(i);
18010            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18011            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18012                    childRes.origUsers, childRes, user, installReason);
18013        }
18014    }
18015
18016    private void updateSettingsInternalLI(PackageParser.Package newPackage,
18017            String installerPackageName, int[] allUsers, int[] installedForUsers,
18018            PackageInstalledInfo res, UserHandle user, int installReason) {
18019        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18020
18021        String pkgName = newPackage.packageName;
18022        synchronized (mPackages) {
18023            //write settings. the installStatus will be incomplete at this stage.
18024            //note that the new package setting would have already been
18025            //added to mPackages. It hasn't been persisted yet.
18026            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18027            // TODO: Remove this write? It's also written at the end of this method
18028            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18029            mSettings.writeLPr();
18030            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18031        }
18032
18033        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18034        synchronized (mPackages) {
18035            updatePermissionsLPw(newPackage.packageName, newPackage,
18036                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18037                            ? UPDATE_PERMISSIONS_ALL : 0));
18038            // For system-bundled packages, we assume that installing an upgraded version
18039            // of the package implies that the user actually wants to run that new code,
18040            // so we enable the package.
18041            PackageSetting ps = mSettings.mPackages.get(pkgName);
18042            final int userId = user.getIdentifier();
18043            if (ps != null) {
18044                if (isSystemApp(newPackage)) {
18045                    if (DEBUG_INSTALL) {
18046                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18047                    }
18048                    // Enable system package for requested users
18049                    if (res.origUsers != null) {
18050                        for (int origUserId : res.origUsers) {
18051                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
18052                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18053                                        origUserId, installerPackageName);
18054                            }
18055                        }
18056                    }
18057                    // Also convey the prior install/uninstall state
18058                    if (allUsers != null && installedForUsers != null) {
18059                        for (int currentUserId : allUsers) {
18060                            final boolean installed = ArrayUtils.contains(
18061                                    installedForUsers, currentUserId);
18062                            if (DEBUG_INSTALL) {
18063                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
18064                            }
18065                            ps.setInstalled(installed, currentUserId);
18066                        }
18067                        // these install state changes will be persisted in the
18068                        // upcoming call to mSettings.writeLPr().
18069                    }
18070                }
18071                // It's implied that when a user requests installation, they want the app to be
18072                // installed and enabled.
18073                if (userId != UserHandle.USER_ALL) {
18074                    ps.setInstalled(true, userId);
18075                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18076                }
18077
18078                // When replacing an existing package, preserve the original install reason for all
18079                // users that had the package installed before.
18080                final Set<Integer> previousUserIds = new ArraySet<>();
18081                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18082                    final int installReasonCount = res.removedInfo.installReasons.size();
18083                    for (int i = 0; i < installReasonCount; i++) {
18084                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18085                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18086                        ps.setInstallReason(previousInstallReason, previousUserId);
18087                        previousUserIds.add(previousUserId);
18088                    }
18089                }
18090
18091                // Set install reason for users that are having the package newly installed.
18092                if (userId == UserHandle.USER_ALL) {
18093                    for (int currentUserId : sUserManager.getUserIds()) {
18094                        if (!previousUserIds.contains(currentUserId)) {
18095                            ps.setInstallReason(installReason, currentUserId);
18096                        }
18097                    }
18098                } else if (!previousUserIds.contains(userId)) {
18099                    ps.setInstallReason(installReason, userId);
18100                }
18101                mSettings.writeKernelMappingLPr(ps);
18102            }
18103            res.name = pkgName;
18104            res.uid = newPackage.applicationInfo.uid;
18105            res.pkg = newPackage;
18106            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18107            mSettings.setInstallerPackageName(pkgName, installerPackageName);
18108            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18109            //to update install status
18110            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18111            mSettings.writeLPr();
18112            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18113        }
18114
18115        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18116    }
18117
18118    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18119        try {
18120            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18121            installPackageLI(args, res);
18122        } finally {
18123            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18124        }
18125    }
18126
18127    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18128        final int installFlags = args.installFlags;
18129        final String installerPackageName = args.installerPackageName;
18130        final String volumeUuid = args.volumeUuid;
18131        final File tmpPackageFile = new File(args.getCodePath());
18132        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18133        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18134                || (args.volumeUuid != null));
18135        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18136        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18137        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18138        boolean replace = false;
18139        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18140        if (args.move != null) {
18141            // moving a complete application; perform an initial scan on the new install location
18142            scanFlags |= SCAN_INITIAL;
18143        }
18144        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18145            scanFlags |= SCAN_DONT_KILL_APP;
18146        }
18147        if (instantApp) {
18148            scanFlags |= SCAN_AS_INSTANT_APP;
18149        }
18150        if (fullApp) {
18151            scanFlags |= SCAN_AS_FULL_APP;
18152        }
18153
18154        // Result object to be returned
18155        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18156
18157        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18158
18159        // Sanity check
18160        if (instantApp && (forwardLocked || onExternal)) {
18161            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18162                    + " external=" + onExternal);
18163            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18164            return;
18165        }
18166
18167        // Retrieve PackageSettings and parse package
18168        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18169                | PackageParser.PARSE_ENFORCE_CODE
18170                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18171                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18172                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18173                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18174        PackageParser pp = new PackageParser();
18175        pp.setSeparateProcesses(mSeparateProcesses);
18176        pp.setDisplayMetrics(mMetrics);
18177        pp.setCallback(mPackageParserCallback);
18178
18179        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18180        final PackageParser.Package pkg;
18181        try {
18182            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18183        } catch (PackageParserException e) {
18184            res.setError("Failed parse during installPackageLI", e);
18185            return;
18186        } finally {
18187            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18188        }
18189
18190        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18191        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18192            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18193            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18194                    "Instant app package must target O");
18195            return;
18196        }
18197        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18198            Slog.w(TAG, "Instant app package " + pkg.packageName
18199                    + " does not target targetSandboxVersion 2");
18200            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18201                    "Instant app package must use targetSanboxVersion 2");
18202            return;
18203        }
18204
18205        if (pkg.applicationInfo.isStaticSharedLibrary()) {
18206            // Static shared libraries have synthetic package names
18207            renameStaticSharedLibraryPackage(pkg);
18208
18209            // No static shared libs on external storage
18210            if (onExternal) {
18211                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18212                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18213                        "Packages declaring static-shared libs cannot be updated");
18214                return;
18215            }
18216        }
18217
18218        // If we are installing a clustered package add results for the children
18219        if (pkg.childPackages != null) {
18220            synchronized (mPackages) {
18221                final int childCount = pkg.childPackages.size();
18222                for (int i = 0; i < childCount; i++) {
18223                    PackageParser.Package childPkg = pkg.childPackages.get(i);
18224                    PackageInstalledInfo childRes = new PackageInstalledInfo();
18225                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18226                    childRes.pkg = childPkg;
18227                    childRes.name = childPkg.packageName;
18228                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18229                    if (childPs != null) {
18230                        childRes.origUsers = childPs.queryInstalledUsers(
18231                                sUserManager.getUserIds(), true);
18232                    }
18233                    if ((mPackages.containsKey(childPkg.packageName))) {
18234                        childRes.removedInfo = new PackageRemovedInfo(this);
18235                        childRes.removedInfo.removedPackage = childPkg.packageName;
18236                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18237                    }
18238                    if (res.addedChildPackages == null) {
18239                        res.addedChildPackages = new ArrayMap<>();
18240                    }
18241                    res.addedChildPackages.put(childPkg.packageName, childRes);
18242                }
18243            }
18244        }
18245
18246        // If package doesn't declare API override, mark that we have an install
18247        // time CPU ABI override.
18248        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18249            pkg.cpuAbiOverride = args.abiOverride;
18250        }
18251
18252        String pkgName = res.name = pkg.packageName;
18253        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18254            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18255                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18256                return;
18257            }
18258        }
18259
18260        try {
18261            // either use what we've been given or parse directly from the APK
18262            if (args.certificates != null) {
18263                try {
18264                    PackageParser.populateCertificates(pkg, args.certificates);
18265                } catch (PackageParserException e) {
18266                    // there was something wrong with the certificates we were given;
18267                    // try to pull them from the APK
18268                    PackageParser.collectCertificates(pkg, parseFlags);
18269                }
18270            } else {
18271                PackageParser.collectCertificates(pkg, parseFlags);
18272            }
18273        } catch (PackageParserException e) {
18274            res.setError("Failed collect during installPackageLI", e);
18275            return;
18276        }
18277
18278        // Get rid of all references to package scan path via parser.
18279        pp = null;
18280        String oldCodePath = null;
18281        boolean systemApp = false;
18282        synchronized (mPackages) {
18283            // Check if installing already existing package
18284            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18285                String oldName = mSettings.getRenamedPackageLPr(pkgName);
18286                if (pkg.mOriginalPackages != null
18287                        && pkg.mOriginalPackages.contains(oldName)
18288                        && mPackages.containsKey(oldName)) {
18289                    // This package is derived from an original package,
18290                    // and this device has been updating from that original
18291                    // name.  We must continue using the original name, so
18292                    // rename the new package here.
18293                    pkg.setPackageName(oldName);
18294                    pkgName = pkg.packageName;
18295                    replace = true;
18296                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18297                            + oldName + " pkgName=" + pkgName);
18298                } else if (mPackages.containsKey(pkgName)) {
18299                    // This package, under its official name, already exists
18300                    // on the device; we should replace it.
18301                    replace = true;
18302                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18303                }
18304
18305                // Child packages are installed through the parent package
18306                if (pkg.parentPackage != null) {
18307                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18308                            "Package " + pkg.packageName + " is child of package "
18309                                    + pkg.parentPackage.parentPackage + ". Child packages "
18310                                    + "can be updated only through the parent package.");
18311                    return;
18312                }
18313
18314                if (replace) {
18315                    // Prevent apps opting out from runtime permissions
18316                    PackageParser.Package oldPackage = mPackages.get(pkgName);
18317                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18318                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18319                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18320                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18321                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18322                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18323                                        + " doesn't support runtime permissions but the old"
18324                                        + " target SDK " + oldTargetSdk + " does.");
18325                        return;
18326                    }
18327                    // Prevent apps from downgrading their targetSandbox.
18328                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18329                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18330                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18331                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18332                                "Package " + pkg.packageName + " new target sandbox "
18333                                + newTargetSandbox + " is incompatible with the previous value of"
18334                                + oldTargetSandbox + ".");
18335                        return;
18336                    }
18337
18338                    // Prevent installing of child packages
18339                    if (oldPackage.parentPackage != null) {
18340                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18341                                "Package " + pkg.packageName + " is child of package "
18342                                        + oldPackage.parentPackage + ". Child packages "
18343                                        + "can be updated only through the parent package.");
18344                        return;
18345                    }
18346                }
18347            }
18348
18349            PackageSetting ps = mSettings.mPackages.get(pkgName);
18350            if (ps != null) {
18351                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18352
18353                // Static shared libs have same package with different versions where
18354                // we internally use a synthetic package name to allow multiple versions
18355                // of the same package, therefore we need to compare signatures against
18356                // the package setting for the latest library version.
18357                PackageSetting signatureCheckPs = ps;
18358                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18359                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18360                    if (libraryEntry != null) {
18361                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18362                    }
18363                }
18364
18365                // Quick sanity check that we're signed correctly if updating;
18366                // we'll check this again later when scanning, but we want to
18367                // bail early here before tripping over redefined permissions.
18368                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18369                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18370                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18371                                + pkg.packageName + " upgrade keys do not match the "
18372                                + "previously installed version");
18373                        return;
18374                    }
18375                } else {
18376                    try {
18377                        verifySignaturesLP(signatureCheckPs, pkg);
18378                    } catch (PackageManagerException e) {
18379                        res.setError(e.error, e.getMessage());
18380                        return;
18381                    }
18382                }
18383
18384                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18385                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18386                    systemApp = (ps.pkg.applicationInfo.flags &
18387                            ApplicationInfo.FLAG_SYSTEM) != 0;
18388                }
18389                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18390            }
18391
18392            int N = pkg.permissions.size();
18393            for (int i = N-1; i >= 0; i--) {
18394                PackageParser.Permission perm = pkg.permissions.get(i);
18395                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18396
18397                // Don't allow anyone but the system to define ephemeral permissions.
18398                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
18399                        && !systemApp) {
18400                    Slog.w(TAG, "Non-System package " + pkg.packageName
18401                            + " attempting to delcare ephemeral permission "
18402                            + perm.info.name + "; Removing ephemeral.");
18403                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
18404                }
18405                // Check whether the newly-scanned package wants to define an already-defined perm
18406                if (bp != null) {
18407                    // If the defining package is signed with our cert, it's okay.  This
18408                    // also includes the "updating the same package" case, of course.
18409                    // "updating same package" could also involve key-rotation.
18410                    final boolean sigsOk;
18411                    if (bp.sourcePackage.equals(pkg.packageName)
18412                            && (bp.packageSetting instanceof PackageSetting)
18413                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18414                                    scanFlags))) {
18415                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18416                    } else {
18417                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18418                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18419                    }
18420                    if (!sigsOk) {
18421                        // If the owning package is the system itself, we log but allow
18422                        // install to proceed; we fail the install on all other permission
18423                        // redefinitions.
18424                        if (!bp.sourcePackage.equals("android")) {
18425                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18426                                    + pkg.packageName + " attempting to redeclare permission "
18427                                    + perm.info.name + " already owned by " + bp.sourcePackage);
18428                            res.origPermission = perm.info.name;
18429                            res.origPackage = bp.sourcePackage;
18430                            return;
18431                        } else {
18432                            Slog.w(TAG, "Package " + pkg.packageName
18433                                    + " attempting to redeclare system permission "
18434                                    + perm.info.name + "; ignoring new declaration");
18435                            pkg.permissions.remove(i);
18436                        }
18437                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18438                        // Prevent apps to change protection level to dangerous from any other
18439                        // type as this would allow a privilege escalation where an app adds a
18440                        // normal/signature permission in other app's group and later redefines
18441                        // it as dangerous leading to the group auto-grant.
18442                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18443                                == PermissionInfo.PROTECTION_DANGEROUS) {
18444                            if (bp != null && !bp.isRuntime()) {
18445                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18446                                        + "non-runtime permission " + perm.info.name
18447                                        + " to runtime; keeping old protection level");
18448                                perm.info.protectionLevel = bp.protectionLevel;
18449                            }
18450                        }
18451                    }
18452                }
18453            }
18454        }
18455
18456        if (systemApp) {
18457            if (onExternal) {
18458                // Abort update; system app can't be replaced with app on sdcard
18459                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18460                        "Cannot install updates to system apps on sdcard");
18461                return;
18462            } else if (instantApp) {
18463                // Abort update; system app can't be replaced with an instant app
18464                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18465                        "Cannot update a system app with an instant app");
18466                return;
18467            }
18468        }
18469
18470        if (args.move != null) {
18471            // We did an in-place move, so dex is ready to roll
18472            scanFlags |= SCAN_NO_DEX;
18473            scanFlags |= SCAN_MOVE;
18474
18475            synchronized (mPackages) {
18476                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18477                if (ps == null) {
18478                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18479                            "Missing settings for moved package " + pkgName);
18480                }
18481
18482                // We moved the entire application as-is, so bring over the
18483                // previously derived ABI information.
18484                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18485                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18486            }
18487
18488        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18489            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18490            scanFlags |= SCAN_NO_DEX;
18491
18492            try {
18493                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18494                    args.abiOverride : pkg.cpuAbiOverride);
18495                final boolean extractNativeLibs = !pkg.isLibrary();
18496                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18497                        extractNativeLibs, mAppLib32InstallDir);
18498            } catch (PackageManagerException pme) {
18499                Slog.e(TAG, "Error deriving application ABI", pme);
18500                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18501                return;
18502            }
18503
18504            // Shared libraries for the package need to be updated.
18505            synchronized (mPackages) {
18506                try {
18507                    updateSharedLibrariesLPr(pkg, null);
18508                } catch (PackageManagerException e) {
18509                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18510                }
18511            }
18512
18513            // dexopt can take some time to complete, so, for instant apps, we skip this
18514            // step during installation. Instead, we'll take extra time the first time the
18515            // instant app starts. It's preferred to do it this way to provide continuous
18516            // progress to the user instead of mysteriously blocking somewhere in the
18517            // middle of running an instant app. The default behaviour can be overridden
18518            // via gservices.
18519            if (!instantApp || Global.getInt(
18520                        mContext.getContentResolver(), Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0) {
18521                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18522                // Do not run PackageDexOptimizer through the local performDexOpt
18523                // method because `pkg` may not be in `mPackages` yet.
18524                //
18525                // Also, don't fail application installs if the dexopt step fails.
18526                DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18527                        REASON_INSTALL,
18528                        DexoptOptions.DEXOPT_BOOT_COMPLETE);
18529                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18530                        null /* instructionSets */,
18531                        getOrCreateCompilerPackageStats(pkg),
18532                        mDexManager.isUsedByOtherApps(pkg.packageName),
18533                        dexoptOptions);
18534                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18535            }
18536
18537            // Notify BackgroundDexOptService that the package has been changed.
18538            // If this is an update of a package which used to fail to compile,
18539            // BDOS will remove it from its blacklist.
18540            // TODO: Layering violation
18541            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18542        }
18543
18544        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18545            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18546            return;
18547        }
18548
18549        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18550
18551        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18552                "installPackageLI")) {
18553            if (replace) {
18554                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18555                    // Static libs have a synthetic package name containing the version
18556                    // and cannot be updated as an update would get a new package name,
18557                    // unless this is the exact same version code which is useful for
18558                    // development.
18559                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18560                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18561                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18562                                + "static-shared libs cannot be updated");
18563                        return;
18564                    }
18565                }
18566                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18567                        installerPackageName, res, args.installReason);
18568            } else {
18569                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18570                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18571            }
18572        }
18573
18574        synchronized (mPackages) {
18575            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18576            if (ps != null) {
18577                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18578                ps.setUpdateAvailable(false /*updateAvailable*/);
18579            }
18580
18581            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18582            for (int i = 0; i < childCount; i++) {
18583                PackageParser.Package childPkg = pkg.childPackages.get(i);
18584                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18585                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18586                if (childPs != null) {
18587                    childRes.newUsers = childPs.queryInstalledUsers(
18588                            sUserManager.getUserIds(), true);
18589                }
18590            }
18591
18592            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18593                updateSequenceNumberLP(ps, res.newUsers);
18594                updateInstantAppInstallerLocked(pkgName);
18595            }
18596        }
18597    }
18598
18599    private void startIntentFilterVerifications(int userId, boolean replacing,
18600            PackageParser.Package pkg) {
18601        if (mIntentFilterVerifierComponent == null) {
18602            Slog.w(TAG, "No IntentFilter verification will not be done as "
18603                    + "there is no IntentFilterVerifier available!");
18604            return;
18605        }
18606
18607        final int verifierUid = getPackageUid(
18608                mIntentFilterVerifierComponent.getPackageName(),
18609                MATCH_DEBUG_TRIAGED_MISSING,
18610                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18611
18612        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18613        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18614        mHandler.sendMessage(msg);
18615
18616        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18617        for (int i = 0; i < childCount; i++) {
18618            PackageParser.Package childPkg = pkg.childPackages.get(i);
18619            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18620            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18621            mHandler.sendMessage(msg);
18622        }
18623    }
18624
18625    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18626            PackageParser.Package pkg) {
18627        int size = pkg.activities.size();
18628        if (size == 0) {
18629            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18630                    "No activity, so no need to verify any IntentFilter!");
18631            return;
18632        }
18633
18634        final boolean hasDomainURLs = hasDomainURLs(pkg);
18635        if (!hasDomainURLs) {
18636            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18637                    "No domain URLs, so no need to verify any IntentFilter!");
18638            return;
18639        }
18640
18641        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18642                + " if any IntentFilter from the " + size
18643                + " Activities needs verification ...");
18644
18645        int count = 0;
18646        final String packageName = pkg.packageName;
18647
18648        synchronized (mPackages) {
18649            // If this is a new install and we see that we've already run verification for this
18650            // package, we have nothing to do: it means the state was restored from backup.
18651            if (!replacing) {
18652                IntentFilterVerificationInfo ivi =
18653                        mSettings.getIntentFilterVerificationLPr(packageName);
18654                if (ivi != null) {
18655                    if (DEBUG_DOMAIN_VERIFICATION) {
18656                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18657                                + ivi.getStatusString());
18658                    }
18659                    return;
18660                }
18661            }
18662
18663            // If any filters need to be verified, then all need to be.
18664            boolean needToVerify = false;
18665            for (PackageParser.Activity a : pkg.activities) {
18666                for (ActivityIntentInfo filter : a.intents) {
18667                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18668                        if (DEBUG_DOMAIN_VERIFICATION) {
18669                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18670                        }
18671                        needToVerify = true;
18672                        break;
18673                    }
18674                }
18675            }
18676
18677            if (needToVerify) {
18678                final int verificationId = mIntentFilterVerificationToken++;
18679                for (PackageParser.Activity a : pkg.activities) {
18680                    for (ActivityIntentInfo filter : a.intents) {
18681                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18682                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18683                                    "Verification needed for IntentFilter:" + filter.toString());
18684                            mIntentFilterVerifier.addOneIntentFilterVerification(
18685                                    verifierUid, userId, verificationId, filter, packageName);
18686                            count++;
18687                        }
18688                    }
18689                }
18690            }
18691        }
18692
18693        if (count > 0) {
18694            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18695                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18696                    +  " for userId:" + userId);
18697            mIntentFilterVerifier.startVerifications(userId);
18698        } else {
18699            if (DEBUG_DOMAIN_VERIFICATION) {
18700                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18701            }
18702        }
18703    }
18704
18705    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18706        final ComponentName cn  = filter.activity.getComponentName();
18707        final String packageName = cn.getPackageName();
18708
18709        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18710                packageName);
18711        if (ivi == null) {
18712            return true;
18713        }
18714        int status = ivi.getStatus();
18715        switch (status) {
18716            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18717            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18718                return true;
18719
18720            default:
18721                // Nothing to do
18722                return false;
18723        }
18724    }
18725
18726    private static boolean isMultiArch(ApplicationInfo info) {
18727        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18728    }
18729
18730    private static boolean isExternal(PackageParser.Package pkg) {
18731        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18732    }
18733
18734    private static boolean isExternal(PackageSetting ps) {
18735        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18736    }
18737
18738    private static boolean isSystemApp(PackageParser.Package pkg) {
18739        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18740    }
18741
18742    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18743        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18744    }
18745
18746    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18747        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18748    }
18749
18750    private static boolean isSystemApp(PackageSetting ps) {
18751        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18752    }
18753
18754    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18755        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18756    }
18757
18758    private int packageFlagsToInstallFlags(PackageSetting ps) {
18759        int installFlags = 0;
18760        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18761            // This existing package was an external ASEC install when we have
18762            // the external flag without a UUID
18763            installFlags |= PackageManager.INSTALL_EXTERNAL;
18764        }
18765        if (ps.isForwardLocked()) {
18766            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
18767        }
18768        return installFlags;
18769    }
18770
18771    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
18772        if (isExternal(pkg)) {
18773            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18774                return StorageManager.UUID_PRIMARY_PHYSICAL;
18775            } else {
18776                return pkg.volumeUuid;
18777            }
18778        } else {
18779            return StorageManager.UUID_PRIVATE_INTERNAL;
18780        }
18781    }
18782
18783    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18784        if (isExternal(pkg)) {
18785            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18786                return mSettings.getExternalVersion();
18787            } else {
18788                return mSettings.findOrCreateVersion(pkg.volumeUuid);
18789            }
18790        } else {
18791            return mSettings.getInternalVersion();
18792        }
18793    }
18794
18795    private void deleteTempPackageFiles() {
18796        final FilenameFilter filter = new FilenameFilter() {
18797            public boolean accept(File dir, String name) {
18798                return name.startsWith("vmdl") && name.endsWith(".tmp");
18799            }
18800        };
18801        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
18802            file.delete();
18803        }
18804    }
18805
18806    @Override
18807    public void deletePackageAsUser(String packageName, int versionCode,
18808            IPackageDeleteObserver observer, int userId, int flags) {
18809        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18810                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18811    }
18812
18813    @Override
18814    public void deletePackageVersioned(VersionedPackage versionedPackage,
18815            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18816        final int callingUid = Binder.getCallingUid();
18817        mContext.enforceCallingOrSelfPermission(
18818                android.Manifest.permission.DELETE_PACKAGES, null);
18819        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
18820        Preconditions.checkNotNull(versionedPackage);
18821        Preconditions.checkNotNull(observer);
18822        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
18823                PackageManager.VERSION_CODE_HIGHEST,
18824                Integer.MAX_VALUE, "versionCode must be >= -1");
18825
18826        final String packageName = versionedPackage.getPackageName();
18827        final int versionCode = versionedPackage.getVersionCode();
18828        final String internalPackageName;
18829        synchronized (mPackages) {
18830            // Normalize package name to handle renamed packages and static libs
18831            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
18832                    versionedPackage.getVersionCode());
18833        }
18834
18835        final int uid = Binder.getCallingUid();
18836        if (!isOrphaned(internalPackageName)
18837                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18838            try {
18839                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18840                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18841                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18842                observer.onUserActionRequired(intent);
18843            } catch (RemoteException re) {
18844            }
18845            return;
18846        }
18847        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18848        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18849        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18850            mContext.enforceCallingOrSelfPermission(
18851                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18852                    "deletePackage for user " + userId);
18853        }
18854
18855        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18856            try {
18857                observer.onPackageDeleted(packageName,
18858                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18859            } catch (RemoteException re) {
18860            }
18861            return;
18862        }
18863
18864        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18865            try {
18866                observer.onPackageDeleted(packageName,
18867                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18868            } catch (RemoteException re) {
18869            }
18870            return;
18871        }
18872
18873        if (DEBUG_REMOVE) {
18874            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18875                    + " deleteAllUsers: " + deleteAllUsers + " version="
18876                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18877                    ? "VERSION_CODE_HIGHEST" : versionCode));
18878        }
18879        // Queue up an async operation since the package deletion may take a little while.
18880        mHandler.post(new Runnable() {
18881            public void run() {
18882                mHandler.removeCallbacks(this);
18883                int returnCode;
18884                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18885                boolean doDeletePackage = true;
18886                if (ps != null) {
18887                    final boolean targetIsInstantApp =
18888                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18889                    doDeletePackage = !targetIsInstantApp
18890                            || canViewInstantApps;
18891                }
18892                if (doDeletePackage) {
18893                    if (!deleteAllUsers) {
18894                        returnCode = deletePackageX(internalPackageName, versionCode,
18895                                userId, deleteFlags);
18896                    } else {
18897                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
18898                                internalPackageName, users);
18899                        // If nobody is blocking uninstall, proceed with delete for all users
18900                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18901                            returnCode = deletePackageX(internalPackageName, versionCode,
18902                                    userId, deleteFlags);
18903                        } else {
18904                            // Otherwise uninstall individually for users with blockUninstalls=false
18905                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18906                            for (int userId : users) {
18907                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18908                                    returnCode = deletePackageX(internalPackageName, versionCode,
18909                                            userId, userFlags);
18910                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18911                                        Slog.w(TAG, "Package delete failed for user " + userId
18912                                                + ", returnCode " + returnCode);
18913                                    }
18914                                }
18915                            }
18916                            // The app has only been marked uninstalled for certain users.
18917                            // We still need to report that delete was blocked
18918                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18919                        }
18920                    }
18921                } else {
18922                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18923                }
18924                try {
18925                    observer.onPackageDeleted(packageName, returnCode, null);
18926                } catch (RemoteException e) {
18927                    Log.i(TAG, "Observer no longer exists.");
18928                } //end catch
18929            } //end run
18930        });
18931    }
18932
18933    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18934        if (pkg.staticSharedLibName != null) {
18935            return pkg.manifestPackageName;
18936        }
18937        return pkg.packageName;
18938    }
18939
18940    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18941        // Handle renamed packages
18942        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18943        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18944
18945        // Is this a static library?
18946        SparseArray<SharedLibraryEntry> versionedLib =
18947                mStaticLibsByDeclaringPackage.get(packageName);
18948        if (versionedLib == null || versionedLib.size() <= 0) {
18949            return packageName;
18950        }
18951
18952        // Figure out which lib versions the caller can see
18953        SparseIntArray versionsCallerCanSee = null;
18954        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18955        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18956                && callingAppId != Process.ROOT_UID) {
18957            versionsCallerCanSee = new SparseIntArray();
18958            String libName = versionedLib.valueAt(0).info.getName();
18959            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18960            if (uidPackages != null) {
18961                for (String uidPackage : uidPackages) {
18962                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18963                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18964                    if (libIdx >= 0) {
18965                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18966                        versionsCallerCanSee.append(libVersion, libVersion);
18967                    }
18968                }
18969            }
18970        }
18971
18972        // Caller can see nothing - done
18973        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18974            return packageName;
18975        }
18976
18977        // Find the version the caller can see and the app version code
18978        SharedLibraryEntry highestVersion = null;
18979        final int versionCount = versionedLib.size();
18980        for (int i = 0; i < versionCount; i++) {
18981            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18982            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18983                    libEntry.info.getVersion()) < 0) {
18984                continue;
18985            }
18986            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18987            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18988                if (libVersionCode == versionCode) {
18989                    return libEntry.apk;
18990                }
18991            } else if (highestVersion == null) {
18992                highestVersion = libEntry;
18993            } else if (libVersionCode  > highestVersion.info
18994                    .getDeclaringPackage().getVersionCode()) {
18995                highestVersion = libEntry;
18996            }
18997        }
18998
18999        if (highestVersion != null) {
19000            return highestVersion.apk;
19001        }
19002
19003        return packageName;
19004    }
19005
19006    boolean isCallerVerifier(int callingUid) {
19007        final int callingUserId = UserHandle.getUserId(callingUid);
19008        return mRequiredVerifierPackage != null &&
19009                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19010    }
19011
19012    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19013        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19014              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19015            return true;
19016        }
19017        final int callingUserId = UserHandle.getUserId(callingUid);
19018        // If the caller installed the pkgName, then allow it to silently uninstall.
19019        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19020            return true;
19021        }
19022
19023        // Allow package verifier to silently uninstall.
19024        if (mRequiredVerifierPackage != null &&
19025                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19026            return true;
19027        }
19028
19029        // Allow package uninstaller to silently uninstall.
19030        if (mRequiredUninstallerPackage != null &&
19031                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19032            return true;
19033        }
19034
19035        // Allow storage manager to silently uninstall.
19036        if (mStorageManagerPackage != null &&
19037                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19038            return true;
19039        }
19040
19041        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19042        // uninstall for device owner provisioning.
19043        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19044                == PERMISSION_GRANTED) {
19045            return true;
19046        }
19047
19048        return false;
19049    }
19050
19051    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19052        int[] result = EMPTY_INT_ARRAY;
19053        for (int userId : userIds) {
19054            if (getBlockUninstallForUser(packageName, userId)) {
19055                result = ArrayUtils.appendInt(result, userId);
19056            }
19057        }
19058        return result;
19059    }
19060
19061    @Override
19062    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19063        final int callingUid = Binder.getCallingUid();
19064        if (getInstantAppPackageName(callingUid) != null
19065                && !isCallerSameApp(packageName, callingUid)) {
19066            return false;
19067        }
19068        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19069    }
19070
19071    private boolean isPackageDeviceAdmin(String packageName, int userId) {
19072        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19073                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19074        try {
19075            if (dpm != null) {
19076                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19077                        /* callingUserOnly =*/ false);
19078                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19079                        : deviceOwnerComponentName.getPackageName();
19080                // Does the package contains the device owner?
19081                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
19082                // this check is probably not needed, since DO should be registered as a device
19083                // admin on some user too. (Original bug for this: b/17657954)
19084                if (packageName.equals(deviceOwnerPackageName)) {
19085                    return true;
19086                }
19087                // Does it contain a device admin for any user?
19088                int[] users;
19089                if (userId == UserHandle.USER_ALL) {
19090                    users = sUserManager.getUserIds();
19091                } else {
19092                    users = new int[]{userId};
19093                }
19094                for (int i = 0; i < users.length; ++i) {
19095                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19096                        return true;
19097                    }
19098                }
19099            }
19100        } catch (RemoteException e) {
19101        }
19102        return false;
19103    }
19104
19105    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19106        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19107    }
19108
19109    /**
19110     *  This method is an internal method that could be get invoked either
19111     *  to delete an installed package or to clean up a failed installation.
19112     *  After deleting an installed package, a broadcast is sent to notify any
19113     *  listeners that the package has been removed. For cleaning up a failed
19114     *  installation, the broadcast is not necessary since the package's
19115     *  installation wouldn't have sent the initial broadcast either
19116     *  The key steps in deleting a package are
19117     *  deleting the package information in internal structures like mPackages,
19118     *  deleting the packages base directories through installd
19119     *  updating mSettings to reflect current status
19120     *  persisting settings for later use
19121     *  sending a broadcast if necessary
19122     */
19123    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19124        final PackageRemovedInfo info = new PackageRemovedInfo(this);
19125        final boolean res;
19126
19127        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19128                ? UserHandle.USER_ALL : userId;
19129
19130        if (isPackageDeviceAdmin(packageName, removeUser)) {
19131            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19132            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19133        }
19134
19135        PackageSetting uninstalledPs = null;
19136        PackageParser.Package pkg = null;
19137
19138        // for the uninstall-updates case and restricted profiles, remember the per-
19139        // user handle installed state
19140        int[] allUsers;
19141        synchronized (mPackages) {
19142            uninstalledPs = mSettings.mPackages.get(packageName);
19143            if (uninstalledPs == null) {
19144                Slog.w(TAG, "Not removing non-existent package " + packageName);
19145                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19146            }
19147
19148            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19149                    && uninstalledPs.versionCode != versionCode) {
19150                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19151                        + uninstalledPs.versionCode + " != " + versionCode);
19152                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19153            }
19154
19155            // Static shared libs can be declared by any package, so let us not
19156            // allow removing a package if it provides a lib others depend on.
19157            pkg = mPackages.get(packageName);
19158
19159            allUsers = sUserManager.getUserIds();
19160
19161            if (pkg != null && pkg.staticSharedLibName != null) {
19162                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19163                        pkg.staticSharedLibVersion);
19164                if (libEntry != null) {
19165                    for (int currUserId : allUsers) {
19166                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19167                            continue;
19168                        }
19169                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19170                                libEntry.info, 0, currUserId);
19171                        if (!ArrayUtils.isEmpty(libClientPackages)) {
19172                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19173                                    + " hosting lib " + libEntry.info.getName() + " version "
19174                                    + libEntry.info.getVersion() + " used by " + libClientPackages
19175                                    + " for user " + currUserId);
19176                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19177                        }
19178                    }
19179                }
19180            }
19181
19182            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19183        }
19184
19185        final int freezeUser;
19186        if (isUpdatedSystemApp(uninstalledPs)
19187                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19188            // We're downgrading a system app, which will apply to all users, so
19189            // freeze them all during the downgrade
19190            freezeUser = UserHandle.USER_ALL;
19191        } else {
19192            freezeUser = removeUser;
19193        }
19194
19195        synchronized (mInstallLock) {
19196            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19197            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19198                    deleteFlags, "deletePackageX")) {
19199                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19200                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19201            }
19202            synchronized (mPackages) {
19203                if (res) {
19204                    if (pkg != null) {
19205                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19206                    }
19207                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19208                    updateInstantAppInstallerLocked(packageName);
19209                }
19210            }
19211        }
19212
19213        if (res) {
19214            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19215            info.sendPackageRemovedBroadcasts(killApp);
19216            info.sendSystemPackageUpdatedBroadcasts();
19217            info.sendSystemPackageAppearedBroadcasts();
19218        }
19219        // Force a gc here.
19220        Runtime.getRuntime().gc();
19221        // Delete the resources here after sending the broadcast to let
19222        // other processes clean up before deleting resources.
19223        if (info.args != null) {
19224            synchronized (mInstallLock) {
19225                info.args.doPostDeleteLI(true);
19226            }
19227        }
19228
19229        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19230    }
19231
19232    static class PackageRemovedInfo {
19233        final PackageSender packageSender;
19234        String removedPackage;
19235        String installerPackageName;
19236        int uid = -1;
19237        int removedAppId = -1;
19238        int[] origUsers;
19239        int[] removedUsers = null;
19240        int[] broadcastUsers = null;
19241        SparseArray<Integer> installReasons;
19242        boolean isRemovedPackageSystemUpdate = false;
19243        boolean isUpdate;
19244        boolean dataRemoved;
19245        boolean removedForAllUsers;
19246        boolean isStaticSharedLib;
19247        // Clean up resources deleted packages.
19248        InstallArgs args = null;
19249        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19250        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19251
19252        PackageRemovedInfo(PackageSender packageSender) {
19253            this.packageSender = packageSender;
19254        }
19255
19256        void sendPackageRemovedBroadcasts(boolean killApp) {
19257            sendPackageRemovedBroadcastInternal(killApp);
19258            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19259            for (int i = 0; i < childCount; i++) {
19260                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19261                childInfo.sendPackageRemovedBroadcastInternal(killApp);
19262            }
19263        }
19264
19265        void sendSystemPackageUpdatedBroadcasts() {
19266            if (isRemovedPackageSystemUpdate) {
19267                sendSystemPackageUpdatedBroadcastsInternal();
19268                final int childCount = (removedChildPackages != null)
19269                        ? removedChildPackages.size() : 0;
19270                for (int i = 0; i < childCount; i++) {
19271                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19272                    if (childInfo.isRemovedPackageSystemUpdate) {
19273                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19274                    }
19275                }
19276            }
19277        }
19278
19279        void sendSystemPackageAppearedBroadcasts() {
19280            final int packageCount = (appearedChildPackages != null)
19281                    ? appearedChildPackages.size() : 0;
19282            for (int i = 0; i < packageCount; i++) {
19283                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19284                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19285                    true /*sendBootCompleted*/, false /*startReceiver*/,
19286                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19287            }
19288        }
19289
19290        private void sendSystemPackageUpdatedBroadcastsInternal() {
19291            Bundle extras = new Bundle(2);
19292            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19293            extras.putBoolean(Intent.EXTRA_REPLACING, true);
19294            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19295                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19296            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19297                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19298            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19299                null, null, 0, removedPackage, null, null);
19300            if (installerPackageName != null) {
19301                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19302                        removedPackage, extras, 0 /*flags*/,
19303                        installerPackageName, null, null);
19304                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19305                        removedPackage, extras, 0 /*flags*/,
19306                        installerPackageName, null, null);
19307            }
19308        }
19309
19310        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19311            // Don't send static shared library removal broadcasts as these
19312            // libs are visible only the the apps that depend on them an one
19313            // cannot remove the library if it has a dependency.
19314            if (isStaticSharedLib) {
19315                return;
19316            }
19317            Bundle extras = new Bundle(2);
19318            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19319            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19320            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19321            if (isUpdate || isRemovedPackageSystemUpdate) {
19322                extras.putBoolean(Intent.EXTRA_REPLACING, true);
19323            }
19324            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19325            if (removedPackage != null) {
19326                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19327                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19328                if (installerPackageName != null) {
19329                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19330                            removedPackage, extras, 0 /*flags*/,
19331                            installerPackageName, null, broadcastUsers);
19332                }
19333                if (dataRemoved && !isRemovedPackageSystemUpdate) {
19334                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19335                        removedPackage, extras,
19336                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19337                        null, null, broadcastUsers);
19338                }
19339            }
19340            if (removedAppId >= 0) {
19341                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19342                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19343                    null, null, broadcastUsers);
19344            }
19345        }
19346
19347        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19348            removedUsers = userIds;
19349            if (removedUsers == null) {
19350                broadcastUsers = null;
19351                return;
19352            }
19353
19354            broadcastUsers = EMPTY_INT_ARRAY;
19355            for (int i = userIds.length - 1; i >= 0; --i) {
19356                final int userId = userIds[i];
19357                if (deletedPackageSetting.getInstantApp(userId)) {
19358                    continue;
19359                }
19360                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19361            }
19362        }
19363    }
19364
19365    /*
19366     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19367     * flag is not set, the data directory is removed as well.
19368     * make sure this flag is set for partially installed apps. If not its meaningless to
19369     * delete a partially installed application.
19370     */
19371    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19372            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19373        String packageName = ps.name;
19374        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19375        // Retrieve object to delete permissions for shared user later on
19376        final PackageParser.Package deletedPkg;
19377        final PackageSetting deletedPs;
19378        // reader
19379        synchronized (mPackages) {
19380            deletedPkg = mPackages.get(packageName);
19381            deletedPs = mSettings.mPackages.get(packageName);
19382            if (outInfo != null) {
19383                outInfo.removedPackage = packageName;
19384                outInfo.installerPackageName = ps.installerPackageName;
19385                outInfo.isStaticSharedLib = deletedPkg != null
19386                        && deletedPkg.staticSharedLibName != null;
19387                outInfo.populateUsers(deletedPs == null ? null
19388                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19389            }
19390        }
19391
19392        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19393
19394        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19395            final PackageParser.Package resolvedPkg;
19396            if (deletedPkg != null) {
19397                resolvedPkg = deletedPkg;
19398            } else {
19399                // We don't have a parsed package when it lives on an ejected
19400                // adopted storage device, so fake something together
19401                resolvedPkg = new PackageParser.Package(ps.name);
19402                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19403            }
19404            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19405                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19406            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19407            if (outInfo != null) {
19408                outInfo.dataRemoved = true;
19409            }
19410            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19411        }
19412
19413        int removedAppId = -1;
19414
19415        // writer
19416        synchronized (mPackages) {
19417            boolean installedStateChanged = false;
19418            if (deletedPs != null) {
19419                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19420                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19421                    clearDefaultBrowserIfNeeded(packageName);
19422                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19423                    removedAppId = mSettings.removePackageLPw(packageName);
19424                    if (outInfo != null) {
19425                        outInfo.removedAppId = removedAppId;
19426                    }
19427                    updatePermissionsLPw(deletedPs.name, null, 0);
19428                    if (deletedPs.sharedUser != null) {
19429                        // Remove permissions associated with package. Since runtime
19430                        // permissions are per user we have to kill the removed package
19431                        // or packages running under the shared user of the removed
19432                        // package if revoking the permissions requested only by the removed
19433                        // package is successful and this causes a change in gids.
19434                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19435                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19436                                    userId);
19437                            if (userIdToKill == UserHandle.USER_ALL
19438                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19439                                // If gids changed for this user, kill all affected packages.
19440                                mHandler.post(new Runnable() {
19441                                    @Override
19442                                    public void run() {
19443                                        // This has to happen with no lock held.
19444                                        killApplication(deletedPs.name, deletedPs.appId,
19445                                                KILL_APP_REASON_GIDS_CHANGED);
19446                                    }
19447                                });
19448                                break;
19449                            }
19450                        }
19451                    }
19452                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19453                }
19454                // make sure to preserve per-user disabled state if this removal was just
19455                // a downgrade of a system app to the factory package
19456                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19457                    if (DEBUG_REMOVE) {
19458                        Slog.d(TAG, "Propagating install state across downgrade");
19459                    }
19460                    for (int userId : allUserHandles) {
19461                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19462                        if (DEBUG_REMOVE) {
19463                            Slog.d(TAG, "    user " + userId + " => " + installed);
19464                        }
19465                        if (installed != ps.getInstalled(userId)) {
19466                            installedStateChanged = true;
19467                        }
19468                        ps.setInstalled(installed, userId);
19469                    }
19470                }
19471            }
19472            // can downgrade to reader
19473            if (writeSettings) {
19474                // Save settings now
19475                mSettings.writeLPr();
19476            }
19477            if (installedStateChanged) {
19478                mSettings.writeKernelMappingLPr(ps);
19479            }
19480        }
19481        if (removedAppId != -1) {
19482            // A user ID was deleted here. Go through all users and remove it
19483            // from KeyStore.
19484            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19485        }
19486    }
19487
19488    static boolean locationIsPrivileged(File path) {
19489        try {
19490            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19491                    .getCanonicalPath();
19492            return path.getCanonicalPath().startsWith(privilegedAppDir);
19493        } catch (IOException e) {
19494            Slog.e(TAG, "Unable to access code path " + path);
19495        }
19496        return false;
19497    }
19498
19499    /*
19500     * Tries to delete system package.
19501     */
19502    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19503            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19504            boolean writeSettings) {
19505        if (deletedPs.parentPackageName != null) {
19506            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19507            return false;
19508        }
19509
19510        final boolean applyUserRestrictions
19511                = (allUserHandles != null) && (outInfo.origUsers != null);
19512        final PackageSetting disabledPs;
19513        // Confirm if the system package has been updated
19514        // An updated system app can be deleted. This will also have to restore
19515        // the system pkg from system partition
19516        // reader
19517        synchronized (mPackages) {
19518            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19519        }
19520
19521        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19522                + " disabledPs=" + disabledPs);
19523
19524        if (disabledPs == null) {
19525            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19526            return false;
19527        } else if (DEBUG_REMOVE) {
19528            Slog.d(TAG, "Deleting system pkg from data partition");
19529        }
19530
19531        if (DEBUG_REMOVE) {
19532            if (applyUserRestrictions) {
19533                Slog.d(TAG, "Remembering install states:");
19534                for (int userId : allUserHandles) {
19535                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19536                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19537                }
19538            }
19539        }
19540
19541        // Delete the updated package
19542        outInfo.isRemovedPackageSystemUpdate = true;
19543        if (outInfo.removedChildPackages != null) {
19544            final int childCount = (deletedPs.childPackageNames != null)
19545                    ? deletedPs.childPackageNames.size() : 0;
19546            for (int i = 0; i < childCount; i++) {
19547                String childPackageName = deletedPs.childPackageNames.get(i);
19548                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19549                        .contains(childPackageName)) {
19550                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19551                            childPackageName);
19552                    if (childInfo != null) {
19553                        childInfo.isRemovedPackageSystemUpdate = true;
19554                    }
19555                }
19556            }
19557        }
19558
19559        if (disabledPs.versionCode < deletedPs.versionCode) {
19560            // Delete data for downgrades
19561            flags &= ~PackageManager.DELETE_KEEP_DATA;
19562        } else {
19563            // Preserve data by setting flag
19564            flags |= PackageManager.DELETE_KEEP_DATA;
19565        }
19566
19567        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19568                outInfo, writeSettings, disabledPs.pkg);
19569        if (!ret) {
19570            return false;
19571        }
19572
19573        // writer
19574        synchronized (mPackages) {
19575            // Reinstate the old system package
19576            enableSystemPackageLPw(disabledPs.pkg);
19577            // Remove any native libraries from the upgraded package.
19578            removeNativeBinariesLI(deletedPs);
19579        }
19580
19581        // Install the system package
19582        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19583        int parseFlags = mDefParseFlags
19584                | PackageParser.PARSE_MUST_BE_APK
19585                | PackageParser.PARSE_IS_SYSTEM
19586                | PackageParser.PARSE_IS_SYSTEM_DIR;
19587        if (locationIsPrivileged(disabledPs.codePath)) {
19588            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
19589        }
19590
19591        final PackageParser.Package newPkg;
19592        try {
19593            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
19594                0 /* currentTime */, null);
19595        } catch (PackageManagerException e) {
19596            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19597                    + e.getMessage());
19598            return false;
19599        }
19600
19601        try {
19602            // update shared libraries for the newly re-installed system package
19603            updateSharedLibrariesLPr(newPkg, null);
19604        } catch (PackageManagerException e) {
19605            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19606        }
19607
19608        prepareAppDataAfterInstallLIF(newPkg);
19609
19610        // writer
19611        synchronized (mPackages) {
19612            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
19613
19614            // Propagate the permissions state as we do not want to drop on the floor
19615            // runtime permissions. The update permissions method below will take
19616            // care of removing obsolete permissions and grant install permissions.
19617            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
19618            updatePermissionsLPw(newPkg.packageName, newPkg,
19619                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
19620
19621            if (applyUserRestrictions) {
19622                boolean installedStateChanged = false;
19623                if (DEBUG_REMOVE) {
19624                    Slog.d(TAG, "Propagating install state across reinstall");
19625                }
19626                for (int userId : allUserHandles) {
19627                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19628                    if (DEBUG_REMOVE) {
19629                        Slog.d(TAG, "    user " + userId + " => " + installed);
19630                    }
19631                    if (installed != ps.getInstalled(userId)) {
19632                        installedStateChanged = true;
19633                    }
19634                    ps.setInstalled(installed, userId);
19635
19636                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19637                }
19638                // Regardless of writeSettings we need to ensure that this restriction
19639                // state propagation is persisted
19640                mSettings.writeAllUsersPackageRestrictionsLPr();
19641                if (installedStateChanged) {
19642                    mSettings.writeKernelMappingLPr(ps);
19643                }
19644            }
19645            // can downgrade to reader here
19646            if (writeSettings) {
19647                mSettings.writeLPr();
19648            }
19649        }
19650        return true;
19651    }
19652
19653    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19654            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19655            PackageRemovedInfo outInfo, boolean writeSettings,
19656            PackageParser.Package replacingPackage) {
19657        synchronized (mPackages) {
19658            if (outInfo != null) {
19659                outInfo.uid = ps.appId;
19660            }
19661
19662            if (outInfo != null && outInfo.removedChildPackages != null) {
19663                final int childCount = (ps.childPackageNames != null)
19664                        ? ps.childPackageNames.size() : 0;
19665                for (int i = 0; i < childCount; i++) {
19666                    String childPackageName = ps.childPackageNames.get(i);
19667                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19668                    if (childPs == null) {
19669                        return false;
19670                    }
19671                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19672                            childPackageName);
19673                    if (childInfo != null) {
19674                        childInfo.uid = childPs.appId;
19675                    }
19676                }
19677            }
19678        }
19679
19680        // Delete package data from internal structures and also remove data if flag is set
19681        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19682
19683        // Delete the child packages data
19684        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19685        for (int i = 0; i < childCount; i++) {
19686            PackageSetting childPs;
19687            synchronized (mPackages) {
19688                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19689            }
19690            if (childPs != null) {
19691                PackageRemovedInfo childOutInfo = (outInfo != null
19692                        && outInfo.removedChildPackages != null)
19693                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19694                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19695                        && (replacingPackage != null
19696                        && !replacingPackage.hasChildPackage(childPs.name))
19697                        ? flags & ~DELETE_KEEP_DATA : flags;
19698                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19699                        deleteFlags, writeSettings);
19700            }
19701        }
19702
19703        // Delete application code and resources only for parent packages
19704        if (ps.parentPackageName == null) {
19705            if (deleteCodeAndResources && (outInfo != null)) {
19706                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19707                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19708                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19709            }
19710        }
19711
19712        return true;
19713    }
19714
19715    @Override
19716    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19717            int userId) {
19718        mContext.enforceCallingOrSelfPermission(
19719                android.Manifest.permission.DELETE_PACKAGES, null);
19720        synchronized (mPackages) {
19721            // Cannot block uninstall of static shared libs as they are
19722            // considered a part of the using app (emulating static linking).
19723            // Also static libs are installed always on internal storage.
19724            PackageParser.Package pkg = mPackages.get(packageName);
19725            if (pkg != null && pkg.staticSharedLibName != null) {
19726                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19727                        + " providing static shared library: " + pkg.staticSharedLibName);
19728                return false;
19729            }
19730            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19731            mSettings.writePackageRestrictionsLPr(userId);
19732        }
19733        return true;
19734    }
19735
19736    @Override
19737    public boolean getBlockUninstallForUser(String packageName, int userId) {
19738        synchronized (mPackages) {
19739            final PackageSetting ps = mSettings.mPackages.get(packageName);
19740            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19741                return false;
19742            }
19743            return mSettings.getBlockUninstallLPr(userId, packageName);
19744        }
19745    }
19746
19747    @Override
19748    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19749        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19750        synchronized (mPackages) {
19751            PackageSetting ps = mSettings.mPackages.get(packageName);
19752            if (ps == null) {
19753                Log.w(TAG, "Package doesn't exist: " + packageName);
19754                return false;
19755            }
19756            if (systemUserApp) {
19757                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19758            } else {
19759                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19760            }
19761            mSettings.writeLPr();
19762        }
19763        return true;
19764    }
19765
19766    /*
19767     * This method handles package deletion in general
19768     */
19769    private boolean deletePackageLIF(String packageName, UserHandle user,
19770            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19771            PackageRemovedInfo outInfo, boolean writeSettings,
19772            PackageParser.Package replacingPackage) {
19773        if (packageName == null) {
19774            Slog.w(TAG, "Attempt to delete null packageName.");
19775            return false;
19776        }
19777
19778        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19779
19780        PackageSetting ps;
19781        synchronized (mPackages) {
19782            ps = mSettings.mPackages.get(packageName);
19783            if (ps == null) {
19784                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19785                return false;
19786            }
19787
19788            if (ps.parentPackageName != null && (!isSystemApp(ps)
19789                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19790                if (DEBUG_REMOVE) {
19791                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19792                            + ((user == null) ? UserHandle.USER_ALL : user));
19793                }
19794                final int removedUserId = (user != null) ? user.getIdentifier()
19795                        : UserHandle.USER_ALL;
19796                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19797                    return false;
19798                }
19799                markPackageUninstalledForUserLPw(ps, user);
19800                scheduleWritePackageRestrictionsLocked(user);
19801                return true;
19802            }
19803        }
19804
19805        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19806                && user.getIdentifier() != UserHandle.USER_ALL)) {
19807            // The caller is asking that the package only be deleted for a single
19808            // user.  To do this, we just mark its uninstalled state and delete
19809            // its data. If this is a system app, we only allow this to happen if
19810            // they have set the special DELETE_SYSTEM_APP which requests different
19811            // semantics than normal for uninstalling system apps.
19812            markPackageUninstalledForUserLPw(ps, user);
19813
19814            if (!isSystemApp(ps)) {
19815                // Do not uninstall the APK if an app should be cached
19816                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19817                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19818                    // Other user still have this package installed, so all
19819                    // we need to do is clear this user's data and save that
19820                    // it is uninstalled.
19821                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19822                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19823                        return false;
19824                    }
19825                    scheduleWritePackageRestrictionsLocked(user);
19826                    return true;
19827                } else {
19828                    // We need to set it back to 'installed' so the uninstall
19829                    // broadcasts will be sent correctly.
19830                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19831                    ps.setInstalled(true, user.getIdentifier());
19832                    mSettings.writeKernelMappingLPr(ps);
19833                }
19834            } else {
19835                // This is a system app, so we assume that the
19836                // other users still have this package installed, so all
19837                // we need to do is clear this user's data and save that
19838                // it is uninstalled.
19839                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19840                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19841                    return false;
19842                }
19843                scheduleWritePackageRestrictionsLocked(user);
19844                return true;
19845            }
19846        }
19847
19848        // If we are deleting a composite package for all users, keep track
19849        // of result for each child.
19850        if (ps.childPackageNames != null && outInfo != null) {
19851            synchronized (mPackages) {
19852                final int childCount = ps.childPackageNames.size();
19853                outInfo.removedChildPackages = new ArrayMap<>(childCount);
19854                for (int i = 0; i < childCount; i++) {
19855                    String childPackageName = ps.childPackageNames.get(i);
19856                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19857                    childInfo.removedPackage = childPackageName;
19858                    childInfo.installerPackageName = ps.installerPackageName;
19859                    outInfo.removedChildPackages.put(childPackageName, childInfo);
19860                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19861                    if (childPs != null) {
19862                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19863                    }
19864                }
19865            }
19866        }
19867
19868        boolean ret = false;
19869        if (isSystemApp(ps)) {
19870            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19871            // When an updated system application is deleted we delete the existing resources
19872            // as well and fall back to existing code in system partition
19873            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19874        } else {
19875            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19876            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19877                    outInfo, writeSettings, replacingPackage);
19878        }
19879
19880        // Take a note whether we deleted the package for all users
19881        if (outInfo != null) {
19882            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19883            if (outInfo.removedChildPackages != null) {
19884                synchronized (mPackages) {
19885                    final int childCount = outInfo.removedChildPackages.size();
19886                    for (int i = 0; i < childCount; i++) {
19887                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19888                        if (childInfo != null) {
19889                            childInfo.removedForAllUsers = mPackages.get(
19890                                    childInfo.removedPackage) == null;
19891                        }
19892                    }
19893                }
19894            }
19895            // If we uninstalled an update to a system app there may be some
19896            // child packages that appeared as they are declared in the system
19897            // app but were not declared in the update.
19898            if (isSystemApp(ps)) {
19899                synchronized (mPackages) {
19900                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19901                    final int childCount = (updatedPs.childPackageNames != null)
19902                            ? updatedPs.childPackageNames.size() : 0;
19903                    for (int i = 0; i < childCount; i++) {
19904                        String childPackageName = updatedPs.childPackageNames.get(i);
19905                        if (outInfo.removedChildPackages == null
19906                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19907                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19908                            if (childPs == null) {
19909                                continue;
19910                            }
19911                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19912                            installRes.name = childPackageName;
19913                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19914                            installRes.pkg = mPackages.get(childPackageName);
19915                            installRes.uid = childPs.pkg.applicationInfo.uid;
19916                            if (outInfo.appearedChildPackages == null) {
19917                                outInfo.appearedChildPackages = new ArrayMap<>();
19918                            }
19919                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19920                        }
19921                    }
19922                }
19923            }
19924        }
19925
19926        return ret;
19927    }
19928
19929    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19930        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19931                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19932        for (int nextUserId : userIds) {
19933            if (DEBUG_REMOVE) {
19934                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19935            }
19936            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19937                    false /*installed*/,
19938                    true /*stopped*/,
19939                    true /*notLaunched*/,
19940                    false /*hidden*/,
19941                    false /*suspended*/,
19942                    false /*instantApp*/,
19943                    null /*lastDisableAppCaller*/,
19944                    null /*enabledComponents*/,
19945                    null /*disabledComponents*/,
19946                    ps.readUserState(nextUserId).domainVerificationStatus,
19947                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19948        }
19949        mSettings.writeKernelMappingLPr(ps);
19950    }
19951
19952    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19953            PackageRemovedInfo outInfo) {
19954        final PackageParser.Package pkg;
19955        synchronized (mPackages) {
19956            pkg = mPackages.get(ps.name);
19957        }
19958
19959        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19960                : new int[] {userId};
19961        for (int nextUserId : userIds) {
19962            if (DEBUG_REMOVE) {
19963                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19964                        + nextUserId);
19965            }
19966
19967            destroyAppDataLIF(pkg, userId,
19968                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19969            destroyAppProfilesLIF(pkg, userId);
19970            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19971            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19972            schedulePackageCleaning(ps.name, nextUserId, false);
19973            synchronized (mPackages) {
19974                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19975                    scheduleWritePackageRestrictionsLocked(nextUserId);
19976                }
19977                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19978            }
19979        }
19980
19981        if (outInfo != null) {
19982            outInfo.removedPackage = ps.name;
19983            outInfo.installerPackageName = ps.installerPackageName;
19984            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19985            outInfo.removedAppId = ps.appId;
19986            outInfo.removedUsers = userIds;
19987            outInfo.broadcastUsers = userIds;
19988        }
19989
19990        return true;
19991    }
19992
19993    private final class ClearStorageConnection implements ServiceConnection {
19994        IMediaContainerService mContainerService;
19995
19996        @Override
19997        public void onServiceConnected(ComponentName name, IBinder service) {
19998            synchronized (this) {
19999                mContainerService = IMediaContainerService.Stub
20000                        .asInterface(Binder.allowBlocking(service));
20001                notifyAll();
20002            }
20003        }
20004
20005        @Override
20006        public void onServiceDisconnected(ComponentName name) {
20007        }
20008    }
20009
20010    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20011        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20012
20013        final boolean mounted;
20014        if (Environment.isExternalStorageEmulated()) {
20015            mounted = true;
20016        } else {
20017            final String status = Environment.getExternalStorageState();
20018
20019            mounted = status.equals(Environment.MEDIA_MOUNTED)
20020                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20021        }
20022
20023        if (!mounted) {
20024            return;
20025        }
20026
20027        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20028        int[] users;
20029        if (userId == UserHandle.USER_ALL) {
20030            users = sUserManager.getUserIds();
20031        } else {
20032            users = new int[] { userId };
20033        }
20034        final ClearStorageConnection conn = new ClearStorageConnection();
20035        if (mContext.bindServiceAsUser(
20036                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20037            try {
20038                for (int curUser : users) {
20039                    long timeout = SystemClock.uptimeMillis() + 5000;
20040                    synchronized (conn) {
20041                        long now;
20042                        while (conn.mContainerService == null &&
20043                                (now = SystemClock.uptimeMillis()) < timeout) {
20044                            try {
20045                                conn.wait(timeout - now);
20046                            } catch (InterruptedException e) {
20047                            }
20048                        }
20049                    }
20050                    if (conn.mContainerService == null) {
20051                        return;
20052                    }
20053
20054                    final UserEnvironment userEnv = new UserEnvironment(curUser);
20055                    clearDirectory(conn.mContainerService,
20056                            userEnv.buildExternalStorageAppCacheDirs(packageName));
20057                    if (allData) {
20058                        clearDirectory(conn.mContainerService,
20059                                userEnv.buildExternalStorageAppDataDirs(packageName));
20060                        clearDirectory(conn.mContainerService,
20061                                userEnv.buildExternalStorageAppMediaDirs(packageName));
20062                    }
20063                }
20064            } finally {
20065                mContext.unbindService(conn);
20066            }
20067        }
20068    }
20069
20070    @Override
20071    public void clearApplicationProfileData(String packageName) {
20072        enforceSystemOrRoot("Only the system can clear all profile data");
20073
20074        final PackageParser.Package pkg;
20075        synchronized (mPackages) {
20076            pkg = mPackages.get(packageName);
20077        }
20078
20079        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20080            synchronized (mInstallLock) {
20081                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20082            }
20083        }
20084    }
20085
20086    @Override
20087    public void clearApplicationUserData(final String packageName,
20088            final IPackageDataObserver observer, final int userId) {
20089        mContext.enforceCallingOrSelfPermission(
20090                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20091
20092        final int callingUid = Binder.getCallingUid();
20093        enforceCrossUserPermission(callingUid, userId,
20094                true /* requireFullPermission */, false /* checkShell */, "clear application data");
20095
20096        final PackageSetting ps = mSettings.getPackageLPr(packageName);
20097        if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
20098            return;
20099        }
20100        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20101            throw new SecurityException("Cannot clear data for a protected package: "
20102                    + packageName);
20103        }
20104        // Queue up an async operation since the package deletion may take a little while.
20105        mHandler.post(new Runnable() {
20106            public void run() {
20107                mHandler.removeCallbacks(this);
20108                final boolean succeeded;
20109                try (PackageFreezer freezer = freezePackage(packageName,
20110                        "clearApplicationUserData")) {
20111                    synchronized (mInstallLock) {
20112                        succeeded = clearApplicationUserDataLIF(packageName, userId);
20113                    }
20114                    clearExternalStorageDataSync(packageName, userId, true);
20115                    synchronized (mPackages) {
20116                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20117                                packageName, userId);
20118                    }
20119                }
20120                if (succeeded) {
20121                    // invoke DeviceStorageMonitor's update method to clear any notifications
20122                    DeviceStorageMonitorInternal dsm = LocalServices
20123                            .getService(DeviceStorageMonitorInternal.class);
20124                    if (dsm != null) {
20125                        dsm.checkMemory();
20126                    }
20127                }
20128                if(observer != null) {
20129                    try {
20130                        observer.onRemoveCompleted(packageName, succeeded);
20131                    } catch (RemoteException e) {
20132                        Log.i(TAG, "Observer no longer exists.");
20133                    }
20134                } //end if observer
20135            } //end run
20136        });
20137    }
20138
20139    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20140        if (packageName == null) {
20141            Slog.w(TAG, "Attempt to delete null packageName.");
20142            return false;
20143        }
20144
20145        // Try finding details about the requested package
20146        PackageParser.Package pkg;
20147        synchronized (mPackages) {
20148            pkg = mPackages.get(packageName);
20149            if (pkg == null) {
20150                final PackageSetting ps = mSettings.mPackages.get(packageName);
20151                if (ps != null) {
20152                    pkg = ps.pkg;
20153                }
20154            }
20155
20156            if (pkg == null) {
20157                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20158                return false;
20159            }
20160
20161            PackageSetting ps = (PackageSetting) pkg.mExtras;
20162            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20163        }
20164
20165        clearAppDataLIF(pkg, userId,
20166                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20167
20168        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20169        removeKeystoreDataIfNeeded(userId, appId);
20170
20171        UserManagerInternal umInternal = getUserManagerInternal();
20172        final int flags;
20173        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20174            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20175        } else if (umInternal.isUserRunning(userId)) {
20176            flags = StorageManager.FLAG_STORAGE_DE;
20177        } else {
20178            flags = 0;
20179        }
20180        prepareAppDataContentsLIF(pkg, userId, flags);
20181
20182        return true;
20183    }
20184
20185    /**
20186     * Reverts user permission state changes (permissions and flags) in
20187     * all packages for a given user.
20188     *
20189     * @param userId The device user for which to do a reset.
20190     */
20191    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20192        final int packageCount = mPackages.size();
20193        for (int i = 0; i < packageCount; i++) {
20194            PackageParser.Package pkg = mPackages.valueAt(i);
20195            PackageSetting ps = (PackageSetting) pkg.mExtras;
20196            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20197        }
20198    }
20199
20200    private void resetNetworkPolicies(int userId) {
20201        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20202    }
20203
20204    /**
20205     * Reverts user permission state changes (permissions and flags).
20206     *
20207     * @param ps The package for which to reset.
20208     * @param userId The device user for which to do a reset.
20209     */
20210    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20211            final PackageSetting ps, final int userId) {
20212        if (ps.pkg == null) {
20213            return;
20214        }
20215
20216        // These are flags that can change base on user actions.
20217        final int userSettableMask = FLAG_PERMISSION_USER_SET
20218                | FLAG_PERMISSION_USER_FIXED
20219                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20220                | FLAG_PERMISSION_REVIEW_REQUIRED;
20221
20222        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20223                | FLAG_PERMISSION_POLICY_FIXED;
20224
20225        boolean writeInstallPermissions = false;
20226        boolean writeRuntimePermissions = false;
20227
20228        final int permissionCount = ps.pkg.requestedPermissions.size();
20229        for (int i = 0; i < permissionCount; i++) {
20230            String permission = ps.pkg.requestedPermissions.get(i);
20231
20232            BasePermission bp = mSettings.mPermissions.get(permission);
20233            if (bp == null) {
20234                continue;
20235            }
20236
20237            // If shared user we just reset the state to which only this app contributed.
20238            if (ps.sharedUser != null) {
20239                boolean used = false;
20240                final int packageCount = ps.sharedUser.packages.size();
20241                for (int j = 0; j < packageCount; j++) {
20242                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20243                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20244                            && pkg.pkg.requestedPermissions.contains(permission)) {
20245                        used = true;
20246                        break;
20247                    }
20248                }
20249                if (used) {
20250                    continue;
20251                }
20252            }
20253
20254            PermissionsState permissionsState = ps.getPermissionsState();
20255
20256            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20257
20258            // Always clear the user settable flags.
20259            final boolean hasInstallState = permissionsState.getInstallPermissionState(
20260                    bp.name) != null;
20261            // If permission review is enabled and this is a legacy app, mark the
20262            // permission as requiring a review as this is the initial state.
20263            int flags = 0;
20264            if (mPermissionReviewRequired
20265                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20266                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20267            }
20268            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20269                if (hasInstallState) {
20270                    writeInstallPermissions = true;
20271                } else {
20272                    writeRuntimePermissions = true;
20273                }
20274            }
20275
20276            // Below is only runtime permission handling.
20277            if (!bp.isRuntime()) {
20278                continue;
20279            }
20280
20281            // Never clobber system or policy.
20282            if ((oldFlags & policyOrSystemFlags) != 0) {
20283                continue;
20284            }
20285
20286            // If this permission was granted by default, make sure it is.
20287            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20288                if (permissionsState.grantRuntimePermission(bp, userId)
20289                        != PERMISSION_OPERATION_FAILURE) {
20290                    writeRuntimePermissions = true;
20291                }
20292            // If permission review is enabled the permissions for a legacy apps
20293            // are represented as constantly granted runtime ones, so don't revoke.
20294            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20295                // Otherwise, reset the permission.
20296                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20297                switch (revokeResult) {
20298                    case PERMISSION_OPERATION_SUCCESS:
20299                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20300                        writeRuntimePermissions = true;
20301                        final int appId = ps.appId;
20302                        mHandler.post(new Runnable() {
20303                            @Override
20304                            public void run() {
20305                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20306                            }
20307                        });
20308                    } break;
20309                }
20310            }
20311        }
20312
20313        // Synchronously write as we are taking permissions away.
20314        if (writeRuntimePermissions) {
20315            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20316        }
20317
20318        // Synchronously write as we are taking permissions away.
20319        if (writeInstallPermissions) {
20320            mSettings.writeLPr();
20321        }
20322    }
20323
20324    /**
20325     * Remove entries from the keystore daemon. Will only remove it if the
20326     * {@code appId} is valid.
20327     */
20328    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20329        if (appId < 0) {
20330            return;
20331        }
20332
20333        final KeyStore keyStore = KeyStore.getInstance();
20334        if (keyStore != null) {
20335            if (userId == UserHandle.USER_ALL) {
20336                for (final int individual : sUserManager.getUserIds()) {
20337                    keyStore.clearUid(UserHandle.getUid(individual, appId));
20338                }
20339            } else {
20340                keyStore.clearUid(UserHandle.getUid(userId, appId));
20341            }
20342        } else {
20343            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20344        }
20345    }
20346
20347    @Override
20348    public void deleteApplicationCacheFiles(final String packageName,
20349            final IPackageDataObserver observer) {
20350        final int userId = UserHandle.getCallingUserId();
20351        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20352    }
20353
20354    @Override
20355    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20356            final IPackageDataObserver observer) {
20357        final int callingUid = Binder.getCallingUid();
20358        mContext.enforceCallingOrSelfPermission(
20359                android.Manifest.permission.DELETE_CACHE_FILES, null);
20360        enforceCrossUserPermission(callingUid, userId,
20361                /* requireFullPermission= */ true, /* checkShell= */ false,
20362                "delete application cache files");
20363        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20364                android.Manifest.permission.ACCESS_INSTANT_APPS);
20365
20366        final PackageParser.Package pkg;
20367        synchronized (mPackages) {
20368            pkg = mPackages.get(packageName);
20369        }
20370
20371        // Queue up an async operation since the package deletion may take a little while.
20372        mHandler.post(new Runnable() {
20373            public void run() {
20374                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20375                boolean doClearData = true;
20376                if (ps != null) {
20377                    final boolean targetIsInstantApp =
20378                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20379                    doClearData = !targetIsInstantApp
20380                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20381                }
20382                if (doClearData) {
20383                    synchronized (mInstallLock) {
20384                        final int flags = StorageManager.FLAG_STORAGE_DE
20385                                | StorageManager.FLAG_STORAGE_CE;
20386                        // We're only clearing cache files, so we don't care if the
20387                        // app is unfrozen and still able to run
20388                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20389                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20390                    }
20391                    clearExternalStorageDataSync(packageName, userId, false);
20392                }
20393                if (observer != null) {
20394                    try {
20395                        observer.onRemoveCompleted(packageName, true);
20396                    } catch (RemoteException e) {
20397                        Log.i(TAG, "Observer no longer exists.");
20398                    }
20399                }
20400            }
20401        });
20402    }
20403
20404    @Override
20405    public void getPackageSizeInfo(final String packageName, int userHandle,
20406            final IPackageStatsObserver observer) {
20407        throw new UnsupportedOperationException(
20408                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20409    }
20410
20411    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20412        final PackageSetting ps;
20413        synchronized (mPackages) {
20414            ps = mSettings.mPackages.get(packageName);
20415            if (ps == null) {
20416                Slog.w(TAG, "Failed to find settings for " + packageName);
20417                return false;
20418            }
20419        }
20420
20421        final String[] packageNames = { packageName };
20422        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20423        final String[] codePaths = { ps.codePathString };
20424
20425        try {
20426            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20427                    ps.appId, ceDataInodes, codePaths, stats);
20428
20429            // For now, ignore code size of packages on system partition
20430            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20431                stats.codeSize = 0;
20432            }
20433
20434            // External clients expect these to be tracked separately
20435            stats.dataSize -= stats.cacheSize;
20436
20437        } catch (InstallerException e) {
20438            Slog.w(TAG, String.valueOf(e));
20439            return false;
20440        }
20441
20442        return true;
20443    }
20444
20445    private int getUidTargetSdkVersionLockedLPr(int uid) {
20446        Object obj = mSettings.getUserIdLPr(uid);
20447        if (obj instanceof SharedUserSetting) {
20448            final SharedUserSetting sus = (SharedUserSetting) obj;
20449            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20450            final Iterator<PackageSetting> it = sus.packages.iterator();
20451            while (it.hasNext()) {
20452                final PackageSetting ps = it.next();
20453                if (ps.pkg != null) {
20454                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20455                    if (v < vers) vers = v;
20456                }
20457            }
20458            return vers;
20459        } else if (obj instanceof PackageSetting) {
20460            final PackageSetting ps = (PackageSetting) obj;
20461            if (ps.pkg != null) {
20462                return ps.pkg.applicationInfo.targetSdkVersion;
20463            }
20464        }
20465        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20466    }
20467
20468    @Override
20469    public void addPreferredActivity(IntentFilter filter, int match,
20470            ComponentName[] set, ComponentName activity, int userId) {
20471        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20472                "Adding preferred");
20473    }
20474
20475    private void addPreferredActivityInternal(IntentFilter filter, int match,
20476            ComponentName[] set, ComponentName activity, boolean always, int userId,
20477            String opname) {
20478        // writer
20479        int callingUid = Binder.getCallingUid();
20480        enforceCrossUserPermission(callingUid, userId,
20481                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20482        if (filter.countActions() == 0) {
20483            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20484            return;
20485        }
20486        synchronized (mPackages) {
20487            if (mContext.checkCallingOrSelfPermission(
20488                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20489                    != PackageManager.PERMISSION_GRANTED) {
20490                if (getUidTargetSdkVersionLockedLPr(callingUid)
20491                        < Build.VERSION_CODES.FROYO) {
20492                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20493                            + callingUid);
20494                    return;
20495                }
20496                mContext.enforceCallingOrSelfPermission(
20497                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20498            }
20499
20500            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20501            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20502                    + userId + ":");
20503            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20504            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20505            scheduleWritePackageRestrictionsLocked(userId);
20506            postPreferredActivityChangedBroadcast(userId);
20507        }
20508    }
20509
20510    private void postPreferredActivityChangedBroadcast(int userId) {
20511        mHandler.post(() -> {
20512            final IActivityManager am = ActivityManager.getService();
20513            if (am == null) {
20514                return;
20515            }
20516
20517            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20518            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20519            try {
20520                am.broadcastIntent(null, intent, null, null,
20521                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20522                        null, false, false, userId);
20523            } catch (RemoteException e) {
20524            }
20525        });
20526    }
20527
20528    @Override
20529    public void replacePreferredActivity(IntentFilter filter, int match,
20530            ComponentName[] set, ComponentName activity, int userId) {
20531        if (filter.countActions() != 1) {
20532            throw new IllegalArgumentException(
20533                    "replacePreferredActivity expects filter to have only 1 action.");
20534        }
20535        if (filter.countDataAuthorities() != 0
20536                || filter.countDataPaths() != 0
20537                || filter.countDataSchemes() > 1
20538                || filter.countDataTypes() != 0) {
20539            throw new IllegalArgumentException(
20540                    "replacePreferredActivity expects filter to have no data authorities, " +
20541                    "paths, or types; and at most one scheme.");
20542        }
20543
20544        final int callingUid = Binder.getCallingUid();
20545        enforceCrossUserPermission(callingUid, userId,
20546                true /* requireFullPermission */, false /* checkShell */,
20547                "replace preferred activity");
20548        synchronized (mPackages) {
20549            if (mContext.checkCallingOrSelfPermission(
20550                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20551                    != PackageManager.PERMISSION_GRANTED) {
20552                if (getUidTargetSdkVersionLockedLPr(callingUid)
20553                        < Build.VERSION_CODES.FROYO) {
20554                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20555                            + Binder.getCallingUid());
20556                    return;
20557                }
20558                mContext.enforceCallingOrSelfPermission(
20559                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20560            }
20561
20562            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20563            if (pir != null) {
20564                // Get all of the existing entries that exactly match this filter.
20565                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20566                if (existing != null && existing.size() == 1) {
20567                    PreferredActivity cur = existing.get(0);
20568                    if (DEBUG_PREFERRED) {
20569                        Slog.i(TAG, "Checking replace of preferred:");
20570                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20571                        if (!cur.mPref.mAlways) {
20572                            Slog.i(TAG, "  -- CUR; not mAlways!");
20573                        } else {
20574                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20575                            Slog.i(TAG, "  -- CUR: mSet="
20576                                    + Arrays.toString(cur.mPref.mSetComponents));
20577                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20578                            Slog.i(TAG, "  -- NEW: mMatch="
20579                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20580                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20581                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20582                        }
20583                    }
20584                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20585                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20586                            && cur.mPref.sameSet(set)) {
20587                        // Setting the preferred activity to what it happens to be already
20588                        if (DEBUG_PREFERRED) {
20589                            Slog.i(TAG, "Replacing with same preferred activity "
20590                                    + cur.mPref.mShortComponent + " for user "
20591                                    + userId + ":");
20592                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20593                        }
20594                        return;
20595                    }
20596                }
20597
20598                if (existing != null) {
20599                    if (DEBUG_PREFERRED) {
20600                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
20601                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20602                    }
20603                    for (int i = 0; i < existing.size(); i++) {
20604                        PreferredActivity pa = existing.get(i);
20605                        if (DEBUG_PREFERRED) {
20606                            Slog.i(TAG, "Removing existing preferred activity "
20607                                    + pa.mPref.mComponent + ":");
20608                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
20609                        }
20610                        pir.removeFilter(pa);
20611                    }
20612                }
20613            }
20614            addPreferredActivityInternal(filter, match, set, activity, true, userId,
20615                    "Replacing preferred");
20616        }
20617    }
20618
20619    @Override
20620    public void clearPackagePreferredActivities(String packageName) {
20621        final int callingUid = Binder.getCallingUid();
20622        if (getInstantAppPackageName(callingUid) != null) {
20623            return;
20624        }
20625        // writer
20626        synchronized (mPackages) {
20627            PackageParser.Package pkg = mPackages.get(packageName);
20628            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
20629                if (mContext.checkCallingOrSelfPermission(
20630                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20631                        != PackageManager.PERMISSION_GRANTED) {
20632                    if (getUidTargetSdkVersionLockedLPr(callingUid)
20633                            < Build.VERSION_CODES.FROYO) {
20634                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20635                                + callingUid);
20636                        return;
20637                    }
20638                    mContext.enforceCallingOrSelfPermission(
20639                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20640                }
20641            }
20642            final PackageSetting ps = mSettings.getPackageLPr(packageName);
20643            if (ps != null
20644                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20645                return;
20646            }
20647            int user = UserHandle.getCallingUserId();
20648            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
20649                scheduleWritePackageRestrictionsLocked(user);
20650            }
20651        }
20652    }
20653
20654    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20655    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
20656        ArrayList<PreferredActivity> removed = null;
20657        boolean changed = false;
20658        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20659            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20660            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20661            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20662                continue;
20663            }
20664            Iterator<PreferredActivity> it = pir.filterIterator();
20665            while (it.hasNext()) {
20666                PreferredActivity pa = it.next();
20667                // Mark entry for removal only if it matches the package name
20668                // and the entry is of type "always".
20669                if (packageName == null ||
20670                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20671                                && pa.mPref.mAlways)) {
20672                    if (removed == null) {
20673                        removed = new ArrayList<PreferredActivity>();
20674                    }
20675                    removed.add(pa);
20676                }
20677            }
20678            if (removed != null) {
20679                for (int j=0; j<removed.size(); j++) {
20680                    PreferredActivity pa = removed.get(j);
20681                    pir.removeFilter(pa);
20682                }
20683                changed = true;
20684            }
20685        }
20686        if (changed) {
20687            postPreferredActivityChangedBroadcast(userId);
20688        }
20689        return changed;
20690    }
20691
20692    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20693    private void clearIntentFilterVerificationsLPw(int userId) {
20694        final int packageCount = mPackages.size();
20695        for (int i = 0; i < packageCount; i++) {
20696            PackageParser.Package pkg = mPackages.valueAt(i);
20697            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20698        }
20699    }
20700
20701    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20702    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20703        if (userId == UserHandle.USER_ALL) {
20704            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20705                    sUserManager.getUserIds())) {
20706                for (int oneUserId : sUserManager.getUserIds()) {
20707                    scheduleWritePackageRestrictionsLocked(oneUserId);
20708                }
20709            }
20710        } else {
20711            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20712                scheduleWritePackageRestrictionsLocked(userId);
20713            }
20714        }
20715    }
20716
20717    /** Clears state for all users, and touches intent filter verification policy */
20718    void clearDefaultBrowserIfNeeded(String packageName) {
20719        for (int oneUserId : sUserManager.getUserIds()) {
20720            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20721        }
20722    }
20723
20724    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20725        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20726        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20727            if (packageName.equals(defaultBrowserPackageName)) {
20728                setDefaultBrowserPackageName(null, userId);
20729            }
20730        }
20731    }
20732
20733    @Override
20734    public void resetApplicationPreferences(int userId) {
20735        mContext.enforceCallingOrSelfPermission(
20736                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20737        final long identity = Binder.clearCallingIdentity();
20738        // writer
20739        try {
20740            synchronized (mPackages) {
20741                clearPackagePreferredActivitiesLPw(null, userId);
20742                mSettings.applyDefaultPreferredAppsLPw(this, userId);
20743                // TODO: We have to reset the default SMS and Phone. This requires
20744                // significant refactoring to keep all default apps in the package
20745                // manager (cleaner but more work) or have the services provide
20746                // callbacks to the package manager to request a default app reset.
20747                applyFactoryDefaultBrowserLPw(userId);
20748                clearIntentFilterVerificationsLPw(userId);
20749                primeDomainVerificationsLPw(userId);
20750                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20751                scheduleWritePackageRestrictionsLocked(userId);
20752            }
20753            resetNetworkPolicies(userId);
20754        } finally {
20755            Binder.restoreCallingIdentity(identity);
20756        }
20757    }
20758
20759    @Override
20760    public int getPreferredActivities(List<IntentFilter> outFilters,
20761            List<ComponentName> outActivities, String packageName) {
20762        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20763            return 0;
20764        }
20765        int num = 0;
20766        final int userId = UserHandle.getCallingUserId();
20767        // reader
20768        synchronized (mPackages) {
20769            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20770            if (pir != null) {
20771                final Iterator<PreferredActivity> it = pir.filterIterator();
20772                while (it.hasNext()) {
20773                    final PreferredActivity pa = it.next();
20774                    if (packageName == null
20775                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
20776                                    && pa.mPref.mAlways)) {
20777                        if (outFilters != null) {
20778                            outFilters.add(new IntentFilter(pa));
20779                        }
20780                        if (outActivities != null) {
20781                            outActivities.add(pa.mPref.mComponent);
20782                        }
20783                    }
20784                }
20785            }
20786        }
20787
20788        return num;
20789    }
20790
20791    @Override
20792    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20793            int userId) {
20794        int callingUid = Binder.getCallingUid();
20795        if (callingUid != Process.SYSTEM_UID) {
20796            throw new SecurityException(
20797                    "addPersistentPreferredActivity can only be run by the system");
20798        }
20799        if (filter.countActions() == 0) {
20800            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20801            return;
20802        }
20803        synchronized (mPackages) {
20804            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20805                    ":");
20806            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20807            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20808                    new PersistentPreferredActivity(filter, activity));
20809            scheduleWritePackageRestrictionsLocked(userId);
20810            postPreferredActivityChangedBroadcast(userId);
20811        }
20812    }
20813
20814    @Override
20815    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20816        int callingUid = Binder.getCallingUid();
20817        if (callingUid != Process.SYSTEM_UID) {
20818            throw new SecurityException(
20819                    "clearPackagePersistentPreferredActivities can only be run by the system");
20820        }
20821        ArrayList<PersistentPreferredActivity> removed = null;
20822        boolean changed = false;
20823        synchronized (mPackages) {
20824            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20825                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20826                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20827                        .valueAt(i);
20828                if (userId != thisUserId) {
20829                    continue;
20830                }
20831                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20832                while (it.hasNext()) {
20833                    PersistentPreferredActivity ppa = it.next();
20834                    // Mark entry for removal only if it matches the package name.
20835                    if (ppa.mComponent.getPackageName().equals(packageName)) {
20836                        if (removed == null) {
20837                            removed = new ArrayList<PersistentPreferredActivity>();
20838                        }
20839                        removed.add(ppa);
20840                    }
20841                }
20842                if (removed != null) {
20843                    for (int j=0; j<removed.size(); j++) {
20844                        PersistentPreferredActivity ppa = removed.get(j);
20845                        ppir.removeFilter(ppa);
20846                    }
20847                    changed = true;
20848                }
20849            }
20850
20851            if (changed) {
20852                scheduleWritePackageRestrictionsLocked(userId);
20853                postPreferredActivityChangedBroadcast(userId);
20854            }
20855        }
20856    }
20857
20858    /**
20859     * Common machinery for picking apart a restored XML blob and passing
20860     * it to a caller-supplied functor to be applied to the running system.
20861     */
20862    private void restoreFromXml(XmlPullParser parser, int userId,
20863            String expectedStartTag, BlobXmlRestorer functor)
20864            throws IOException, XmlPullParserException {
20865        int type;
20866        while ((type = parser.next()) != XmlPullParser.START_TAG
20867                && type != XmlPullParser.END_DOCUMENT) {
20868        }
20869        if (type != XmlPullParser.START_TAG) {
20870            // oops didn't find a start tag?!
20871            if (DEBUG_BACKUP) {
20872                Slog.e(TAG, "Didn't find start tag during restore");
20873            }
20874            return;
20875        }
20876Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20877        // this is supposed to be TAG_PREFERRED_BACKUP
20878        if (!expectedStartTag.equals(parser.getName())) {
20879            if (DEBUG_BACKUP) {
20880                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20881            }
20882            return;
20883        }
20884
20885        // skip interfering stuff, then we're aligned with the backing implementation
20886        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20887Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20888        functor.apply(parser, userId);
20889    }
20890
20891    private interface BlobXmlRestorer {
20892        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20893    }
20894
20895    /**
20896     * Non-Binder method, support for the backup/restore mechanism: write the
20897     * full set of preferred activities in its canonical XML format.  Returns the
20898     * XML output as a byte array, or null if there is none.
20899     */
20900    @Override
20901    public byte[] getPreferredActivityBackup(int userId) {
20902        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20903            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20904        }
20905
20906        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20907        try {
20908            final XmlSerializer serializer = new FastXmlSerializer();
20909            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20910            serializer.startDocument(null, true);
20911            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20912
20913            synchronized (mPackages) {
20914                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20915            }
20916
20917            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20918            serializer.endDocument();
20919            serializer.flush();
20920        } catch (Exception e) {
20921            if (DEBUG_BACKUP) {
20922                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20923            }
20924            return null;
20925        }
20926
20927        return dataStream.toByteArray();
20928    }
20929
20930    @Override
20931    public void restorePreferredActivities(byte[] backup, int userId) {
20932        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20933            throw new SecurityException("Only the system may call restorePreferredActivities()");
20934        }
20935
20936        try {
20937            final XmlPullParser parser = Xml.newPullParser();
20938            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20939            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20940                    new BlobXmlRestorer() {
20941                        @Override
20942                        public void apply(XmlPullParser parser, int userId)
20943                                throws XmlPullParserException, IOException {
20944                            synchronized (mPackages) {
20945                                mSettings.readPreferredActivitiesLPw(parser, userId);
20946                            }
20947                        }
20948                    } );
20949        } catch (Exception e) {
20950            if (DEBUG_BACKUP) {
20951                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20952            }
20953        }
20954    }
20955
20956    /**
20957     * Non-Binder method, support for the backup/restore mechanism: write the
20958     * default browser (etc) settings in its canonical XML format.  Returns the default
20959     * browser XML representation as a byte array, or null if there is none.
20960     */
20961    @Override
20962    public byte[] getDefaultAppsBackup(int userId) {
20963        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20964            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20965        }
20966
20967        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20968        try {
20969            final XmlSerializer serializer = new FastXmlSerializer();
20970            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20971            serializer.startDocument(null, true);
20972            serializer.startTag(null, TAG_DEFAULT_APPS);
20973
20974            synchronized (mPackages) {
20975                mSettings.writeDefaultAppsLPr(serializer, userId);
20976            }
20977
20978            serializer.endTag(null, TAG_DEFAULT_APPS);
20979            serializer.endDocument();
20980            serializer.flush();
20981        } catch (Exception e) {
20982            if (DEBUG_BACKUP) {
20983                Slog.e(TAG, "Unable to write default apps for backup", e);
20984            }
20985            return null;
20986        }
20987
20988        return dataStream.toByteArray();
20989    }
20990
20991    @Override
20992    public void restoreDefaultApps(byte[] backup, int userId) {
20993        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20994            throw new SecurityException("Only the system may call restoreDefaultApps()");
20995        }
20996
20997        try {
20998            final XmlPullParser parser = Xml.newPullParser();
20999            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21000            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21001                    new BlobXmlRestorer() {
21002                        @Override
21003                        public void apply(XmlPullParser parser, int userId)
21004                                throws XmlPullParserException, IOException {
21005                            synchronized (mPackages) {
21006                                mSettings.readDefaultAppsLPw(parser, userId);
21007                            }
21008                        }
21009                    } );
21010        } catch (Exception e) {
21011            if (DEBUG_BACKUP) {
21012                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21013            }
21014        }
21015    }
21016
21017    @Override
21018    public byte[] getIntentFilterVerificationBackup(int userId) {
21019        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21020            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21021        }
21022
21023        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21024        try {
21025            final XmlSerializer serializer = new FastXmlSerializer();
21026            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21027            serializer.startDocument(null, true);
21028            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21029
21030            synchronized (mPackages) {
21031                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21032            }
21033
21034            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21035            serializer.endDocument();
21036            serializer.flush();
21037        } catch (Exception e) {
21038            if (DEBUG_BACKUP) {
21039                Slog.e(TAG, "Unable to write default apps for backup", e);
21040            }
21041            return null;
21042        }
21043
21044        return dataStream.toByteArray();
21045    }
21046
21047    @Override
21048    public void restoreIntentFilterVerification(byte[] backup, int userId) {
21049        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21050            throw new SecurityException("Only the system may call restorePreferredActivities()");
21051        }
21052
21053        try {
21054            final XmlPullParser parser = Xml.newPullParser();
21055            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21056            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21057                    new BlobXmlRestorer() {
21058                        @Override
21059                        public void apply(XmlPullParser parser, int userId)
21060                                throws XmlPullParserException, IOException {
21061                            synchronized (mPackages) {
21062                                mSettings.readAllDomainVerificationsLPr(parser, userId);
21063                                mSettings.writeLPr();
21064                            }
21065                        }
21066                    } );
21067        } catch (Exception e) {
21068            if (DEBUG_BACKUP) {
21069                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21070            }
21071        }
21072    }
21073
21074    @Override
21075    public byte[] getPermissionGrantBackup(int userId) {
21076        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21077            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21078        }
21079
21080        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21081        try {
21082            final XmlSerializer serializer = new FastXmlSerializer();
21083            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21084            serializer.startDocument(null, true);
21085            serializer.startTag(null, TAG_PERMISSION_BACKUP);
21086
21087            synchronized (mPackages) {
21088                serializeRuntimePermissionGrantsLPr(serializer, userId);
21089            }
21090
21091            serializer.endTag(null, TAG_PERMISSION_BACKUP);
21092            serializer.endDocument();
21093            serializer.flush();
21094        } catch (Exception e) {
21095            if (DEBUG_BACKUP) {
21096                Slog.e(TAG, "Unable to write default apps for backup", e);
21097            }
21098            return null;
21099        }
21100
21101        return dataStream.toByteArray();
21102    }
21103
21104    @Override
21105    public void restorePermissionGrants(byte[] backup, int userId) {
21106        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21107            throw new SecurityException("Only the system may call restorePermissionGrants()");
21108        }
21109
21110        try {
21111            final XmlPullParser parser = Xml.newPullParser();
21112            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21113            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21114                    new BlobXmlRestorer() {
21115                        @Override
21116                        public void apply(XmlPullParser parser, int userId)
21117                                throws XmlPullParserException, IOException {
21118                            synchronized (mPackages) {
21119                                processRestoredPermissionGrantsLPr(parser, userId);
21120                            }
21121                        }
21122                    } );
21123        } catch (Exception e) {
21124            if (DEBUG_BACKUP) {
21125                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21126            }
21127        }
21128    }
21129
21130    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21131            throws IOException {
21132        serializer.startTag(null, TAG_ALL_GRANTS);
21133
21134        final int N = mSettings.mPackages.size();
21135        for (int i = 0; i < N; i++) {
21136            final PackageSetting ps = mSettings.mPackages.valueAt(i);
21137            boolean pkgGrantsKnown = false;
21138
21139            PermissionsState packagePerms = ps.getPermissionsState();
21140
21141            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21142                final int grantFlags = state.getFlags();
21143                // only look at grants that are not system/policy fixed
21144                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21145                    final boolean isGranted = state.isGranted();
21146                    // And only back up the user-twiddled state bits
21147                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21148                        final String packageName = mSettings.mPackages.keyAt(i);
21149                        if (!pkgGrantsKnown) {
21150                            serializer.startTag(null, TAG_GRANT);
21151                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21152                            pkgGrantsKnown = true;
21153                        }
21154
21155                        final boolean userSet =
21156                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21157                        final boolean userFixed =
21158                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21159                        final boolean revoke =
21160                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21161
21162                        serializer.startTag(null, TAG_PERMISSION);
21163                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21164                        if (isGranted) {
21165                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
21166                        }
21167                        if (userSet) {
21168                            serializer.attribute(null, ATTR_USER_SET, "true");
21169                        }
21170                        if (userFixed) {
21171                            serializer.attribute(null, ATTR_USER_FIXED, "true");
21172                        }
21173                        if (revoke) {
21174                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21175                        }
21176                        serializer.endTag(null, TAG_PERMISSION);
21177                    }
21178                }
21179            }
21180
21181            if (pkgGrantsKnown) {
21182                serializer.endTag(null, TAG_GRANT);
21183            }
21184        }
21185
21186        serializer.endTag(null, TAG_ALL_GRANTS);
21187    }
21188
21189    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21190            throws XmlPullParserException, IOException {
21191        String pkgName = null;
21192        int outerDepth = parser.getDepth();
21193        int type;
21194        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21195                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21196            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21197                continue;
21198            }
21199
21200            final String tagName = parser.getName();
21201            if (tagName.equals(TAG_GRANT)) {
21202                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21203                if (DEBUG_BACKUP) {
21204                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21205                }
21206            } else if (tagName.equals(TAG_PERMISSION)) {
21207
21208                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21209                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21210
21211                int newFlagSet = 0;
21212                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21213                    newFlagSet |= FLAG_PERMISSION_USER_SET;
21214                }
21215                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21216                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21217                }
21218                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21219                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21220                }
21221                if (DEBUG_BACKUP) {
21222                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
21223                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21224                }
21225                final PackageSetting ps = mSettings.mPackages.get(pkgName);
21226                if (ps != null) {
21227                    // Already installed so we apply the grant immediately
21228                    if (DEBUG_BACKUP) {
21229                        Slog.v(TAG, "        + already installed; applying");
21230                    }
21231                    PermissionsState perms = ps.getPermissionsState();
21232                    BasePermission bp = mSettings.mPermissions.get(permName);
21233                    if (bp != null) {
21234                        if (isGranted) {
21235                            perms.grantRuntimePermission(bp, userId);
21236                        }
21237                        if (newFlagSet != 0) {
21238                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21239                        }
21240                    }
21241                } else {
21242                    // Need to wait for post-restore install to apply the grant
21243                    if (DEBUG_BACKUP) {
21244                        Slog.v(TAG, "        - not yet installed; saving for later");
21245                    }
21246                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21247                            isGranted, newFlagSet, userId);
21248                }
21249            } else {
21250                PackageManagerService.reportSettingsProblem(Log.WARN,
21251                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21252                XmlUtils.skipCurrentTag(parser);
21253            }
21254        }
21255
21256        scheduleWriteSettingsLocked();
21257        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21258    }
21259
21260    @Override
21261    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21262            int sourceUserId, int targetUserId, int flags) {
21263        mContext.enforceCallingOrSelfPermission(
21264                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21265        int callingUid = Binder.getCallingUid();
21266        enforceOwnerRights(ownerPackage, callingUid);
21267        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21268        if (intentFilter.countActions() == 0) {
21269            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21270            return;
21271        }
21272        synchronized (mPackages) {
21273            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21274                    ownerPackage, targetUserId, flags);
21275            CrossProfileIntentResolver resolver =
21276                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21277            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21278            // We have all those whose filter is equal. Now checking if the rest is equal as well.
21279            if (existing != null) {
21280                int size = existing.size();
21281                for (int i = 0; i < size; i++) {
21282                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21283                        return;
21284                    }
21285                }
21286            }
21287            resolver.addFilter(newFilter);
21288            scheduleWritePackageRestrictionsLocked(sourceUserId);
21289        }
21290    }
21291
21292    @Override
21293    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21294        mContext.enforceCallingOrSelfPermission(
21295                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21296        final int callingUid = Binder.getCallingUid();
21297        enforceOwnerRights(ownerPackage, callingUid);
21298        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21299        synchronized (mPackages) {
21300            CrossProfileIntentResolver resolver =
21301                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21302            ArraySet<CrossProfileIntentFilter> set =
21303                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21304            for (CrossProfileIntentFilter filter : set) {
21305                if (filter.getOwnerPackage().equals(ownerPackage)) {
21306                    resolver.removeFilter(filter);
21307                }
21308            }
21309            scheduleWritePackageRestrictionsLocked(sourceUserId);
21310        }
21311    }
21312
21313    // Enforcing that callingUid is owning pkg on userId
21314    private void enforceOwnerRights(String pkg, int callingUid) {
21315        // The system owns everything.
21316        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21317            return;
21318        }
21319        final int callingUserId = UserHandle.getUserId(callingUid);
21320        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21321        if (pi == null) {
21322            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21323                    + callingUserId);
21324        }
21325        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21326            throw new SecurityException("Calling uid " + callingUid
21327                    + " does not own package " + pkg);
21328        }
21329    }
21330
21331    @Override
21332    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21333        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21334            return null;
21335        }
21336        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21337    }
21338
21339    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21340        UserManagerService ums = UserManagerService.getInstance();
21341        if (ums != null) {
21342            final UserInfo parent = ums.getProfileParent(userId);
21343            final int launcherUid = (parent != null) ? parent.id : userId;
21344            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21345            if (launcherComponent != null) {
21346                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21347                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21348                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21349                        .setPackage(launcherComponent.getPackageName());
21350                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21351            }
21352        }
21353    }
21354
21355    /**
21356     * Report the 'Home' activity which is currently set as "always use this one". If non is set
21357     * then reports the most likely home activity or null if there are more than one.
21358     */
21359    private ComponentName getDefaultHomeActivity(int userId) {
21360        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21361        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21362        if (cn != null) {
21363            return cn;
21364        }
21365
21366        // Find the launcher with the highest priority and return that component if there are no
21367        // other home activity with the same priority.
21368        int lastPriority = Integer.MIN_VALUE;
21369        ComponentName lastComponent = null;
21370        final int size = allHomeCandidates.size();
21371        for (int i = 0; i < size; i++) {
21372            final ResolveInfo ri = allHomeCandidates.get(i);
21373            if (ri.priority > lastPriority) {
21374                lastComponent = ri.activityInfo.getComponentName();
21375                lastPriority = ri.priority;
21376            } else if (ri.priority == lastPriority) {
21377                // Two components found with same priority.
21378                lastComponent = null;
21379            }
21380        }
21381        return lastComponent;
21382    }
21383
21384    private Intent getHomeIntent() {
21385        Intent intent = new Intent(Intent.ACTION_MAIN);
21386        intent.addCategory(Intent.CATEGORY_HOME);
21387        intent.addCategory(Intent.CATEGORY_DEFAULT);
21388        return intent;
21389    }
21390
21391    private IntentFilter getHomeFilter() {
21392        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21393        filter.addCategory(Intent.CATEGORY_HOME);
21394        filter.addCategory(Intent.CATEGORY_DEFAULT);
21395        return filter;
21396    }
21397
21398    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21399            int userId) {
21400        Intent intent  = getHomeIntent();
21401        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21402                PackageManager.GET_META_DATA, userId);
21403        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21404                true, false, false, userId);
21405
21406        allHomeCandidates.clear();
21407        if (list != null) {
21408            for (ResolveInfo ri : list) {
21409                allHomeCandidates.add(ri);
21410            }
21411        }
21412        return (preferred == null || preferred.activityInfo == null)
21413                ? null
21414                : new ComponentName(preferred.activityInfo.packageName,
21415                        preferred.activityInfo.name);
21416    }
21417
21418    @Override
21419    public void setHomeActivity(ComponentName comp, int userId) {
21420        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21421            return;
21422        }
21423        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21424        getHomeActivitiesAsUser(homeActivities, userId);
21425
21426        boolean found = false;
21427
21428        final int size = homeActivities.size();
21429        final ComponentName[] set = new ComponentName[size];
21430        for (int i = 0; i < size; i++) {
21431            final ResolveInfo candidate = homeActivities.get(i);
21432            final ActivityInfo info = candidate.activityInfo;
21433            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21434            set[i] = activityName;
21435            if (!found && activityName.equals(comp)) {
21436                found = true;
21437            }
21438        }
21439        if (!found) {
21440            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21441                    + userId);
21442        }
21443        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21444                set, comp, userId);
21445    }
21446
21447    private @Nullable String getSetupWizardPackageName() {
21448        final Intent intent = new Intent(Intent.ACTION_MAIN);
21449        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21450
21451        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21452                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21453                        | MATCH_DISABLED_COMPONENTS,
21454                UserHandle.myUserId());
21455        if (matches.size() == 1) {
21456            return matches.get(0).getComponentInfo().packageName;
21457        } else {
21458            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21459                    + ": matches=" + matches);
21460            return null;
21461        }
21462    }
21463
21464    private @Nullable String getStorageManagerPackageName() {
21465        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21466
21467        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21468                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21469                        | MATCH_DISABLED_COMPONENTS,
21470                UserHandle.myUserId());
21471        if (matches.size() == 1) {
21472            return matches.get(0).getComponentInfo().packageName;
21473        } else {
21474            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21475                    + matches.size() + ": matches=" + matches);
21476            return null;
21477        }
21478    }
21479
21480    @Override
21481    public void setApplicationEnabledSetting(String appPackageName,
21482            int newState, int flags, int userId, String callingPackage) {
21483        if (!sUserManager.exists(userId)) return;
21484        if (callingPackage == null) {
21485            callingPackage = Integer.toString(Binder.getCallingUid());
21486        }
21487        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21488    }
21489
21490    @Override
21491    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21492        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21493        synchronized (mPackages) {
21494            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21495            if (pkgSetting != null) {
21496                pkgSetting.setUpdateAvailable(updateAvailable);
21497            }
21498        }
21499    }
21500
21501    @Override
21502    public void setComponentEnabledSetting(ComponentName componentName,
21503            int newState, int flags, int userId) {
21504        if (!sUserManager.exists(userId)) return;
21505        setEnabledSetting(componentName.getPackageName(),
21506                componentName.getClassName(), newState, flags, userId, null);
21507    }
21508
21509    private void setEnabledSetting(final String packageName, String className, int newState,
21510            final int flags, int userId, String callingPackage) {
21511        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21512              || newState == COMPONENT_ENABLED_STATE_ENABLED
21513              || newState == COMPONENT_ENABLED_STATE_DISABLED
21514              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21515              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21516            throw new IllegalArgumentException("Invalid new component state: "
21517                    + newState);
21518        }
21519        PackageSetting pkgSetting;
21520        final int callingUid = Binder.getCallingUid();
21521        final int permission;
21522        if (callingUid == Process.SYSTEM_UID) {
21523            permission = PackageManager.PERMISSION_GRANTED;
21524        } else {
21525            permission = mContext.checkCallingOrSelfPermission(
21526                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21527        }
21528        enforceCrossUserPermission(callingUid, userId,
21529                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21530        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21531        boolean sendNow = false;
21532        boolean isApp = (className == null);
21533        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21534        String componentName = isApp ? packageName : className;
21535        int packageUid = -1;
21536        ArrayList<String> components;
21537
21538        // reader
21539        synchronized (mPackages) {
21540            pkgSetting = mSettings.mPackages.get(packageName);
21541            if (pkgSetting == null) {
21542                if (!isCallerInstantApp) {
21543                    if (className == null) {
21544                        throw new IllegalArgumentException("Unknown package: " + packageName);
21545                    }
21546                    throw new IllegalArgumentException(
21547                            "Unknown component: " + packageName + "/" + className);
21548                } else {
21549                    // throw SecurityException to prevent leaking package information
21550                    throw new SecurityException(
21551                            "Attempt to change component state; "
21552                            + "pid=" + Binder.getCallingPid()
21553                            + ", uid=" + callingUid
21554                            + (className == null
21555                                    ? ", package=" + packageName
21556                                    : ", component=" + packageName + "/" + className));
21557                }
21558            }
21559        }
21560
21561        // Limit who can change which apps
21562        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21563            // Don't allow apps that don't have permission to modify other apps
21564            if (!allowedByPermission
21565                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21566                throw new SecurityException(
21567                        "Attempt to change component state; "
21568                        + "pid=" + Binder.getCallingPid()
21569                        + ", uid=" + callingUid
21570                        + (className == null
21571                                ? ", package=" + packageName
21572                                : ", component=" + packageName + "/" + className));
21573            }
21574            // Don't allow changing protected packages.
21575            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21576                throw new SecurityException("Cannot disable a protected package: " + packageName);
21577            }
21578        }
21579
21580        synchronized (mPackages) {
21581            if (callingUid == Process.SHELL_UID
21582                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21583                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21584                // unless it is a test package.
21585                int oldState = pkgSetting.getEnabled(userId);
21586                if (className == null
21587                    &&
21588                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21589                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21590                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21591                    &&
21592                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21593                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
21594                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21595                    // ok
21596                } else {
21597                    throw new SecurityException(
21598                            "Shell cannot change component state for " + packageName + "/"
21599                            + className + " to " + newState);
21600                }
21601            }
21602            if (className == null) {
21603                // We're dealing with an application/package level state change
21604                if (pkgSetting.getEnabled(userId) == newState) {
21605                    // Nothing to do
21606                    return;
21607                }
21608                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21609                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21610                    // Don't care about who enables an app.
21611                    callingPackage = null;
21612                }
21613                pkgSetting.setEnabled(newState, userId, callingPackage);
21614                // pkgSetting.pkg.mSetEnabled = newState;
21615            } else {
21616                // We're dealing with a component level state change
21617                // First, verify that this is a valid class name.
21618                PackageParser.Package pkg = pkgSetting.pkg;
21619                if (pkg == null || !pkg.hasComponentClassName(className)) {
21620                    if (pkg != null &&
21621                            pkg.applicationInfo.targetSdkVersion >=
21622                                    Build.VERSION_CODES.JELLY_BEAN) {
21623                        throw new IllegalArgumentException("Component class " + className
21624                                + " does not exist in " + packageName);
21625                    } else {
21626                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21627                                + className + " does not exist in " + packageName);
21628                    }
21629                }
21630                switch (newState) {
21631                case COMPONENT_ENABLED_STATE_ENABLED:
21632                    if (!pkgSetting.enableComponentLPw(className, userId)) {
21633                        return;
21634                    }
21635                    break;
21636                case COMPONENT_ENABLED_STATE_DISABLED:
21637                    if (!pkgSetting.disableComponentLPw(className, userId)) {
21638                        return;
21639                    }
21640                    break;
21641                case COMPONENT_ENABLED_STATE_DEFAULT:
21642                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
21643                        return;
21644                    }
21645                    break;
21646                default:
21647                    Slog.e(TAG, "Invalid new component state: " + newState);
21648                    return;
21649                }
21650            }
21651            scheduleWritePackageRestrictionsLocked(userId);
21652            updateSequenceNumberLP(pkgSetting, new int[] { userId });
21653            final long callingId = Binder.clearCallingIdentity();
21654            try {
21655                updateInstantAppInstallerLocked(packageName);
21656            } finally {
21657                Binder.restoreCallingIdentity(callingId);
21658            }
21659            components = mPendingBroadcasts.get(userId, packageName);
21660            final boolean newPackage = components == null;
21661            if (newPackage) {
21662                components = new ArrayList<String>();
21663            }
21664            if (!components.contains(componentName)) {
21665                components.add(componentName);
21666            }
21667            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21668                sendNow = true;
21669                // Purge entry from pending broadcast list if another one exists already
21670                // since we are sending one right away.
21671                mPendingBroadcasts.remove(userId, packageName);
21672            } else {
21673                if (newPackage) {
21674                    mPendingBroadcasts.put(userId, packageName, components);
21675                }
21676                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21677                    // Schedule a message
21678                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21679                }
21680            }
21681        }
21682
21683        long callingId = Binder.clearCallingIdentity();
21684        try {
21685            if (sendNow) {
21686                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21687                sendPackageChangedBroadcast(packageName,
21688                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21689            }
21690        } finally {
21691            Binder.restoreCallingIdentity(callingId);
21692        }
21693    }
21694
21695    @Override
21696    public void flushPackageRestrictionsAsUser(int userId) {
21697        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21698            return;
21699        }
21700        if (!sUserManager.exists(userId)) {
21701            return;
21702        }
21703        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21704                false /* checkShell */, "flushPackageRestrictions");
21705        synchronized (mPackages) {
21706            mSettings.writePackageRestrictionsLPr(userId);
21707            mDirtyUsers.remove(userId);
21708            if (mDirtyUsers.isEmpty()) {
21709                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21710            }
21711        }
21712    }
21713
21714    private void sendPackageChangedBroadcast(String packageName,
21715            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21716        if (DEBUG_INSTALL)
21717            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21718                    + componentNames);
21719        Bundle extras = new Bundle(4);
21720        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21721        String nameList[] = new String[componentNames.size()];
21722        componentNames.toArray(nameList);
21723        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21724        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21725        extras.putInt(Intent.EXTRA_UID, packageUid);
21726        // If this is not reporting a change of the overall package, then only send it
21727        // to registered receivers.  We don't want to launch a swath of apps for every
21728        // little component state change.
21729        final int flags = !componentNames.contains(packageName)
21730                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21731        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21732                new int[] {UserHandle.getUserId(packageUid)});
21733    }
21734
21735    @Override
21736    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21737        if (!sUserManager.exists(userId)) return;
21738        final int callingUid = Binder.getCallingUid();
21739        if (getInstantAppPackageName(callingUid) != null) {
21740            return;
21741        }
21742        final int permission = mContext.checkCallingOrSelfPermission(
21743                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21744        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21745        enforceCrossUserPermission(callingUid, userId,
21746                true /* requireFullPermission */, true /* checkShell */, "stop package");
21747        // writer
21748        synchronized (mPackages) {
21749            final PackageSetting ps = mSettings.mPackages.get(packageName);
21750            if (!filterAppAccessLPr(ps, callingUid, userId)
21751                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21752                            allowedByPermission, callingUid, userId)) {
21753                scheduleWritePackageRestrictionsLocked(userId);
21754            }
21755        }
21756    }
21757
21758    @Override
21759    public String getInstallerPackageName(String packageName) {
21760        final int callingUid = Binder.getCallingUid();
21761        if (getInstantAppPackageName(callingUid) != null) {
21762            return null;
21763        }
21764        // reader
21765        synchronized (mPackages) {
21766            final PackageSetting ps = mSettings.mPackages.get(packageName);
21767            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21768                return null;
21769            }
21770            return mSettings.getInstallerPackageNameLPr(packageName);
21771        }
21772    }
21773
21774    public boolean isOrphaned(String packageName) {
21775        // reader
21776        synchronized (mPackages) {
21777            return mSettings.isOrphaned(packageName);
21778        }
21779    }
21780
21781    @Override
21782    public int getApplicationEnabledSetting(String packageName, int userId) {
21783        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21784        int callingUid = Binder.getCallingUid();
21785        enforceCrossUserPermission(callingUid, userId,
21786                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21787        // reader
21788        synchronized (mPackages) {
21789            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21790                return COMPONENT_ENABLED_STATE_DISABLED;
21791            }
21792            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21793        }
21794    }
21795
21796    @Override
21797    public int getComponentEnabledSetting(ComponentName component, int userId) {
21798        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21799        int callingUid = Binder.getCallingUid();
21800        enforceCrossUserPermission(callingUid, userId,
21801                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21802        synchronized (mPackages) {
21803            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21804                    component, TYPE_UNKNOWN, userId)) {
21805                return COMPONENT_ENABLED_STATE_DISABLED;
21806            }
21807            return mSettings.getComponentEnabledSettingLPr(component, userId);
21808        }
21809    }
21810
21811    @Override
21812    public void enterSafeMode() {
21813        enforceSystemOrRoot("Only the system can request entering safe mode");
21814
21815        if (!mSystemReady) {
21816            mSafeMode = true;
21817        }
21818    }
21819
21820    @Override
21821    public void systemReady() {
21822        enforceSystemOrRoot("Only the system can claim the system is ready");
21823
21824        mSystemReady = true;
21825        final ContentResolver resolver = mContext.getContentResolver();
21826        ContentObserver co = new ContentObserver(mHandler) {
21827            @Override
21828            public void onChange(boolean selfChange) {
21829                mEphemeralAppsDisabled =
21830                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21831                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21832            }
21833        };
21834        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21835                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21836                false, co, UserHandle.USER_SYSTEM);
21837        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21838                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21839        co.onChange(true);
21840
21841        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21842        // disabled after already being started.
21843        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21844                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21845
21846        // Read the compatibilty setting when the system is ready.
21847        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21848                mContext.getContentResolver(),
21849                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21850        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21851        if (DEBUG_SETTINGS) {
21852            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21853        }
21854
21855        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21856
21857        synchronized (mPackages) {
21858            // Verify that all of the preferred activity components actually
21859            // exist.  It is possible for applications to be updated and at
21860            // that point remove a previously declared activity component that
21861            // had been set as a preferred activity.  We try to clean this up
21862            // the next time we encounter that preferred activity, but it is
21863            // possible for the user flow to never be able to return to that
21864            // situation so here we do a sanity check to make sure we haven't
21865            // left any junk around.
21866            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21867            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21868                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21869                removed.clear();
21870                for (PreferredActivity pa : pir.filterSet()) {
21871                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21872                        removed.add(pa);
21873                    }
21874                }
21875                if (removed.size() > 0) {
21876                    for (int r=0; r<removed.size(); r++) {
21877                        PreferredActivity pa = removed.get(r);
21878                        Slog.w(TAG, "Removing dangling preferred activity: "
21879                                + pa.mPref.mComponent);
21880                        pir.removeFilter(pa);
21881                    }
21882                    mSettings.writePackageRestrictionsLPr(
21883                            mSettings.mPreferredActivities.keyAt(i));
21884                }
21885            }
21886
21887            for (int userId : UserManagerService.getInstance().getUserIds()) {
21888                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21889                    grantPermissionsUserIds = ArrayUtils.appendInt(
21890                            grantPermissionsUserIds, userId);
21891                }
21892            }
21893        }
21894        sUserManager.systemReady();
21895
21896        // If we upgraded grant all default permissions before kicking off.
21897        for (int userId : grantPermissionsUserIds) {
21898            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21899        }
21900
21901        // If we did not grant default permissions, we preload from this the
21902        // default permission exceptions lazily to ensure we don't hit the
21903        // disk on a new user creation.
21904        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21905            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21906        }
21907
21908        // Kick off any messages waiting for system ready
21909        if (mPostSystemReadyMessages != null) {
21910            for (Message msg : mPostSystemReadyMessages) {
21911                msg.sendToTarget();
21912            }
21913            mPostSystemReadyMessages = null;
21914        }
21915
21916        // Watch for external volumes that come and go over time
21917        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21918        storage.registerListener(mStorageListener);
21919
21920        mInstallerService.systemReady();
21921        mPackageDexOptimizer.systemReady();
21922
21923        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21924                StorageManagerInternal.class);
21925        StorageManagerInternal.addExternalStoragePolicy(
21926                new StorageManagerInternal.ExternalStorageMountPolicy() {
21927            @Override
21928            public int getMountMode(int uid, String packageName) {
21929                if (Process.isIsolated(uid)) {
21930                    return Zygote.MOUNT_EXTERNAL_NONE;
21931                }
21932                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
21933                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21934                }
21935                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21936                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21937                }
21938                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21939                    return Zygote.MOUNT_EXTERNAL_READ;
21940                }
21941                return Zygote.MOUNT_EXTERNAL_WRITE;
21942            }
21943
21944            @Override
21945            public boolean hasExternalStorage(int uid, String packageName) {
21946                return true;
21947            }
21948        });
21949
21950        // Now that we're mostly running, clean up stale users and apps
21951        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21952        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21953
21954        if (mPrivappPermissionsViolations != null) {
21955            Slog.wtf(TAG,"Signature|privileged permissions not in "
21956                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21957            mPrivappPermissionsViolations = null;
21958        }
21959    }
21960
21961    public void waitForAppDataPrepared() {
21962        if (mPrepareAppDataFuture == null) {
21963            return;
21964        }
21965        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21966        mPrepareAppDataFuture = null;
21967    }
21968
21969    @Override
21970    public boolean isSafeMode() {
21971        // allow instant applications
21972        return mSafeMode;
21973    }
21974
21975    @Override
21976    public boolean hasSystemUidErrors() {
21977        // allow instant applications
21978        return mHasSystemUidErrors;
21979    }
21980
21981    static String arrayToString(int[] array) {
21982        StringBuffer buf = new StringBuffer(128);
21983        buf.append('[');
21984        if (array != null) {
21985            for (int i=0; i<array.length; i++) {
21986                if (i > 0) buf.append(", ");
21987                buf.append(array[i]);
21988            }
21989        }
21990        buf.append(']');
21991        return buf.toString();
21992    }
21993
21994    static class DumpState {
21995        public static final int DUMP_LIBS = 1 << 0;
21996        public static final int DUMP_FEATURES = 1 << 1;
21997        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
21998        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
21999        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22000        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22001        public static final int DUMP_PERMISSIONS = 1 << 6;
22002        public static final int DUMP_PACKAGES = 1 << 7;
22003        public static final int DUMP_SHARED_USERS = 1 << 8;
22004        public static final int DUMP_MESSAGES = 1 << 9;
22005        public static final int DUMP_PROVIDERS = 1 << 10;
22006        public static final int DUMP_VERIFIERS = 1 << 11;
22007        public static final int DUMP_PREFERRED = 1 << 12;
22008        public static final int DUMP_PREFERRED_XML = 1 << 13;
22009        public static final int DUMP_KEYSETS = 1 << 14;
22010        public static final int DUMP_VERSION = 1 << 15;
22011        public static final int DUMP_INSTALLS = 1 << 16;
22012        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22013        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22014        public static final int DUMP_FROZEN = 1 << 19;
22015        public static final int DUMP_DEXOPT = 1 << 20;
22016        public static final int DUMP_COMPILER_STATS = 1 << 21;
22017        public static final int DUMP_CHANGES = 1 << 22;
22018        public static final int DUMP_VOLUMES = 1 << 23;
22019
22020        public static final int OPTION_SHOW_FILTERS = 1 << 0;
22021
22022        private int mTypes;
22023
22024        private int mOptions;
22025
22026        private boolean mTitlePrinted;
22027
22028        private SharedUserSetting mSharedUser;
22029
22030        public boolean isDumping(int type) {
22031            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22032                return true;
22033            }
22034
22035            return (mTypes & type) != 0;
22036        }
22037
22038        public void setDump(int type) {
22039            mTypes |= type;
22040        }
22041
22042        public boolean isOptionEnabled(int option) {
22043            return (mOptions & option) != 0;
22044        }
22045
22046        public void setOptionEnabled(int option) {
22047            mOptions |= option;
22048        }
22049
22050        public boolean onTitlePrinted() {
22051            final boolean printed = mTitlePrinted;
22052            mTitlePrinted = true;
22053            return printed;
22054        }
22055
22056        public boolean getTitlePrinted() {
22057            return mTitlePrinted;
22058        }
22059
22060        public void setTitlePrinted(boolean enabled) {
22061            mTitlePrinted = enabled;
22062        }
22063
22064        public SharedUserSetting getSharedUser() {
22065            return mSharedUser;
22066        }
22067
22068        public void setSharedUser(SharedUserSetting user) {
22069            mSharedUser = user;
22070        }
22071    }
22072
22073    @Override
22074    public void onShellCommand(FileDescriptor in, FileDescriptor out,
22075            FileDescriptor err, String[] args, ShellCallback callback,
22076            ResultReceiver resultReceiver) {
22077        (new PackageManagerShellCommand(this)).exec(
22078                this, in, out, err, args, callback, resultReceiver);
22079    }
22080
22081    @Override
22082    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22083        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22084
22085        DumpState dumpState = new DumpState();
22086        boolean fullPreferred = false;
22087        boolean checkin = false;
22088
22089        String packageName = null;
22090        ArraySet<String> permissionNames = null;
22091
22092        int opti = 0;
22093        while (opti < args.length) {
22094            String opt = args[opti];
22095            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22096                break;
22097            }
22098            opti++;
22099
22100            if ("-a".equals(opt)) {
22101                // Right now we only know how to print all.
22102            } else if ("-h".equals(opt)) {
22103                pw.println("Package manager dump options:");
22104                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
22105                pw.println("    --checkin: dump for a checkin");
22106                pw.println("    -f: print details of intent filters");
22107                pw.println("    -h: print this help");
22108                pw.println("  cmd may be one of:");
22109                pw.println("    l[ibraries]: list known shared libraries");
22110                pw.println("    f[eatures]: list device features");
22111                pw.println("    k[eysets]: print known keysets");
22112                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22113                pw.println("    perm[issions]: dump permissions");
22114                pw.println("    permission [name ...]: dump declaration and use of given permission");
22115                pw.println("    pref[erred]: print preferred package settings");
22116                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
22117                pw.println("    prov[iders]: dump content providers");
22118                pw.println("    p[ackages]: dump installed packages");
22119                pw.println("    s[hared-users]: dump shared user IDs");
22120                pw.println("    m[essages]: print collected runtime messages");
22121                pw.println("    v[erifiers]: print package verifier info");
22122                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
22123                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22124                pw.println("    version: print database version info");
22125                pw.println("    write: write current settings now");
22126                pw.println("    installs: details about install sessions");
22127                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
22128                pw.println("    dexopt: dump dexopt state");
22129                pw.println("    compiler-stats: dump compiler statistics");
22130                pw.println("    enabled-overlays: dump list of enabled overlay packages");
22131                pw.println("    <package.name>: info about given package");
22132                return;
22133            } else if ("--checkin".equals(opt)) {
22134                checkin = true;
22135            } else if ("-f".equals(opt)) {
22136                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22137            } else if ("--proto".equals(opt)) {
22138                dumpProto(fd);
22139                return;
22140            } else {
22141                pw.println("Unknown argument: " + opt + "; use -h for help");
22142            }
22143        }
22144
22145        // Is the caller requesting to dump a particular piece of data?
22146        if (opti < args.length) {
22147            String cmd = args[opti];
22148            opti++;
22149            // Is this a package name?
22150            if ("android".equals(cmd) || cmd.contains(".")) {
22151                packageName = cmd;
22152                // When dumping a single package, we always dump all of its
22153                // filter information since the amount of data will be reasonable.
22154                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22155            } else if ("check-permission".equals(cmd)) {
22156                if (opti >= args.length) {
22157                    pw.println("Error: check-permission missing permission argument");
22158                    return;
22159                }
22160                String perm = args[opti];
22161                opti++;
22162                if (opti >= args.length) {
22163                    pw.println("Error: check-permission missing package argument");
22164                    return;
22165                }
22166
22167                String pkg = args[opti];
22168                opti++;
22169                int user = UserHandle.getUserId(Binder.getCallingUid());
22170                if (opti < args.length) {
22171                    try {
22172                        user = Integer.parseInt(args[opti]);
22173                    } catch (NumberFormatException e) {
22174                        pw.println("Error: check-permission user argument is not a number: "
22175                                + args[opti]);
22176                        return;
22177                    }
22178                }
22179
22180                // Normalize package name to handle renamed packages and static libs
22181                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22182
22183                pw.println(checkPermission(perm, pkg, user));
22184                return;
22185            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22186                dumpState.setDump(DumpState.DUMP_LIBS);
22187            } else if ("f".equals(cmd) || "features".equals(cmd)) {
22188                dumpState.setDump(DumpState.DUMP_FEATURES);
22189            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22190                if (opti >= args.length) {
22191                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22192                            | DumpState.DUMP_SERVICE_RESOLVERS
22193                            | DumpState.DUMP_RECEIVER_RESOLVERS
22194                            | DumpState.DUMP_CONTENT_RESOLVERS);
22195                } else {
22196                    while (opti < args.length) {
22197                        String name = args[opti];
22198                        if ("a".equals(name) || "activity".equals(name)) {
22199                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22200                        } else if ("s".equals(name) || "service".equals(name)) {
22201                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22202                        } else if ("r".equals(name) || "receiver".equals(name)) {
22203                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22204                        } else if ("c".equals(name) || "content".equals(name)) {
22205                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22206                        } else {
22207                            pw.println("Error: unknown resolver table type: " + name);
22208                            return;
22209                        }
22210                        opti++;
22211                    }
22212                }
22213            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22214                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22215            } else if ("permission".equals(cmd)) {
22216                if (opti >= args.length) {
22217                    pw.println("Error: permission requires permission name");
22218                    return;
22219                }
22220                permissionNames = new ArraySet<>();
22221                while (opti < args.length) {
22222                    permissionNames.add(args[opti]);
22223                    opti++;
22224                }
22225                dumpState.setDump(DumpState.DUMP_PERMISSIONS
22226                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22227            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22228                dumpState.setDump(DumpState.DUMP_PREFERRED);
22229            } else if ("preferred-xml".equals(cmd)) {
22230                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22231                if (opti < args.length && "--full".equals(args[opti])) {
22232                    fullPreferred = true;
22233                    opti++;
22234                }
22235            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22236                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22237            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22238                dumpState.setDump(DumpState.DUMP_PACKAGES);
22239            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22240                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22241            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22242                dumpState.setDump(DumpState.DUMP_PROVIDERS);
22243            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22244                dumpState.setDump(DumpState.DUMP_MESSAGES);
22245            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22246                dumpState.setDump(DumpState.DUMP_VERIFIERS);
22247            } else if ("i".equals(cmd) || "ifv".equals(cmd)
22248                    || "intent-filter-verifiers".equals(cmd)) {
22249                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22250            } else if ("version".equals(cmd)) {
22251                dumpState.setDump(DumpState.DUMP_VERSION);
22252            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22253                dumpState.setDump(DumpState.DUMP_KEYSETS);
22254            } else if ("installs".equals(cmd)) {
22255                dumpState.setDump(DumpState.DUMP_INSTALLS);
22256            } else if ("frozen".equals(cmd)) {
22257                dumpState.setDump(DumpState.DUMP_FROZEN);
22258            } else if ("volumes".equals(cmd)) {
22259                dumpState.setDump(DumpState.DUMP_VOLUMES);
22260            } else if ("dexopt".equals(cmd)) {
22261                dumpState.setDump(DumpState.DUMP_DEXOPT);
22262            } else if ("compiler-stats".equals(cmd)) {
22263                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22264            } else if ("changes".equals(cmd)) {
22265                dumpState.setDump(DumpState.DUMP_CHANGES);
22266            } else if ("write".equals(cmd)) {
22267                synchronized (mPackages) {
22268                    mSettings.writeLPr();
22269                    pw.println("Settings written.");
22270                    return;
22271                }
22272            }
22273        }
22274
22275        if (checkin) {
22276            pw.println("vers,1");
22277        }
22278
22279        // reader
22280        synchronized (mPackages) {
22281            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22282                if (!checkin) {
22283                    if (dumpState.onTitlePrinted())
22284                        pw.println();
22285                    pw.println("Database versions:");
22286                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22287                }
22288            }
22289
22290            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22291                if (!checkin) {
22292                    if (dumpState.onTitlePrinted())
22293                        pw.println();
22294                    pw.println("Verifiers:");
22295                    pw.print("  Required: ");
22296                    pw.print(mRequiredVerifierPackage);
22297                    pw.print(" (uid=");
22298                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22299                            UserHandle.USER_SYSTEM));
22300                    pw.println(")");
22301                } else if (mRequiredVerifierPackage != null) {
22302                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22303                    pw.print(",");
22304                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22305                            UserHandle.USER_SYSTEM));
22306                }
22307            }
22308
22309            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22310                    packageName == null) {
22311                if (mIntentFilterVerifierComponent != null) {
22312                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22313                    if (!checkin) {
22314                        if (dumpState.onTitlePrinted())
22315                            pw.println();
22316                        pw.println("Intent Filter Verifier:");
22317                        pw.print("  Using: ");
22318                        pw.print(verifierPackageName);
22319                        pw.print(" (uid=");
22320                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22321                                UserHandle.USER_SYSTEM));
22322                        pw.println(")");
22323                    } else if (verifierPackageName != null) {
22324                        pw.print("ifv,"); pw.print(verifierPackageName);
22325                        pw.print(",");
22326                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22327                                UserHandle.USER_SYSTEM));
22328                    }
22329                } else {
22330                    pw.println();
22331                    pw.println("No Intent Filter Verifier available!");
22332                }
22333            }
22334
22335            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22336                boolean printedHeader = false;
22337                final Iterator<String> it = mSharedLibraries.keySet().iterator();
22338                while (it.hasNext()) {
22339                    String libName = it.next();
22340                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22341                    if (versionedLib == null) {
22342                        continue;
22343                    }
22344                    final int versionCount = versionedLib.size();
22345                    for (int i = 0; i < versionCount; i++) {
22346                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22347                        if (!checkin) {
22348                            if (!printedHeader) {
22349                                if (dumpState.onTitlePrinted())
22350                                    pw.println();
22351                                pw.println("Libraries:");
22352                                printedHeader = true;
22353                            }
22354                            pw.print("  ");
22355                        } else {
22356                            pw.print("lib,");
22357                        }
22358                        pw.print(libEntry.info.getName());
22359                        if (libEntry.info.isStatic()) {
22360                            pw.print(" version=" + libEntry.info.getVersion());
22361                        }
22362                        if (!checkin) {
22363                            pw.print(" -> ");
22364                        }
22365                        if (libEntry.path != null) {
22366                            pw.print(" (jar) ");
22367                            pw.print(libEntry.path);
22368                        } else {
22369                            pw.print(" (apk) ");
22370                            pw.print(libEntry.apk);
22371                        }
22372                        pw.println();
22373                    }
22374                }
22375            }
22376
22377            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22378                if (dumpState.onTitlePrinted())
22379                    pw.println();
22380                if (!checkin) {
22381                    pw.println("Features:");
22382                }
22383
22384                synchronized (mAvailableFeatures) {
22385                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22386                        if (checkin) {
22387                            pw.print("feat,");
22388                            pw.print(feat.name);
22389                            pw.print(",");
22390                            pw.println(feat.version);
22391                        } else {
22392                            pw.print("  ");
22393                            pw.print(feat.name);
22394                            if (feat.version > 0) {
22395                                pw.print(" version=");
22396                                pw.print(feat.version);
22397                            }
22398                            pw.println();
22399                        }
22400                    }
22401                }
22402            }
22403
22404            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22405                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22406                        : "Activity Resolver Table:", "  ", packageName,
22407                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22408                    dumpState.setTitlePrinted(true);
22409                }
22410            }
22411            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22412                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22413                        : "Receiver Resolver Table:", "  ", packageName,
22414                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22415                    dumpState.setTitlePrinted(true);
22416                }
22417            }
22418            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22419                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22420                        : "Service Resolver Table:", "  ", packageName,
22421                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22422                    dumpState.setTitlePrinted(true);
22423                }
22424            }
22425            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22426                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22427                        : "Provider Resolver Table:", "  ", packageName,
22428                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22429                    dumpState.setTitlePrinted(true);
22430                }
22431            }
22432
22433            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22434                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22435                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22436                    int user = mSettings.mPreferredActivities.keyAt(i);
22437                    if (pir.dump(pw,
22438                            dumpState.getTitlePrinted()
22439                                ? "\nPreferred Activities User " + user + ":"
22440                                : "Preferred Activities User " + user + ":", "  ",
22441                            packageName, true, false)) {
22442                        dumpState.setTitlePrinted(true);
22443                    }
22444                }
22445            }
22446
22447            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22448                pw.flush();
22449                FileOutputStream fout = new FileOutputStream(fd);
22450                BufferedOutputStream str = new BufferedOutputStream(fout);
22451                XmlSerializer serializer = new FastXmlSerializer();
22452                try {
22453                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22454                    serializer.startDocument(null, true);
22455                    serializer.setFeature(
22456                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22457                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22458                    serializer.endDocument();
22459                    serializer.flush();
22460                } catch (IllegalArgumentException e) {
22461                    pw.println("Failed writing: " + e);
22462                } catch (IllegalStateException e) {
22463                    pw.println("Failed writing: " + e);
22464                } catch (IOException e) {
22465                    pw.println("Failed writing: " + e);
22466                }
22467            }
22468
22469            if (!checkin
22470                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22471                    && packageName == null) {
22472                pw.println();
22473                int count = mSettings.mPackages.size();
22474                if (count == 0) {
22475                    pw.println("No applications!");
22476                    pw.println();
22477                } else {
22478                    final String prefix = "  ";
22479                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22480                    if (allPackageSettings.size() == 0) {
22481                        pw.println("No domain preferred apps!");
22482                        pw.println();
22483                    } else {
22484                        pw.println("App verification status:");
22485                        pw.println();
22486                        count = 0;
22487                        for (PackageSetting ps : allPackageSettings) {
22488                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22489                            if (ivi == null || ivi.getPackageName() == null) continue;
22490                            pw.println(prefix + "Package: " + ivi.getPackageName());
22491                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
22492                            pw.println(prefix + "Status:  " + ivi.getStatusString());
22493                            pw.println();
22494                            count++;
22495                        }
22496                        if (count == 0) {
22497                            pw.println(prefix + "No app verification established.");
22498                            pw.println();
22499                        }
22500                        for (int userId : sUserManager.getUserIds()) {
22501                            pw.println("App linkages for user " + userId + ":");
22502                            pw.println();
22503                            count = 0;
22504                            for (PackageSetting ps : allPackageSettings) {
22505                                final long status = ps.getDomainVerificationStatusForUser(userId);
22506                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22507                                        && !DEBUG_DOMAIN_VERIFICATION) {
22508                                    continue;
22509                                }
22510                                pw.println(prefix + "Package: " + ps.name);
22511                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22512                                String statusStr = IntentFilterVerificationInfo.
22513                                        getStatusStringFromValue(status);
22514                                pw.println(prefix + "Status:  " + statusStr);
22515                                pw.println();
22516                                count++;
22517                            }
22518                            if (count == 0) {
22519                                pw.println(prefix + "No configured app linkages.");
22520                                pw.println();
22521                            }
22522                        }
22523                    }
22524                }
22525            }
22526
22527            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22528                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22529                if (packageName == null && permissionNames == null) {
22530                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
22531                        if (iperm == 0) {
22532                            if (dumpState.onTitlePrinted())
22533                                pw.println();
22534                            pw.println("AppOp Permissions:");
22535                        }
22536                        pw.print("  AppOp Permission ");
22537                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
22538                        pw.println(":");
22539                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
22540                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
22541                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
22542                        }
22543                    }
22544                }
22545            }
22546
22547            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22548                boolean printedSomething = false;
22549                for (PackageParser.Provider p : mProviders.mProviders.values()) {
22550                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22551                        continue;
22552                    }
22553                    if (!printedSomething) {
22554                        if (dumpState.onTitlePrinted())
22555                            pw.println();
22556                        pw.println("Registered ContentProviders:");
22557                        printedSomething = true;
22558                    }
22559                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
22560                    pw.print("    "); pw.println(p.toString());
22561                }
22562                printedSomething = false;
22563                for (Map.Entry<String, PackageParser.Provider> entry :
22564                        mProvidersByAuthority.entrySet()) {
22565                    PackageParser.Provider p = entry.getValue();
22566                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22567                        continue;
22568                    }
22569                    if (!printedSomething) {
22570                        if (dumpState.onTitlePrinted())
22571                            pw.println();
22572                        pw.println("ContentProvider Authorities:");
22573                        printedSomething = true;
22574                    }
22575                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
22576                    pw.print("    "); pw.println(p.toString());
22577                    if (p.info != null && p.info.applicationInfo != null) {
22578                        final String appInfo = p.info.applicationInfo.toString();
22579                        pw.print("      applicationInfo="); pw.println(appInfo);
22580                    }
22581                }
22582            }
22583
22584            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22585                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22586            }
22587
22588            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22589                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22590            }
22591
22592            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22593                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22594            }
22595
22596            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22597                if (dumpState.onTitlePrinted()) pw.println();
22598                pw.println("Package Changes:");
22599                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22600                final int K = mChangedPackages.size();
22601                for (int i = 0; i < K; i++) {
22602                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
22603                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22604                    final int N = changes.size();
22605                    if (N == 0) {
22606                        pw.print("    "); pw.println("No packages changed");
22607                    } else {
22608                        for (int j = 0; j < N; j++) {
22609                            final String pkgName = changes.valueAt(j);
22610                            final int sequenceNumber = changes.keyAt(j);
22611                            pw.print("    ");
22612                            pw.print("seq=");
22613                            pw.print(sequenceNumber);
22614                            pw.print(", package=");
22615                            pw.println(pkgName);
22616                        }
22617                    }
22618                }
22619            }
22620
22621            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
22622                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
22623            }
22624
22625            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
22626                // XXX should handle packageName != null by dumping only install data that
22627                // the given package is involved with.
22628                if (dumpState.onTitlePrinted()) pw.println();
22629
22630                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22631                ipw.println();
22632                ipw.println("Frozen packages:");
22633                ipw.increaseIndent();
22634                if (mFrozenPackages.size() == 0) {
22635                    ipw.println("(none)");
22636                } else {
22637                    for (int i = 0; i < mFrozenPackages.size(); i++) {
22638                        ipw.println(mFrozenPackages.valueAt(i));
22639                    }
22640                }
22641                ipw.decreaseIndent();
22642            }
22643
22644            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
22645                if (dumpState.onTitlePrinted()) pw.println();
22646
22647                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22648                ipw.println();
22649                ipw.println("Loaded volumes:");
22650                ipw.increaseIndent();
22651                if (mLoadedVolumes.size() == 0) {
22652                    ipw.println("(none)");
22653                } else {
22654                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
22655                        ipw.println(mLoadedVolumes.valueAt(i));
22656                    }
22657                }
22658                ipw.decreaseIndent();
22659            }
22660
22661            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22662                if (dumpState.onTitlePrinted()) pw.println();
22663                dumpDexoptStateLPr(pw, packageName);
22664            }
22665
22666            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22667                if (dumpState.onTitlePrinted()) pw.println();
22668                dumpCompilerStatsLPr(pw, packageName);
22669            }
22670
22671            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22672                if (dumpState.onTitlePrinted()) pw.println();
22673                mSettings.dumpReadMessagesLPr(pw, dumpState);
22674
22675                pw.println();
22676                pw.println("Package warning messages:");
22677                BufferedReader in = null;
22678                String line = null;
22679                try {
22680                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22681                    while ((line = in.readLine()) != null) {
22682                        if (line.contains("ignored: updated version")) continue;
22683                        pw.println(line);
22684                    }
22685                } catch (IOException ignored) {
22686                } finally {
22687                    IoUtils.closeQuietly(in);
22688                }
22689            }
22690
22691            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22692                BufferedReader in = null;
22693                String line = null;
22694                try {
22695                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22696                    while ((line = in.readLine()) != null) {
22697                        if (line.contains("ignored: updated version")) continue;
22698                        pw.print("msg,");
22699                        pw.println(line);
22700                    }
22701                } catch (IOException ignored) {
22702                } finally {
22703                    IoUtils.closeQuietly(in);
22704                }
22705            }
22706        }
22707
22708        // PackageInstaller should be called outside of mPackages lock
22709        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22710            // XXX should handle packageName != null by dumping only install data that
22711            // the given package is involved with.
22712            if (dumpState.onTitlePrinted()) pw.println();
22713            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
22714        }
22715    }
22716
22717    private void dumpProto(FileDescriptor fd) {
22718        final ProtoOutputStream proto = new ProtoOutputStream(fd);
22719
22720        synchronized (mPackages) {
22721            final long requiredVerifierPackageToken =
22722                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22723            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22724            proto.write(
22725                    PackageServiceDumpProto.PackageShortProto.UID,
22726                    getPackageUid(
22727                            mRequiredVerifierPackage,
22728                            MATCH_DEBUG_TRIAGED_MISSING,
22729                            UserHandle.USER_SYSTEM));
22730            proto.end(requiredVerifierPackageToken);
22731
22732            if (mIntentFilterVerifierComponent != null) {
22733                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22734                final long verifierPackageToken =
22735                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22736                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22737                proto.write(
22738                        PackageServiceDumpProto.PackageShortProto.UID,
22739                        getPackageUid(
22740                                verifierPackageName,
22741                                MATCH_DEBUG_TRIAGED_MISSING,
22742                                UserHandle.USER_SYSTEM));
22743                proto.end(verifierPackageToken);
22744            }
22745
22746            dumpSharedLibrariesProto(proto);
22747            dumpFeaturesProto(proto);
22748            mSettings.dumpPackagesProto(proto);
22749            mSettings.dumpSharedUsersProto(proto);
22750            dumpMessagesProto(proto);
22751        }
22752        proto.flush();
22753    }
22754
22755    private void dumpMessagesProto(ProtoOutputStream proto) {
22756        BufferedReader in = null;
22757        String line = null;
22758        try {
22759            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22760            while ((line = in.readLine()) != null) {
22761                if (line.contains("ignored: updated version")) continue;
22762                proto.write(PackageServiceDumpProto.MESSAGES, line);
22763            }
22764        } catch (IOException ignored) {
22765        } finally {
22766            IoUtils.closeQuietly(in);
22767        }
22768    }
22769
22770    private void dumpFeaturesProto(ProtoOutputStream proto) {
22771        synchronized (mAvailableFeatures) {
22772            final int count = mAvailableFeatures.size();
22773            for (int i = 0; i < count; i++) {
22774                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
22775                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
22776                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
22777                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
22778                proto.end(featureToken);
22779            }
22780        }
22781    }
22782
22783    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22784        final int count = mSharedLibraries.size();
22785        for (int i = 0; i < count; i++) {
22786            final String libName = mSharedLibraries.keyAt(i);
22787            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22788            if (versionedLib == null) {
22789                continue;
22790            }
22791            final int versionCount = versionedLib.size();
22792            for (int j = 0; j < versionCount; j++) {
22793                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22794                final long sharedLibraryToken =
22795                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22796                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22797                final boolean isJar = (libEntry.path != null);
22798                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22799                if (isJar) {
22800                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22801                } else {
22802                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22803                }
22804                proto.end(sharedLibraryToken);
22805            }
22806        }
22807    }
22808
22809    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22810        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22811        ipw.println();
22812        ipw.println("Dexopt state:");
22813        ipw.increaseIndent();
22814        Collection<PackageParser.Package> packages = null;
22815        if (packageName != null) {
22816            PackageParser.Package targetPackage = mPackages.get(packageName);
22817            if (targetPackage != null) {
22818                packages = Collections.singletonList(targetPackage);
22819            } else {
22820                ipw.println("Unable to find package: " + packageName);
22821                return;
22822            }
22823        } else {
22824            packages = mPackages.values();
22825        }
22826
22827        for (PackageParser.Package pkg : packages) {
22828            ipw.println("[" + pkg.packageName + "]");
22829            ipw.increaseIndent();
22830            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
22831            ipw.decreaseIndent();
22832        }
22833    }
22834
22835    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22836        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22837        ipw.println();
22838        ipw.println("Compiler stats:");
22839        ipw.increaseIndent();
22840        Collection<PackageParser.Package> packages = null;
22841        if (packageName != null) {
22842            PackageParser.Package targetPackage = mPackages.get(packageName);
22843            if (targetPackage != null) {
22844                packages = Collections.singletonList(targetPackage);
22845            } else {
22846                ipw.println("Unable to find package: " + packageName);
22847                return;
22848            }
22849        } else {
22850            packages = mPackages.values();
22851        }
22852
22853        for (PackageParser.Package pkg : packages) {
22854            ipw.println("[" + pkg.packageName + "]");
22855            ipw.increaseIndent();
22856
22857            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22858            if (stats == null) {
22859                ipw.println("(No recorded stats)");
22860            } else {
22861                stats.dump(ipw);
22862            }
22863            ipw.decreaseIndent();
22864        }
22865    }
22866
22867    private String dumpDomainString(String packageName) {
22868        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22869                .getList();
22870        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22871
22872        ArraySet<String> result = new ArraySet<>();
22873        if (iviList.size() > 0) {
22874            for (IntentFilterVerificationInfo ivi : iviList) {
22875                for (String host : ivi.getDomains()) {
22876                    result.add(host);
22877                }
22878            }
22879        }
22880        if (filters != null && filters.size() > 0) {
22881            for (IntentFilter filter : filters) {
22882                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22883                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22884                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22885                    result.addAll(filter.getHostsList());
22886                }
22887            }
22888        }
22889
22890        StringBuilder sb = new StringBuilder(result.size() * 16);
22891        for (String domain : result) {
22892            if (sb.length() > 0) sb.append(" ");
22893            sb.append(domain);
22894        }
22895        return sb.toString();
22896    }
22897
22898    // ------- apps on sdcard specific code -------
22899    static final boolean DEBUG_SD_INSTALL = false;
22900
22901    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22902
22903    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22904
22905    private boolean mMediaMounted = false;
22906
22907    static String getEncryptKey() {
22908        try {
22909            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22910                    SD_ENCRYPTION_KEYSTORE_NAME);
22911            if (sdEncKey == null) {
22912                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22913                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22914                if (sdEncKey == null) {
22915                    Slog.e(TAG, "Failed to create encryption keys");
22916                    return null;
22917                }
22918            }
22919            return sdEncKey;
22920        } catch (NoSuchAlgorithmException nsae) {
22921            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22922            return null;
22923        } catch (IOException ioe) {
22924            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22925            return null;
22926        }
22927    }
22928
22929    /*
22930     * Update media status on PackageManager.
22931     */
22932    @Override
22933    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
22934        enforceSystemOrRoot("Media status can only be updated by the system");
22935        // reader; this apparently protects mMediaMounted, but should probably
22936        // be a different lock in that case.
22937        synchronized (mPackages) {
22938            Log.i(TAG, "Updating external media status from "
22939                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
22940                    + (mediaStatus ? "mounted" : "unmounted"));
22941            if (DEBUG_SD_INSTALL)
22942                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
22943                        + ", mMediaMounted=" + mMediaMounted);
22944            if (mediaStatus == mMediaMounted) {
22945                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
22946                        : 0, -1);
22947                mHandler.sendMessage(msg);
22948                return;
22949            }
22950            mMediaMounted = mediaStatus;
22951        }
22952        // Queue up an async operation since the package installation may take a
22953        // little while.
22954        mHandler.post(new Runnable() {
22955            public void run() {
22956                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
22957            }
22958        });
22959    }
22960
22961    /**
22962     * Called by StorageManagerService when the initial ASECs to scan are available.
22963     * Should block until all the ASEC containers are finished being scanned.
22964     */
22965    public void scanAvailableAsecs() {
22966        updateExternalMediaStatusInner(true, false, false);
22967    }
22968
22969    /*
22970     * Collect information of applications on external media, map them against
22971     * existing containers and update information based on current mount status.
22972     * Please note that we always have to report status if reportStatus has been
22973     * set to true especially when unloading packages.
22974     */
22975    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
22976            boolean externalStorage) {
22977        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
22978        int[] uidArr = EmptyArray.INT;
22979
22980        final String[] list = PackageHelper.getSecureContainerList();
22981        if (ArrayUtils.isEmpty(list)) {
22982            Log.i(TAG, "No secure containers found");
22983        } else {
22984            // Process list of secure containers and categorize them
22985            // as active or stale based on their package internal state.
22986
22987            // reader
22988            synchronized (mPackages) {
22989                for (String cid : list) {
22990                    // Leave stages untouched for now; installer service owns them
22991                    if (PackageInstallerService.isStageName(cid)) continue;
22992
22993                    if (DEBUG_SD_INSTALL)
22994                        Log.i(TAG, "Processing container " + cid);
22995                    String pkgName = getAsecPackageName(cid);
22996                    if (pkgName == null) {
22997                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
22998                        continue;
22999                    }
23000                    if (DEBUG_SD_INSTALL)
23001                        Log.i(TAG, "Looking for pkg : " + pkgName);
23002
23003                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
23004                    if (ps == null) {
23005                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23006                        continue;
23007                    }
23008
23009                    /*
23010                     * Skip packages that are not external if we're unmounting
23011                     * external storage.
23012                     */
23013                    if (externalStorage && !isMounted && !isExternal(ps)) {
23014                        continue;
23015                    }
23016
23017                    final AsecInstallArgs args = new AsecInstallArgs(cid,
23018                            getAppDexInstructionSets(ps), ps.isForwardLocked());
23019                    // The package status is changed only if the code path
23020                    // matches between settings and the container id.
23021                    if (ps.codePathString != null
23022                            && ps.codePathString.startsWith(args.getCodePath())) {
23023                        if (DEBUG_SD_INSTALL) {
23024                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23025                                    + " at code path: " + ps.codePathString);
23026                        }
23027
23028                        // We do have a valid package installed on sdcard
23029                        processCids.put(args, ps.codePathString);
23030                        final int uid = ps.appId;
23031                        if (uid != -1) {
23032                            uidArr = ArrayUtils.appendInt(uidArr, uid);
23033                        }
23034                    } else {
23035                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23036                                + ps.codePathString);
23037                    }
23038                }
23039            }
23040
23041            Arrays.sort(uidArr);
23042        }
23043
23044        // Process packages with valid entries.
23045        if (isMounted) {
23046            if (DEBUG_SD_INSTALL)
23047                Log.i(TAG, "Loading packages");
23048            loadMediaPackages(processCids, uidArr, externalStorage);
23049            startCleaningPackages();
23050            mInstallerService.onSecureContainersAvailable();
23051        } else {
23052            if (DEBUG_SD_INSTALL)
23053                Log.i(TAG, "Unloading packages");
23054            unloadMediaPackages(processCids, uidArr, reportStatus);
23055        }
23056    }
23057
23058    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23059            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23060        final int size = infos.size();
23061        final String[] packageNames = new String[size];
23062        final int[] packageUids = new int[size];
23063        for (int i = 0; i < size; i++) {
23064            final ApplicationInfo info = infos.get(i);
23065            packageNames[i] = info.packageName;
23066            packageUids[i] = info.uid;
23067        }
23068        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23069                finishedReceiver);
23070    }
23071
23072    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23073            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23074        sendResourcesChangedBroadcast(mediaStatus, replacing,
23075                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23076    }
23077
23078    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23079            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23080        int size = pkgList.length;
23081        if (size > 0) {
23082            // Send broadcasts here
23083            Bundle extras = new Bundle();
23084            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23085            if (uidArr != null) {
23086                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23087            }
23088            if (replacing) {
23089                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23090            }
23091            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23092                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23093            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23094        }
23095    }
23096
23097   /*
23098     * Look at potentially valid container ids from processCids If package
23099     * information doesn't match the one on record or package scanning fails,
23100     * the cid is added to list of removeCids. We currently don't delete stale
23101     * containers.
23102     */
23103    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23104            boolean externalStorage) {
23105        ArrayList<String> pkgList = new ArrayList<String>();
23106        Set<AsecInstallArgs> keys = processCids.keySet();
23107
23108        for (AsecInstallArgs args : keys) {
23109            String codePath = processCids.get(args);
23110            if (DEBUG_SD_INSTALL)
23111                Log.i(TAG, "Loading container : " + args.cid);
23112            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23113            try {
23114                // Make sure there are no container errors first.
23115                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23116                    Slog.e(TAG, "Failed to mount cid : " + args.cid
23117                            + " when installing from sdcard");
23118                    continue;
23119                }
23120                // Check code path here.
23121                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23122                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23123                            + " does not match one in settings " + codePath);
23124                    continue;
23125                }
23126                // Parse package
23127                int parseFlags = mDefParseFlags;
23128                if (args.isExternalAsec()) {
23129                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23130                }
23131                if (args.isFwdLocked()) {
23132                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23133                }
23134
23135                synchronized (mInstallLock) {
23136                    PackageParser.Package pkg = null;
23137                    try {
23138                        // Sadly we don't know the package name yet to freeze it
23139                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23140                                SCAN_IGNORE_FROZEN, 0, null);
23141                    } catch (PackageManagerException e) {
23142                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23143                    }
23144                    // Scan the package
23145                    if (pkg != null) {
23146                        /*
23147                         * TODO why is the lock being held? doPostInstall is
23148                         * called in other places without the lock. This needs
23149                         * to be straightened out.
23150                         */
23151                        // writer
23152                        synchronized (mPackages) {
23153                            retCode = PackageManager.INSTALL_SUCCEEDED;
23154                            pkgList.add(pkg.packageName);
23155                            // Post process args
23156                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23157                                    pkg.applicationInfo.uid);
23158                        }
23159                    } else {
23160                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
23161                    }
23162                }
23163
23164            } finally {
23165                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23166                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23167                }
23168            }
23169        }
23170        // writer
23171        synchronized (mPackages) {
23172            // If the platform SDK has changed since the last time we booted,
23173            // we need to re-grant app permission to catch any new ones that
23174            // appear. This is really a hack, and means that apps can in some
23175            // cases get permissions that the user didn't initially explicitly
23176            // allow... it would be nice to have some better way to handle
23177            // this situation.
23178            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23179                    : mSettings.getInternalVersion();
23180            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23181                    : StorageManager.UUID_PRIVATE_INTERNAL;
23182
23183            int updateFlags = UPDATE_PERMISSIONS_ALL;
23184            if (ver.sdkVersion != mSdkVersion) {
23185                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23186                        + mSdkVersion + "; regranting permissions for external");
23187                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23188            }
23189            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23190
23191            // Yay, everything is now upgraded
23192            ver.forceCurrent();
23193
23194            // can downgrade to reader
23195            // Persist settings
23196            mSettings.writeLPr();
23197        }
23198        // Send a broadcast to let everyone know we are done processing
23199        if (pkgList.size() > 0) {
23200            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23201        }
23202    }
23203
23204   /*
23205     * Utility method to unload a list of specified containers
23206     */
23207    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23208        // Just unmount all valid containers.
23209        for (AsecInstallArgs arg : cidArgs) {
23210            synchronized (mInstallLock) {
23211                arg.doPostDeleteLI(false);
23212           }
23213       }
23214   }
23215
23216    /*
23217     * Unload packages mounted on external media. This involves deleting package
23218     * data from internal structures, sending broadcasts about disabled packages,
23219     * gc'ing to free up references, unmounting all secure containers
23220     * corresponding to packages on external media, and posting a
23221     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23222     * that we always have to post this message if status has been requested no
23223     * matter what.
23224     */
23225    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23226            final boolean reportStatus) {
23227        if (DEBUG_SD_INSTALL)
23228            Log.i(TAG, "unloading media packages");
23229        ArrayList<String> pkgList = new ArrayList<String>();
23230        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23231        final Set<AsecInstallArgs> keys = processCids.keySet();
23232        for (AsecInstallArgs args : keys) {
23233            String pkgName = args.getPackageName();
23234            if (DEBUG_SD_INSTALL)
23235                Log.i(TAG, "Trying to unload pkg : " + pkgName);
23236            // Delete package internally
23237            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23238            synchronized (mInstallLock) {
23239                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23240                final boolean res;
23241                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23242                        "unloadMediaPackages")) {
23243                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23244                            null);
23245                }
23246                if (res) {
23247                    pkgList.add(pkgName);
23248                } else {
23249                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23250                    failedList.add(args);
23251                }
23252            }
23253        }
23254
23255        // reader
23256        synchronized (mPackages) {
23257            // We didn't update the settings after removing each package;
23258            // write them now for all packages.
23259            mSettings.writeLPr();
23260        }
23261
23262        // We have to absolutely send UPDATED_MEDIA_STATUS only
23263        // after confirming that all the receivers processed the ordered
23264        // broadcast when packages get disabled, force a gc to clean things up.
23265        // and unload all the containers.
23266        if (pkgList.size() > 0) {
23267            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23268                    new IIntentReceiver.Stub() {
23269                public void performReceive(Intent intent, int resultCode, String data,
23270                        Bundle extras, boolean ordered, boolean sticky,
23271                        int sendingUser) throws RemoteException {
23272                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23273                            reportStatus ? 1 : 0, 1, keys);
23274                    mHandler.sendMessage(msg);
23275                }
23276            });
23277        } else {
23278            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23279                    keys);
23280            mHandler.sendMessage(msg);
23281        }
23282    }
23283
23284    private void loadPrivatePackages(final VolumeInfo vol) {
23285        mHandler.post(new Runnable() {
23286            @Override
23287            public void run() {
23288                loadPrivatePackagesInner(vol);
23289            }
23290        });
23291    }
23292
23293    private void loadPrivatePackagesInner(VolumeInfo vol) {
23294        final String volumeUuid = vol.fsUuid;
23295        if (TextUtils.isEmpty(volumeUuid)) {
23296            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23297            return;
23298        }
23299
23300        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23301        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23302        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23303
23304        final VersionInfo ver;
23305        final List<PackageSetting> packages;
23306        synchronized (mPackages) {
23307            ver = mSettings.findOrCreateVersion(volumeUuid);
23308            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23309        }
23310
23311        for (PackageSetting ps : packages) {
23312            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23313            synchronized (mInstallLock) {
23314                final PackageParser.Package pkg;
23315                try {
23316                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23317                    loaded.add(pkg.applicationInfo);
23318
23319                } catch (PackageManagerException e) {
23320                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23321                }
23322
23323                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23324                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23325                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23326                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23327                }
23328            }
23329        }
23330
23331        // Reconcile app data for all started/unlocked users
23332        final StorageManager sm = mContext.getSystemService(StorageManager.class);
23333        final UserManager um = mContext.getSystemService(UserManager.class);
23334        UserManagerInternal umInternal = getUserManagerInternal();
23335        for (UserInfo user : um.getUsers()) {
23336            final int flags;
23337            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23338                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23339            } else if (umInternal.isUserRunning(user.id)) {
23340                flags = StorageManager.FLAG_STORAGE_DE;
23341            } else {
23342                continue;
23343            }
23344
23345            try {
23346                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23347                synchronized (mInstallLock) {
23348                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23349                }
23350            } catch (IllegalStateException e) {
23351                // Device was probably ejected, and we'll process that event momentarily
23352                Slog.w(TAG, "Failed to prepare storage: " + e);
23353            }
23354        }
23355
23356        synchronized (mPackages) {
23357            int updateFlags = UPDATE_PERMISSIONS_ALL;
23358            if (ver.sdkVersion != mSdkVersion) {
23359                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23360                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
23361                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23362            }
23363            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23364
23365            // Yay, everything is now upgraded
23366            ver.forceCurrent();
23367
23368            mSettings.writeLPr();
23369        }
23370
23371        for (PackageFreezer freezer : freezers) {
23372            freezer.close();
23373        }
23374
23375        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23376        sendResourcesChangedBroadcast(true, false, loaded, null);
23377        mLoadedVolumes.add(vol.getId());
23378    }
23379
23380    private void unloadPrivatePackages(final VolumeInfo vol) {
23381        mHandler.post(new Runnable() {
23382            @Override
23383            public void run() {
23384                unloadPrivatePackagesInner(vol);
23385            }
23386        });
23387    }
23388
23389    private void unloadPrivatePackagesInner(VolumeInfo vol) {
23390        final String volumeUuid = vol.fsUuid;
23391        if (TextUtils.isEmpty(volumeUuid)) {
23392            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23393            return;
23394        }
23395
23396        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23397        synchronized (mInstallLock) {
23398        synchronized (mPackages) {
23399            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23400            for (PackageSetting ps : packages) {
23401                if (ps.pkg == null) continue;
23402
23403                final ApplicationInfo info = ps.pkg.applicationInfo;
23404                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23405                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23406
23407                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23408                        "unloadPrivatePackagesInner")) {
23409                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23410                            false, null)) {
23411                        unloaded.add(info);
23412                    } else {
23413                        Slog.w(TAG, "Failed to unload " + ps.codePath);
23414                    }
23415                }
23416
23417                // Try very hard to release any references to this package
23418                // so we don't risk the system server being killed due to
23419                // open FDs
23420                AttributeCache.instance().removePackage(ps.name);
23421            }
23422
23423            mSettings.writeLPr();
23424        }
23425        }
23426
23427        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23428        sendResourcesChangedBroadcast(false, false, unloaded, null);
23429        mLoadedVolumes.remove(vol.getId());
23430
23431        // Try very hard to release any references to this path so we don't risk
23432        // the system server being killed due to open FDs
23433        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23434
23435        for (int i = 0; i < 3; i++) {
23436            System.gc();
23437            System.runFinalization();
23438        }
23439    }
23440
23441    private void assertPackageKnown(String volumeUuid, String packageName)
23442            throws PackageManagerException {
23443        synchronized (mPackages) {
23444            // Normalize package name to handle renamed packages
23445            packageName = normalizePackageNameLPr(packageName);
23446
23447            final PackageSetting ps = mSettings.mPackages.get(packageName);
23448            if (ps == null) {
23449                throw new PackageManagerException("Package " + packageName + " is unknown");
23450            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23451                throw new PackageManagerException(
23452                        "Package " + packageName + " found on unknown volume " + volumeUuid
23453                                + "; expected volume " + ps.volumeUuid);
23454            }
23455        }
23456    }
23457
23458    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23459            throws PackageManagerException {
23460        synchronized (mPackages) {
23461            // Normalize package name to handle renamed packages
23462            packageName = normalizePackageNameLPr(packageName);
23463
23464            final PackageSetting ps = mSettings.mPackages.get(packageName);
23465            if (ps == null) {
23466                throw new PackageManagerException("Package " + packageName + " is unknown");
23467            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23468                throw new PackageManagerException(
23469                        "Package " + packageName + " found on unknown volume " + volumeUuid
23470                                + "; expected volume " + ps.volumeUuid);
23471            } else if (!ps.getInstalled(userId)) {
23472                throw new PackageManagerException(
23473                        "Package " + packageName + " not installed for user " + userId);
23474            }
23475        }
23476    }
23477
23478    private List<String> collectAbsoluteCodePaths() {
23479        synchronized (mPackages) {
23480            List<String> codePaths = new ArrayList<>();
23481            final int packageCount = mSettings.mPackages.size();
23482            for (int i = 0; i < packageCount; i++) {
23483                final PackageSetting ps = mSettings.mPackages.valueAt(i);
23484                codePaths.add(ps.codePath.getAbsolutePath());
23485            }
23486            return codePaths;
23487        }
23488    }
23489
23490    /**
23491     * Examine all apps present on given mounted volume, and destroy apps that
23492     * aren't expected, either due to uninstallation or reinstallation on
23493     * another volume.
23494     */
23495    private void reconcileApps(String volumeUuid) {
23496        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
23497        List<File> filesToDelete = null;
23498
23499        final File[] files = FileUtils.listFilesOrEmpty(
23500                Environment.getDataAppDirectory(volumeUuid));
23501        for (File file : files) {
23502            final boolean isPackage = (isApkFile(file) || file.isDirectory())
23503                    && !PackageInstallerService.isStageName(file.getName());
23504            if (!isPackage) {
23505                // Ignore entries which are not packages
23506                continue;
23507            }
23508
23509            String absolutePath = file.getAbsolutePath();
23510
23511            boolean pathValid = false;
23512            final int absoluteCodePathCount = absoluteCodePaths.size();
23513            for (int i = 0; i < absoluteCodePathCount; i++) {
23514                String absoluteCodePath = absoluteCodePaths.get(i);
23515                if (absolutePath.startsWith(absoluteCodePath)) {
23516                    pathValid = true;
23517                    break;
23518                }
23519            }
23520
23521            if (!pathValid) {
23522                if (filesToDelete == null) {
23523                    filesToDelete = new ArrayList<>();
23524                }
23525                filesToDelete.add(file);
23526            }
23527        }
23528
23529        if (filesToDelete != null) {
23530            final int fileToDeleteCount = filesToDelete.size();
23531            for (int i = 0; i < fileToDeleteCount; i++) {
23532                File fileToDelete = filesToDelete.get(i);
23533                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
23534                synchronized (mInstallLock) {
23535                    removeCodePathLI(fileToDelete);
23536                }
23537            }
23538        }
23539    }
23540
23541    /**
23542     * Reconcile all app data for the given user.
23543     * <p>
23544     * Verifies that directories exist and that ownership and labeling is
23545     * correct for all installed apps on all mounted volumes.
23546     */
23547    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
23548        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23549        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
23550            final String volumeUuid = vol.getFsUuid();
23551            synchronized (mInstallLock) {
23552                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
23553            }
23554        }
23555    }
23556
23557    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23558            boolean migrateAppData) {
23559        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
23560    }
23561
23562    /**
23563     * Reconcile all app data on given mounted volume.
23564     * <p>
23565     * Destroys app data that isn't expected, either due to uninstallation or
23566     * reinstallation on another volume.
23567     * <p>
23568     * Verifies that directories exist and that ownership and labeling is
23569     * correct for all installed apps.
23570     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
23571     */
23572    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23573            boolean migrateAppData, boolean onlyCoreApps) {
23574        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
23575                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
23576        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
23577
23578        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
23579        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
23580
23581        // First look for stale data that doesn't belong, and check if things
23582        // have changed since we did our last restorecon
23583        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23584            if (StorageManager.isFileEncryptedNativeOrEmulated()
23585                    && !StorageManager.isUserKeyUnlocked(userId)) {
23586                throw new RuntimeException(
23587                        "Yikes, someone asked us to reconcile CE storage while " + userId
23588                                + " was still locked; this would have caused massive data loss!");
23589            }
23590
23591            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
23592            for (File file : files) {
23593                final String packageName = file.getName();
23594                try {
23595                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23596                } catch (PackageManagerException e) {
23597                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23598                    try {
23599                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23600                                StorageManager.FLAG_STORAGE_CE, 0);
23601                    } catch (InstallerException e2) {
23602                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23603                    }
23604                }
23605            }
23606        }
23607        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
23608            final File[] files = FileUtils.listFilesOrEmpty(deDir);
23609            for (File file : files) {
23610                final String packageName = file.getName();
23611                try {
23612                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23613                } catch (PackageManagerException e) {
23614                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23615                    try {
23616                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23617                                StorageManager.FLAG_STORAGE_DE, 0);
23618                    } catch (InstallerException e2) {
23619                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23620                    }
23621                }
23622            }
23623        }
23624
23625        // Ensure that data directories are ready to roll for all packages
23626        // installed for this volume and user
23627        final List<PackageSetting> packages;
23628        synchronized (mPackages) {
23629            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23630        }
23631        int preparedCount = 0;
23632        for (PackageSetting ps : packages) {
23633            final String packageName = ps.name;
23634            if (ps.pkg == null) {
23635                Slog.w(TAG, "Odd, missing scanned package " + packageName);
23636                // TODO: might be due to legacy ASEC apps; we should circle back
23637                // and reconcile again once they're scanned
23638                continue;
23639            }
23640            // Skip non-core apps if requested
23641            if (onlyCoreApps && !ps.pkg.coreApp) {
23642                result.add(packageName);
23643                continue;
23644            }
23645
23646            if (ps.getInstalled(userId)) {
23647                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
23648                preparedCount++;
23649            }
23650        }
23651
23652        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
23653        return result;
23654    }
23655
23656    /**
23657     * Prepare app data for the given app just after it was installed or
23658     * upgraded. This method carefully only touches users that it's installed
23659     * for, and it forces a restorecon to handle any seinfo changes.
23660     * <p>
23661     * Verifies that directories exist and that ownership and labeling is
23662     * correct for all installed apps. If there is an ownership mismatch, it
23663     * will try recovering system apps by wiping data; third-party app data is
23664     * left intact.
23665     * <p>
23666     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
23667     */
23668    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
23669        final PackageSetting ps;
23670        synchronized (mPackages) {
23671            ps = mSettings.mPackages.get(pkg.packageName);
23672            mSettings.writeKernelMappingLPr(ps);
23673        }
23674
23675        final UserManager um = mContext.getSystemService(UserManager.class);
23676        UserManagerInternal umInternal = getUserManagerInternal();
23677        for (UserInfo user : um.getUsers()) {
23678            final int flags;
23679            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23680                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23681            } else if (umInternal.isUserRunning(user.id)) {
23682                flags = StorageManager.FLAG_STORAGE_DE;
23683            } else {
23684                continue;
23685            }
23686
23687            if (ps.getInstalled(user.id)) {
23688                // TODO: when user data is locked, mark that we're still dirty
23689                prepareAppDataLIF(pkg, user.id, flags);
23690            }
23691        }
23692    }
23693
23694    /**
23695     * Prepare app data for the given app.
23696     * <p>
23697     * Verifies that directories exist and that ownership and labeling is
23698     * correct for all installed apps. If there is an ownership mismatch, this
23699     * will try recovering system apps by wiping data; third-party app data is
23700     * left intact.
23701     */
23702    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
23703        if (pkg == null) {
23704            Slog.wtf(TAG, "Package was null!", new Throwable());
23705            return;
23706        }
23707        prepareAppDataLeafLIF(pkg, userId, flags);
23708        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23709        for (int i = 0; i < childCount; i++) {
23710            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
23711        }
23712    }
23713
23714    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
23715            boolean maybeMigrateAppData) {
23716        prepareAppDataLIF(pkg, userId, flags);
23717
23718        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
23719            // We may have just shuffled around app data directories, so
23720            // prepare them one more time
23721            prepareAppDataLIF(pkg, userId, flags);
23722        }
23723    }
23724
23725    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23726        if (DEBUG_APP_DATA) {
23727            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
23728                    + Integer.toHexString(flags));
23729        }
23730
23731        final String volumeUuid = pkg.volumeUuid;
23732        final String packageName = pkg.packageName;
23733        final ApplicationInfo app = pkg.applicationInfo;
23734        final int appId = UserHandle.getAppId(app.uid);
23735
23736        Preconditions.checkNotNull(app.seInfo);
23737
23738        long ceDataInode = -1;
23739        try {
23740            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23741                    appId, app.seInfo, app.targetSdkVersion);
23742        } catch (InstallerException e) {
23743            if (app.isSystemApp()) {
23744                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23745                        + ", but trying to recover: " + e);
23746                destroyAppDataLeafLIF(pkg, userId, flags);
23747                try {
23748                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23749                            appId, app.seInfo, app.targetSdkVersion);
23750                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23751                } catch (InstallerException e2) {
23752                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
23753                }
23754            } else {
23755                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23756            }
23757        }
23758
23759        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23760            // TODO: mark this structure as dirty so we persist it!
23761            synchronized (mPackages) {
23762                final PackageSetting ps = mSettings.mPackages.get(packageName);
23763                if (ps != null) {
23764                    ps.setCeDataInode(ceDataInode, userId);
23765                }
23766            }
23767        }
23768
23769        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23770    }
23771
23772    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23773        if (pkg == null) {
23774            Slog.wtf(TAG, "Package was null!", new Throwable());
23775            return;
23776        }
23777        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23778        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23779        for (int i = 0; i < childCount; i++) {
23780            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23781        }
23782    }
23783
23784    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23785        final String volumeUuid = pkg.volumeUuid;
23786        final String packageName = pkg.packageName;
23787        final ApplicationInfo app = pkg.applicationInfo;
23788
23789        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23790            // Create a native library symlink only if we have native libraries
23791            // and if the native libraries are 32 bit libraries. We do not provide
23792            // this symlink for 64 bit libraries.
23793            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23794                final String nativeLibPath = app.nativeLibraryDir;
23795                try {
23796                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23797                            nativeLibPath, userId);
23798                } catch (InstallerException e) {
23799                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23800                }
23801            }
23802        }
23803    }
23804
23805    /**
23806     * For system apps on non-FBE devices, this method migrates any existing
23807     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23808     * requested by the app.
23809     */
23810    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23811        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
23812                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23813            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23814                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23815            try {
23816                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23817                        storageTarget);
23818            } catch (InstallerException e) {
23819                logCriticalInfo(Log.WARN,
23820                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23821            }
23822            return true;
23823        } else {
23824            return false;
23825        }
23826    }
23827
23828    public PackageFreezer freezePackage(String packageName, String killReason) {
23829        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23830    }
23831
23832    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23833        return new PackageFreezer(packageName, userId, killReason);
23834    }
23835
23836    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23837            String killReason) {
23838        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23839    }
23840
23841    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23842            String killReason) {
23843        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23844            return new PackageFreezer();
23845        } else {
23846            return freezePackage(packageName, userId, killReason);
23847        }
23848    }
23849
23850    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23851            String killReason) {
23852        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23853    }
23854
23855    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23856            String killReason) {
23857        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23858            return new PackageFreezer();
23859        } else {
23860            return freezePackage(packageName, userId, killReason);
23861        }
23862    }
23863
23864    /**
23865     * Class that freezes and kills the given package upon creation, and
23866     * unfreezes it upon closing. This is typically used when doing surgery on
23867     * app code/data to prevent the app from running while you're working.
23868     */
23869    private class PackageFreezer implements AutoCloseable {
23870        private final String mPackageName;
23871        private final PackageFreezer[] mChildren;
23872
23873        private final boolean mWeFroze;
23874
23875        private final AtomicBoolean mClosed = new AtomicBoolean();
23876        private final CloseGuard mCloseGuard = CloseGuard.get();
23877
23878        /**
23879         * Create and return a stub freezer that doesn't actually do anything,
23880         * typically used when someone requested
23881         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23882         * {@link PackageManager#DELETE_DONT_KILL_APP}.
23883         */
23884        public PackageFreezer() {
23885            mPackageName = null;
23886            mChildren = null;
23887            mWeFroze = false;
23888            mCloseGuard.open("close");
23889        }
23890
23891        public PackageFreezer(String packageName, int userId, String killReason) {
23892            synchronized (mPackages) {
23893                mPackageName = packageName;
23894                mWeFroze = mFrozenPackages.add(mPackageName);
23895
23896                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23897                if (ps != null) {
23898                    killApplication(ps.name, ps.appId, userId, killReason);
23899                }
23900
23901                final PackageParser.Package p = mPackages.get(packageName);
23902                if (p != null && p.childPackages != null) {
23903                    final int N = p.childPackages.size();
23904                    mChildren = new PackageFreezer[N];
23905                    for (int i = 0; i < N; i++) {
23906                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23907                                userId, killReason);
23908                    }
23909                } else {
23910                    mChildren = null;
23911                }
23912            }
23913            mCloseGuard.open("close");
23914        }
23915
23916        @Override
23917        protected void finalize() throws Throwable {
23918            try {
23919                if (mCloseGuard != null) {
23920                    mCloseGuard.warnIfOpen();
23921                }
23922
23923                close();
23924            } finally {
23925                super.finalize();
23926            }
23927        }
23928
23929        @Override
23930        public void close() {
23931            mCloseGuard.close();
23932            if (mClosed.compareAndSet(false, true)) {
23933                synchronized (mPackages) {
23934                    if (mWeFroze) {
23935                        mFrozenPackages.remove(mPackageName);
23936                    }
23937
23938                    if (mChildren != null) {
23939                        for (PackageFreezer freezer : mChildren) {
23940                            freezer.close();
23941                        }
23942                    }
23943                }
23944            }
23945        }
23946    }
23947
23948    /**
23949     * Verify that given package is currently frozen.
23950     */
23951    private void checkPackageFrozen(String packageName) {
23952        synchronized (mPackages) {
23953            if (!mFrozenPackages.contains(packageName)) {
23954                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23955            }
23956        }
23957    }
23958
23959    @Override
23960    public int movePackage(final String packageName, final String volumeUuid) {
23961        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23962
23963        final int callingUid = Binder.getCallingUid();
23964        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23965        final int moveId = mNextMoveId.getAndIncrement();
23966        mHandler.post(new Runnable() {
23967            @Override
23968            public void run() {
23969                try {
23970                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23971                } catch (PackageManagerException e) {
23972                    Slog.w(TAG, "Failed to move " + packageName, e);
23973                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
23974                }
23975            }
23976        });
23977        return moveId;
23978    }
23979
23980    private void movePackageInternal(final String packageName, final String volumeUuid,
23981            final int moveId, final int callingUid, UserHandle user)
23982                    throws PackageManagerException {
23983        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23984        final PackageManager pm = mContext.getPackageManager();
23985
23986        final boolean currentAsec;
23987        final String currentVolumeUuid;
23988        final File codeFile;
23989        final String installerPackageName;
23990        final String packageAbiOverride;
23991        final int appId;
23992        final String seinfo;
23993        final String label;
23994        final int targetSdkVersion;
23995        final PackageFreezer freezer;
23996        final int[] installedUserIds;
23997
23998        // reader
23999        synchronized (mPackages) {
24000            final PackageParser.Package pkg = mPackages.get(packageName);
24001            final PackageSetting ps = mSettings.mPackages.get(packageName);
24002            if (pkg == null
24003                    || ps == null
24004                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24005                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24006            }
24007            if (pkg.applicationInfo.isSystemApp()) {
24008                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24009                        "Cannot move system application");
24010            }
24011
24012            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24013            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24014                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24015            if (isInternalStorage && !allow3rdPartyOnInternal) {
24016                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24017                        "3rd party apps are not allowed on internal storage");
24018            }
24019
24020            if (pkg.applicationInfo.isExternalAsec()) {
24021                currentAsec = true;
24022                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24023            } else if (pkg.applicationInfo.isForwardLocked()) {
24024                currentAsec = true;
24025                currentVolumeUuid = "forward_locked";
24026            } else {
24027                currentAsec = false;
24028                currentVolumeUuid = ps.volumeUuid;
24029
24030                final File probe = new File(pkg.codePath);
24031                final File probeOat = new File(probe, "oat");
24032                if (!probe.isDirectory() || !probeOat.isDirectory()) {
24033                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24034                            "Move only supported for modern cluster style installs");
24035                }
24036            }
24037
24038            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24039                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24040                        "Package already moved to " + volumeUuid);
24041            }
24042            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24043                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24044                        "Device admin cannot be moved");
24045            }
24046
24047            if (mFrozenPackages.contains(packageName)) {
24048                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24049                        "Failed to move already frozen package");
24050            }
24051
24052            codeFile = new File(pkg.codePath);
24053            installerPackageName = ps.installerPackageName;
24054            packageAbiOverride = ps.cpuAbiOverrideString;
24055            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24056            seinfo = pkg.applicationInfo.seInfo;
24057            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24058            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24059            freezer = freezePackage(packageName, "movePackageInternal");
24060            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24061        }
24062
24063        final Bundle extras = new Bundle();
24064        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24065        extras.putString(Intent.EXTRA_TITLE, label);
24066        mMoveCallbacks.notifyCreated(moveId, extras);
24067
24068        int installFlags;
24069        final boolean moveCompleteApp;
24070        final File measurePath;
24071
24072        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24073            installFlags = INSTALL_INTERNAL;
24074            moveCompleteApp = !currentAsec;
24075            measurePath = Environment.getDataAppDirectory(volumeUuid);
24076        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24077            installFlags = INSTALL_EXTERNAL;
24078            moveCompleteApp = false;
24079            measurePath = storage.getPrimaryPhysicalVolume().getPath();
24080        } else {
24081            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24082            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24083                    || !volume.isMountedWritable()) {
24084                freezer.close();
24085                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24086                        "Move location not mounted private volume");
24087            }
24088
24089            Preconditions.checkState(!currentAsec);
24090
24091            installFlags = INSTALL_INTERNAL;
24092            moveCompleteApp = true;
24093            measurePath = Environment.getDataAppDirectory(volumeUuid);
24094        }
24095
24096        // If we're moving app data around, we need all the users unlocked
24097        if (moveCompleteApp) {
24098            for (int userId : installedUserIds) {
24099                if (StorageManager.isFileEncryptedNativeOrEmulated()
24100                        && !StorageManager.isUserKeyUnlocked(userId)) {
24101                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24102                            "User " + userId + " must be unlocked");
24103                }
24104            }
24105        }
24106
24107        final PackageStats stats = new PackageStats(null, -1);
24108        synchronized (mInstaller) {
24109            for (int userId : installedUserIds) {
24110                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24111                    freezer.close();
24112                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24113                            "Failed to measure package size");
24114                }
24115            }
24116        }
24117
24118        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24119                + stats.dataSize);
24120
24121        final long startFreeBytes = measurePath.getUsableSpace();
24122        final long sizeBytes;
24123        if (moveCompleteApp) {
24124            sizeBytes = stats.codeSize + stats.dataSize;
24125        } else {
24126            sizeBytes = stats.codeSize;
24127        }
24128
24129        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24130            freezer.close();
24131            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24132                    "Not enough free space to move");
24133        }
24134
24135        mMoveCallbacks.notifyStatusChanged(moveId, 10);
24136
24137        final CountDownLatch installedLatch = new CountDownLatch(1);
24138        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24139            @Override
24140            public void onUserActionRequired(Intent intent) throws RemoteException {
24141                throw new IllegalStateException();
24142            }
24143
24144            @Override
24145            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24146                    Bundle extras) throws RemoteException {
24147                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24148                        + PackageManager.installStatusToString(returnCode, msg));
24149
24150                installedLatch.countDown();
24151                freezer.close();
24152
24153                final int status = PackageManager.installStatusToPublicStatus(returnCode);
24154                switch (status) {
24155                    case PackageInstaller.STATUS_SUCCESS:
24156                        mMoveCallbacks.notifyStatusChanged(moveId,
24157                                PackageManager.MOVE_SUCCEEDED);
24158                        break;
24159                    case PackageInstaller.STATUS_FAILURE_STORAGE:
24160                        mMoveCallbacks.notifyStatusChanged(moveId,
24161                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24162                        break;
24163                    default:
24164                        mMoveCallbacks.notifyStatusChanged(moveId,
24165                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24166                        break;
24167                }
24168            }
24169        };
24170
24171        final MoveInfo move;
24172        if (moveCompleteApp) {
24173            // Kick off a thread to report progress estimates
24174            new Thread() {
24175                @Override
24176                public void run() {
24177                    while (true) {
24178                        try {
24179                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
24180                                break;
24181                            }
24182                        } catch (InterruptedException ignored) {
24183                        }
24184
24185                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24186                        final int progress = 10 + (int) MathUtils.constrain(
24187                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24188                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
24189                    }
24190                }
24191            }.start();
24192
24193            final String dataAppName = codeFile.getName();
24194            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24195                    dataAppName, appId, seinfo, targetSdkVersion);
24196        } else {
24197            move = null;
24198        }
24199
24200        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24201
24202        final Message msg = mHandler.obtainMessage(INIT_COPY);
24203        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24204        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24205                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24206                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24207                PackageManager.INSTALL_REASON_UNKNOWN);
24208        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24209        msg.obj = params;
24210
24211        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24212                System.identityHashCode(msg.obj));
24213        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24214                System.identityHashCode(msg.obj));
24215
24216        mHandler.sendMessage(msg);
24217    }
24218
24219    @Override
24220    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24221        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24222
24223        final int realMoveId = mNextMoveId.getAndIncrement();
24224        final Bundle extras = new Bundle();
24225        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24226        mMoveCallbacks.notifyCreated(realMoveId, extras);
24227
24228        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24229            @Override
24230            public void onCreated(int moveId, Bundle extras) {
24231                // Ignored
24232            }
24233
24234            @Override
24235            public void onStatusChanged(int moveId, int status, long estMillis) {
24236                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24237            }
24238        };
24239
24240        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24241        storage.setPrimaryStorageUuid(volumeUuid, callback);
24242        return realMoveId;
24243    }
24244
24245    @Override
24246    public int getMoveStatus(int moveId) {
24247        mContext.enforceCallingOrSelfPermission(
24248                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24249        return mMoveCallbacks.mLastStatus.get(moveId);
24250    }
24251
24252    @Override
24253    public void registerMoveCallback(IPackageMoveObserver callback) {
24254        mContext.enforceCallingOrSelfPermission(
24255                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24256        mMoveCallbacks.register(callback);
24257    }
24258
24259    @Override
24260    public void unregisterMoveCallback(IPackageMoveObserver callback) {
24261        mContext.enforceCallingOrSelfPermission(
24262                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24263        mMoveCallbacks.unregister(callback);
24264    }
24265
24266    @Override
24267    public boolean setInstallLocation(int loc) {
24268        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24269                null);
24270        if (getInstallLocation() == loc) {
24271            return true;
24272        }
24273        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24274                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24275            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24276                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24277            return true;
24278        }
24279        return false;
24280   }
24281
24282    @Override
24283    public int getInstallLocation() {
24284        // allow instant app access
24285        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24286                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24287                PackageHelper.APP_INSTALL_AUTO);
24288    }
24289
24290    /** Called by UserManagerService */
24291    void cleanUpUser(UserManagerService userManager, int userHandle) {
24292        synchronized (mPackages) {
24293            mDirtyUsers.remove(userHandle);
24294            mUserNeedsBadging.delete(userHandle);
24295            mSettings.removeUserLPw(userHandle);
24296            mPendingBroadcasts.remove(userHandle);
24297            mInstantAppRegistry.onUserRemovedLPw(userHandle);
24298            removeUnusedPackagesLPw(userManager, userHandle);
24299        }
24300    }
24301
24302    /**
24303     * We're removing userHandle and would like to remove any downloaded packages
24304     * that are no longer in use by any other user.
24305     * @param userHandle the user being removed
24306     */
24307    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24308        final boolean DEBUG_CLEAN_APKS = false;
24309        int [] users = userManager.getUserIds();
24310        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24311        while (psit.hasNext()) {
24312            PackageSetting ps = psit.next();
24313            if (ps.pkg == null) {
24314                continue;
24315            }
24316            final String packageName = ps.pkg.packageName;
24317            // Skip over if system app
24318            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24319                continue;
24320            }
24321            if (DEBUG_CLEAN_APKS) {
24322                Slog.i(TAG, "Checking package " + packageName);
24323            }
24324            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24325            if (keep) {
24326                if (DEBUG_CLEAN_APKS) {
24327                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
24328                }
24329            } else {
24330                for (int i = 0; i < users.length; i++) {
24331                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
24332                        keep = true;
24333                        if (DEBUG_CLEAN_APKS) {
24334                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
24335                                    + users[i]);
24336                        }
24337                        break;
24338                    }
24339                }
24340            }
24341            if (!keep) {
24342                if (DEBUG_CLEAN_APKS) {
24343                    Slog.i(TAG, "  Removing package " + packageName);
24344                }
24345                mHandler.post(new Runnable() {
24346                    public void run() {
24347                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24348                                userHandle, 0);
24349                    } //end run
24350                });
24351            }
24352        }
24353    }
24354
24355    /** Called by UserManagerService */
24356    void createNewUser(int userId, String[] disallowedPackages) {
24357        synchronized (mInstallLock) {
24358            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24359        }
24360        synchronized (mPackages) {
24361            scheduleWritePackageRestrictionsLocked(userId);
24362            scheduleWritePackageListLocked(userId);
24363            applyFactoryDefaultBrowserLPw(userId);
24364            primeDomainVerificationsLPw(userId);
24365        }
24366    }
24367
24368    void onNewUserCreated(final int userId) {
24369        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
24370        // If permission review for legacy apps is required, we represent
24371        // dagerous permissions for such apps as always granted runtime
24372        // permissions to keep per user flag state whether review is needed.
24373        // Hence, if a new user is added we have to propagate dangerous
24374        // permission grants for these legacy apps.
24375        if (mPermissionReviewRequired) {
24376            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
24377                    | UPDATE_PERMISSIONS_REPLACE_ALL);
24378        }
24379    }
24380
24381    @Override
24382    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
24383        mContext.enforceCallingOrSelfPermission(
24384                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24385                "Only package verification agents can read the verifier device identity");
24386
24387        synchronized (mPackages) {
24388            return mSettings.getVerifierDeviceIdentityLPw();
24389        }
24390    }
24391
24392    @Override
24393    public void setPermissionEnforced(String permission, boolean enforced) {
24394        // TODO: Now that we no longer change GID for storage, this should to away.
24395        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24396                "setPermissionEnforced");
24397        if (READ_EXTERNAL_STORAGE.equals(permission)) {
24398            synchronized (mPackages) {
24399                if (mSettings.mReadExternalStorageEnforced == null
24400                        || mSettings.mReadExternalStorageEnforced != enforced) {
24401                    mSettings.mReadExternalStorageEnforced = enforced;
24402                    mSettings.writeLPr();
24403                }
24404            }
24405            // kill any non-foreground processes so we restart them and
24406            // grant/revoke the GID.
24407            final IActivityManager am = ActivityManager.getService();
24408            if (am != null) {
24409                final long token = Binder.clearCallingIdentity();
24410                try {
24411                    am.killProcessesBelowForeground("setPermissionEnforcement");
24412                } catch (RemoteException e) {
24413                } finally {
24414                    Binder.restoreCallingIdentity(token);
24415                }
24416            }
24417        } else {
24418            throw new IllegalArgumentException("No selective enforcement for " + permission);
24419        }
24420    }
24421
24422    @Override
24423    @Deprecated
24424    public boolean isPermissionEnforced(String permission) {
24425        // allow instant applications
24426        return true;
24427    }
24428
24429    @Override
24430    public boolean isStorageLow() {
24431        // allow instant applications
24432        final long token = Binder.clearCallingIdentity();
24433        try {
24434            final DeviceStorageMonitorInternal
24435                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24436            if (dsm != null) {
24437                return dsm.isMemoryLow();
24438            } else {
24439                return false;
24440            }
24441        } finally {
24442            Binder.restoreCallingIdentity(token);
24443        }
24444    }
24445
24446    @Override
24447    public IPackageInstaller getPackageInstaller() {
24448        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24449            return null;
24450        }
24451        return mInstallerService;
24452    }
24453
24454    private boolean userNeedsBadging(int userId) {
24455        int index = mUserNeedsBadging.indexOfKey(userId);
24456        if (index < 0) {
24457            final UserInfo userInfo;
24458            final long token = Binder.clearCallingIdentity();
24459            try {
24460                userInfo = sUserManager.getUserInfo(userId);
24461            } finally {
24462                Binder.restoreCallingIdentity(token);
24463            }
24464            final boolean b;
24465            if (userInfo != null && userInfo.isManagedProfile()) {
24466                b = true;
24467            } else {
24468                b = false;
24469            }
24470            mUserNeedsBadging.put(userId, b);
24471            return b;
24472        }
24473        return mUserNeedsBadging.valueAt(index);
24474    }
24475
24476    @Override
24477    public KeySet getKeySetByAlias(String packageName, String alias) {
24478        if (packageName == null || alias == null) {
24479            return null;
24480        }
24481        synchronized(mPackages) {
24482            final PackageParser.Package pkg = mPackages.get(packageName);
24483            if (pkg == null) {
24484                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24485                throw new IllegalArgumentException("Unknown package: " + packageName);
24486            }
24487            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24488            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
24489                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
24490                throw new IllegalArgumentException("Unknown package: " + packageName);
24491            }
24492            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24493            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
24494        }
24495    }
24496
24497    @Override
24498    public KeySet getSigningKeySet(String packageName) {
24499        if (packageName == null) {
24500            return null;
24501        }
24502        synchronized(mPackages) {
24503            final int callingUid = Binder.getCallingUid();
24504            final int callingUserId = UserHandle.getUserId(callingUid);
24505            final PackageParser.Package pkg = mPackages.get(packageName);
24506            if (pkg == null) {
24507                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24508                throw new IllegalArgumentException("Unknown package: " + packageName);
24509            }
24510            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24511            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
24512                // filter and pretend the package doesn't exist
24513                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
24514                        + ", uid:" + callingUid);
24515                throw new IllegalArgumentException("Unknown package: " + packageName);
24516            }
24517            if (pkg.applicationInfo.uid != callingUid
24518                    && Process.SYSTEM_UID != callingUid) {
24519                throw new SecurityException("May not access signing KeySet of other apps.");
24520            }
24521            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24522            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
24523        }
24524    }
24525
24526    @Override
24527    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
24528        final int callingUid = Binder.getCallingUid();
24529        if (getInstantAppPackageName(callingUid) != null) {
24530            return false;
24531        }
24532        if (packageName == null || ks == null) {
24533            return false;
24534        }
24535        synchronized(mPackages) {
24536            final PackageParser.Package pkg = mPackages.get(packageName);
24537            if (pkg == null
24538                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24539                            UserHandle.getUserId(callingUid))) {
24540                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24541                throw new IllegalArgumentException("Unknown package: " + packageName);
24542            }
24543            IBinder ksh = ks.getToken();
24544            if (ksh instanceof KeySetHandle) {
24545                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24546                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
24547            }
24548            return false;
24549        }
24550    }
24551
24552    @Override
24553    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
24554        final int callingUid = Binder.getCallingUid();
24555        if (getInstantAppPackageName(callingUid) != null) {
24556            return false;
24557        }
24558        if (packageName == null || ks == null) {
24559            return false;
24560        }
24561        synchronized(mPackages) {
24562            final PackageParser.Package pkg = mPackages.get(packageName);
24563            if (pkg == null
24564                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24565                            UserHandle.getUserId(callingUid))) {
24566                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24567                throw new IllegalArgumentException("Unknown package: " + packageName);
24568            }
24569            IBinder ksh = ks.getToken();
24570            if (ksh instanceof KeySetHandle) {
24571                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24572                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
24573            }
24574            return false;
24575        }
24576    }
24577
24578    private void deletePackageIfUnusedLPr(final String packageName) {
24579        PackageSetting ps = mSettings.mPackages.get(packageName);
24580        if (ps == null) {
24581            return;
24582        }
24583        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
24584            // TODO Implement atomic delete if package is unused
24585            // It is currently possible that the package will be deleted even if it is installed
24586            // after this method returns.
24587            mHandler.post(new Runnable() {
24588                public void run() {
24589                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24590                            0, PackageManager.DELETE_ALL_USERS);
24591                }
24592            });
24593        }
24594    }
24595
24596    /**
24597     * Check and throw if the given before/after packages would be considered a
24598     * downgrade.
24599     */
24600    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
24601            throws PackageManagerException {
24602        if (after.versionCode < before.mVersionCode) {
24603            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24604                    "Update version code " + after.versionCode + " is older than current "
24605                    + before.mVersionCode);
24606        } else if (after.versionCode == before.mVersionCode) {
24607            if (after.baseRevisionCode < before.baseRevisionCode) {
24608                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24609                        "Update base revision code " + after.baseRevisionCode
24610                        + " is older than current " + before.baseRevisionCode);
24611            }
24612
24613            if (!ArrayUtils.isEmpty(after.splitNames)) {
24614                for (int i = 0; i < after.splitNames.length; i++) {
24615                    final String splitName = after.splitNames[i];
24616                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
24617                    if (j != -1) {
24618                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
24619                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24620                                    "Update split " + splitName + " revision code "
24621                                    + after.splitRevisionCodes[i] + " is older than current "
24622                                    + before.splitRevisionCodes[j]);
24623                        }
24624                    }
24625                }
24626            }
24627        }
24628    }
24629
24630    private static class MoveCallbacks extends Handler {
24631        private static final int MSG_CREATED = 1;
24632        private static final int MSG_STATUS_CHANGED = 2;
24633
24634        private final RemoteCallbackList<IPackageMoveObserver>
24635                mCallbacks = new RemoteCallbackList<>();
24636
24637        private final SparseIntArray mLastStatus = new SparseIntArray();
24638
24639        public MoveCallbacks(Looper looper) {
24640            super(looper);
24641        }
24642
24643        public void register(IPackageMoveObserver callback) {
24644            mCallbacks.register(callback);
24645        }
24646
24647        public void unregister(IPackageMoveObserver callback) {
24648            mCallbacks.unregister(callback);
24649        }
24650
24651        @Override
24652        public void handleMessage(Message msg) {
24653            final SomeArgs args = (SomeArgs) msg.obj;
24654            final int n = mCallbacks.beginBroadcast();
24655            for (int i = 0; i < n; i++) {
24656                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
24657                try {
24658                    invokeCallback(callback, msg.what, args);
24659                } catch (RemoteException ignored) {
24660                }
24661            }
24662            mCallbacks.finishBroadcast();
24663            args.recycle();
24664        }
24665
24666        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
24667                throws RemoteException {
24668            switch (what) {
24669                case MSG_CREATED: {
24670                    callback.onCreated(args.argi1, (Bundle) args.arg2);
24671                    break;
24672                }
24673                case MSG_STATUS_CHANGED: {
24674                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
24675                    break;
24676                }
24677            }
24678        }
24679
24680        private void notifyCreated(int moveId, Bundle extras) {
24681            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
24682
24683            final SomeArgs args = SomeArgs.obtain();
24684            args.argi1 = moveId;
24685            args.arg2 = extras;
24686            obtainMessage(MSG_CREATED, args).sendToTarget();
24687        }
24688
24689        private void notifyStatusChanged(int moveId, int status) {
24690            notifyStatusChanged(moveId, status, -1);
24691        }
24692
24693        private void notifyStatusChanged(int moveId, int status, long estMillis) {
24694            Slog.v(TAG, "Move " + moveId + " status " + status);
24695
24696            final SomeArgs args = SomeArgs.obtain();
24697            args.argi1 = moveId;
24698            args.argi2 = status;
24699            args.arg3 = estMillis;
24700            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24701
24702            synchronized (mLastStatus) {
24703                mLastStatus.put(moveId, status);
24704            }
24705        }
24706    }
24707
24708    private final static class OnPermissionChangeListeners extends Handler {
24709        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24710
24711        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24712                new RemoteCallbackList<>();
24713
24714        public OnPermissionChangeListeners(Looper looper) {
24715            super(looper);
24716        }
24717
24718        @Override
24719        public void handleMessage(Message msg) {
24720            switch (msg.what) {
24721                case MSG_ON_PERMISSIONS_CHANGED: {
24722                    final int uid = msg.arg1;
24723                    handleOnPermissionsChanged(uid);
24724                } break;
24725            }
24726        }
24727
24728        public void addListenerLocked(IOnPermissionsChangeListener listener) {
24729            mPermissionListeners.register(listener);
24730
24731        }
24732
24733        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24734            mPermissionListeners.unregister(listener);
24735        }
24736
24737        public void onPermissionsChanged(int uid) {
24738            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24739                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24740            }
24741        }
24742
24743        private void handleOnPermissionsChanged(int uid) {
24744            final int count = mPermissionListeners.beginBroadcast();
24745            try {
24746                for (int i = 0; i < count; i++) {
24747                    IOnPermissionsChangeListener callback = mPermissionListeners
24748                            .getBroadcastItem(i);
24749                    try {
24750                        callback.onPermissionsChanged(uid);
24751                    } catch (RemoteException e) {
24752                        Log.e(TAG, "Permission listener is dead", e);
24753                    }
24754                }
24755            } finally {
24756                mPermissionListeners.finishBroadcast();
24757            }
24758        }
24759    }
24760
24761    private class PackageManagerInternalImpl extends PackageManagerInternal {
24762        @Override
24763        public void setLocationPackagesProvider(PackagesProvider provider) {
24764            synchronized (mPackages) {
24765                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
24766            }
24767        }
24768
24769        @Override
24770        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24771            synchronized (mPackages) {
24772                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
24773            }
24774        }
24775
24776        @Override
24777        public void setSmsAppPackagesProvider(PackagesProvider provider) {
24778            synchronized (mPackages) {
24779                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
24780            }
24781        }
24782
24783        @Override
24784        public void setDialerAppPackagesProvider(PackagesProvider provider) {
24785            synchronized (mPackages) {
24786                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
24787            }
24788        }
24789
24790        @Override
24791        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24792            synchronized (mPackages) {
24793                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
24794            }
24795        }
24796
24797        @Override
24798        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24799            synchronized (mPackages) {
24800                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
24801            }
24802        }
24803
24804        @Override
24805        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24806            synchronized (mPackages) {
24807                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
24808                        packageName, userId);
24809            }
24810        }
24811
24812        @Override
24813        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24814            synchronized (mPackages) {
24815                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24816                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
24817                        packageName, userId);
24818            }
24819        }
24820
24821        @Override
24822        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24823            synchronized (mPackages) {
24824                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
24825                        packageName, userId);
24826            }
24827        }
24828
24829        @Override
24830        public void setKeepUninstalledPackages(final List<String> packageList) {
24831            Preconditions.checkNotNull(packageList);
24832            List<String> removedFromList = null;
24833            synchronized (mPackages) {
24834                if (mKeepUninstalledPackages != null) {
24835                    final int packagesCount = mKeepUninstalledPackages.size();
24836                    for (int i = 0; i < packagesCount; i++) {
24837                        String oldPackage = mKeepUninstalledPackages.get(i);
24838                        if (packageList != null && packageList.contains(oldPackage)) {
24839                            continue;
24840                        }
24841                        if (removedFromList == null) {
24842                            removedFromList = new ArrayList<>();
24843                        }
24844                        removedFromList.add(oldPackage);
24845                    }
24846                }
24847                mKeepUninstalledPackages = new ArrayList<>(packageList);
24848                if (removedFromList != null) {
24849                    final int removedCount = removedFromList.size();
24850                    for (int i = 0; i < removedCount; i++) {
24851                        deletePackageIfUnusedLPr(removedFromList.get(i));
24852                    }
24853                }
24854            }
24855        }
24856
24857        @Override
24858        public boolean isPermissionsReviewRequired(String packageName, int userId) {
24859            synchronized (mPackages) {
24860                // If we do not support permission review, done.
24861                if (!mPermissionReviewRequired) {
24862                    return false;
24863                }
24864
24865                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24866                if (packageSetting == null) {
24867                    return false;
24868                }
24869
24870                // Permission review applies only to apps not supporting the new permission model.
24871                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
24872                    return false;
24873                }
24874
24875                // Legacy apps have the permission and get user consent on launch.
24876                PermissionsState permissionsState = packageSetting.getPermissionsState();
24877                return permissionsState.isPermissionReviewRequired(userId);
24878            }
24879        }
24880
24881        @Override
24882        public PackageInfo getPackageInfo(
24883                String packageName, int flags, int filterCallingUid, int userId) {
24884            return PackageManagerService.this
24885                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24886                            flags, filterCallingUid, userId);
24887        }
24888
24889        @Override
24890        public ApplicationInfo getApplicationInfo(
24891                String packageName, int flags, int filterCallingUid, int userId) {
24892            return PackageManagerService.this
24893                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24894        }
24895
24896        @Override
24897        public ActivityInfo getActivityInfo(
24898                ComponentName component, int flags, int filterCallingUid, int userId) {
24899            return PackageManagerService.this
24900                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24901        }
24902
24903        @Override
24904        public List<ResolveInfo> queryIntentActivities(
24905                Intent intent, int flags, int filterCallingUid, int userId) {
24906            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24907            return PackageManagerService.this
24908                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24909                            userId, false /*resolveForStart*/);
24910        }
24911
24912        @Override
24913        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24914                int userId) {
24915            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24916        }
24917
24918        @Override
24919        public void setDeviceAndProfileOwnerPackages(
24920                int deviceOwnerUserId, String deviceOwnerPackage,
24921                SparseArray<String> profileOwnerPackages) {
24922            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24923                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24924        }
24925
24926        @Override
24927        public boolean isPackageDataProtected(int userId, String packageName) {
24928            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24929        }
24930
24931        @Override
24932        public boolean isPackageEphemeral(int userId, String packageName) {
24933            synchronized (mPackages) {
24934                final PackageSetting ps = mSettings.mPackages.get(packageName);
24935                return ps != null ? ps.getInstantApp(userId) : false;
24936            }
24937        }
24938
24939        @Override
24940        public boolean wasPackageEverLaunched(String packageName, int userId) {
24941            synchronized (mPackages) {
24942                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24943            }
24944        }
24945
24946        @Override
24947        public void grantRuntimePermission(String packageName, String name, int userId,
24948                boolean overridePolicy) {
24949            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
24950                    overridePolicy);
24951        }
24952
24953        @Override
24954        public void revokeRuntimePermission(String packageName, String name, int userId,
24955                boolean overridePolicy) {
24956            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
24957                    overridePolicy);
24958        }
24959
24960        @Override
24961        public String getNameForUid(int uid) {
24962            return PackageManagerService.this.getNameForUid(uid);
24963        }
24964
24965        @Override
24966        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24967                Intent origIntent, String resolvedType, String callingPackage,
24968                Bundle verificationBundle, int userId) {
24969            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24970                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24971                    userId);
24972        }
24973
24974        @Override
24975        public void grantEphemeralAccess(int userId, Intent intent,
24976                int targetAppId, int ephemeralAppId) {
24977            synchronized (mPackages) {
24978                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24979                        targetAppId, ephemeralAppId);
24980            }
24981        }
24982
24983        @Override
24984        public boolean isInstantAppInstallerComponent(ComponentName component) {
24985            synchronized (mPackages) {
24986                return mInstantAppInstallerActivity != null
24987                        && mInstantAppInstallerActivity.getComponentName().equals(component);
24988            }
24989        }
24990
24991        @Override
24992        public void pruneInstantApps() {
24993            mInstantAppRegistry.pruneInstantApps();
24994        }
24995
24996        @Override
24997        public String getSetupWizardPackageName() {
24998            return mSetupWizardPackage;
24999        }
25000
25001        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25002            if (policy != null) {
25003                mExternalSourcesPolicy = policy;
25004            }
25005        }
25006
25007        @Override
25008        public boolean isPackagePersistent(String packageName) {
25009            synchronized (mPackages) {
25010                PackageParser.Package pkg = mPackages.get(packageName);
25011                return pkg != null
25012                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25013                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
25014                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25015                        : false;
25016            }
25017        }
25018
25019        @Override
25020        public List<PackageInfo> getOverlayPackages(int userId) {
25021            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25022            synchronized (mPackages) {
25023                for (PackageParser.Package p : mPackages.values()) {
25024                    if (p.mOverlayTarget != null) {
25025                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25026                        if (pkg != null) {
25027                            overlayPackages.add(pkg);
25028                        }
25029                    }
25030                }
25031            }
25032            return overlayPackages;
25033        }
25034
25035        @Override
25036        public List<String> getTargetPackageNames(int userId) {
25037            List<String> targetPackages = new ArrayList<>();
25038            synchronized (mPackages) {
25039                for (PackageParser.Package p : mPackages.values()) {
25040                    if (p.mOverlayTarget == null) {
25041                        targetPackages.add(p.packageName);
25042                    }
25043                }
25044            }
25045            return targetPackages;
25046        }
25047
25048        @Override
25049        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25050                @Nullable List<String> overlayPackageNames) {
25051            synchronized (mPackages) {
25052                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25053                    Slog.e(TAG, "failed to find package " + targetPackageName);
25054                    return false;
25055                }
25056                ArrayList<String> overlayPaths = null;
25057                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25058                    final int N = overlayPackageNames.size();
25059                    overlayPaths = new ArrayList<>(N);
25060                    for (int i = 0; i < N; i++) {
25061                        final String packageName = overlayPackageNames.get(i);
25062                        final PackageParser.Package pkg = mPackages.get(packageName);
25063                        if (pkg == null) {
25064                            Slog.e(TAG, "failed to find package " + packageName);
25065                            return false;
25066                        }
25067                        overlayPaths.add(pkg.baseCodePath);
25068                    }
25069                }
25070
25071                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25072                ps.setOverlayPaths(overlayPaths, userId);
25073                return true;
25074            }
25075        }
25076
25077        @Override
25078        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25079                int flags, int userId) {
25080            return resolveIntentInternal(
25081                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
25082        }
25083
25084        @Override
25085        public ResolveInfo resolveService(Intent intent, String resolvedType,
25086                int flags, int userId, int callingUid) {
25087            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25088        }
25089
25090        @Override
25091        public void addIsolatedUid(int isolatedUid, int ownerUid) {
25092            synchronized (mPackages) {
25093                mIsolatedOwners.put(isolatedUid, ownerUid);
25094            }
25095        }
25096
25097        @Override
25098        public void removeIsolatedUid(int isolatedUid) {
25099            synchronized (mPackages) {
25100                mIsolatedOwners.delete(isolatedUid);
25101            }
25102        }
25103
25104        @Override
25105        public int getUidTargetSdkVersion(int uid) {
25106            synchronized (mPackages) {
25107                return getUidTargetSdkVersionLockedLPr(uid);
25108            }
25109        }
25110
25111        @Override
25112        public boolean canAccessInstantApps(int callingUid, int userId) {
25113            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25114        }
25115    }
25116
25117    @Override
25118    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25119        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25120        synchronized (mPackages) {
25121            final long identity = Binder.clearCallingIdentity();
25122            try {
25123                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25124                        packageNames, userId);
25125            } finally {
25126                Binder.restoreCallingIdentity(identity);
25127            }
25128        }
25129    }
25130
25131    @Override
25132    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25133        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25134        synchronized (mPackages) {
25135            final long identity = Binder.clearCallingIdentity();
25136            try {
25137                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25138                        packageNames, userId);
25139            } finally {
25140                Binder.restoreCallingIdentity(identity);
25141            }
25142        }
25143    }
25144
25145    private static void enforceSystemOrPhoneCaller(String tag) {
25146        int callingUid = Binder.getCallingUid();
25147        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25148            throw new SecurityException(
25149                    "Cannot call " + tag + " from UID " + callingUid);
25150        }
25151    }
25152
25153    boolean isHistoricalPackageUsageAvailable() {
25154        return mPackageUsage.isHistoricalPackageUsageAvailable();
25155    }
25156
25157    /**
25158     * Return a <b>copy</b> of the collection of packages known to the package manager.
25159     * @return A copy of the values of mPackages.
25160     */
25161    Collection<PackageParser.Package> getPackages() {
25162        synchronized (mPackages) {
25163            return new ArrayList<>(mPackages.values());
25164        }
25165    }
25166
25167    /**
25168     * Logs process start information (including base APK hash) to the security log.
25169     * @hide
25170     */
25171    @Override
25172    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25173            String apkFile, int pid) {
25174        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25175            return;
25176        }
25177        if (!SecurityLog.isLoggingEnabled()) {
25178            return;
25179        }
25180        Bundle data = new Bundle();
25181        data.putLong("startTimestamp", System.currentTimeMillis());
25182        data.putString("processName", processName);
25183        data.putInt("uid", uid);
25184        data.putString("seinfo", seinfo);
25185        data.putString("apkFile", apkFile);
25186        data.putInt("pid", pid);
25187        Message msg = mProcessLoggingHandler.obtainMessage(
25188                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25189        msg.setData(data);
25190        mProcessLoggingHandler.sendMessage(msg);
25191    }
25192
25193    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25194        return mCompilerStats.getPackageStats(pkgName);
25195    }
25196
25197    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25198        return getOrCreateCompilerPackageStats(pkg.packageName);
25199    }
25200
25201    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25202        return mCompilerStats.getOrCreatePackageStats(pkgName);
25203    }
25204
25205    public void deleteCompilerPackageStats(String pkgName) {
25206        mCompilerStats.deletePackageStats(pkgName);
25207    }
25208
25209    @Override
25210    public int getInstallReason(String packageName, int userId) {
25211        final int callingUid = Binder.getCallingUid();
25212        enforceCrossUserPermission(callingUid, userId,
25213                true /* requireFullPermission */, false /* checkShell */,
25214                "get install reason");
25215        synchronized (mPackages) {
25216            final PackageSetting ps = mSettings.mPackages.get(packageName);
25217            if (filterAppAccessLPr(ps, callingUid, userId)) {
25218                return PackageManager.INSTALL_REASON_UNKNOWN;
25219            }
25220            if (ps != null) {
25221                return ps.getInstallReason(userId);
25222            }
25223        }
25224        return PackageManager.INSTALL_REASON_UNKNOWN;
25225    }
25226
25227    @Override
25228    public boolean canRequestPackageInstalls(String packageName, int userId) {
25229        return canRequestPackageInstallsInternal(packageName, 0, userId,
25230                true /* throwIfPermNotDeclared*/);
25231    }
25232
25233    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25234            boolean throwIfPermNotDeclared) {
25235        int callingUid = Binder.getCallingUid();
25236        int uid = getPackageUid(packageName, 0, userId);
25237        if (callingUid != uid && callingUid != Process.ROOT_UID
25238                && callingUid != Process.SYSTEM_UID) {
25239            throw new SecurityException(
25240                    "Caller uid " + callingUid + " does not own package " + packageName);
25241        }
25242        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25243        if (info == null) {
25244            return false;
25245        }
25246        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25247            return false;
25248        }
25249        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25250        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25251        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25252            if (throwIfPermNotDeclared) {
25253                throw new SecurityException("Need to declare " + appOpPermission
25254                        + " to call this api");
25255            } else {
25256                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25257                return false;
25258            }
25259        }
25260        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25261            return false;
25262        }
25263        if (mExternalSourcesPolicy != null) {
25264            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25265            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
25266                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25267            }
25268        }
25269        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
25270    }
25271
25272    @Override
25273    public ComponentName getInstantAppResolverSettingsComponent() {
25274        return mInstantAppResolverSettingsComponent;
25275    }
25276
25277    @Override
25278    public ComponentName getInstantAppInstallerComponent() {
25279        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25280            return null;
25281        }
25282        return mInstantAppInstallerActivity == null
25283                ? null : mInstantAppInstallerActivity.getComponentName();
25284    }
25285
25286    @Override
25287    public String getInstantAppAndroidId(String packageName, int userId) {
25288        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25289                "getInstantAppAndroidId");
25290        enforceCrossUserPermission(Binder.getCallingUid(), userId,
25291                true /* requireFullPermission */, false /* checkShell */,
25292                "getInstantAppAndroidId");
25293        // Make sure the target is an Instant App.
25294        if (!isInstantApp(packageName, userId)) {
25295            return null;
25296        }
25297        synchronized (mPackages) {
25298            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25299        }
25300    }
25301
25302    boolean canHaveOatDir(String packageName) {
25303        synchronized (mPackages) {
25304            PackageParser.Package p = mPackages.get(packageName);
25305            if (p == null) {
25306                return false;
25307            }
25308            return p.canHaveOatDir();
25309        }
25310    }
25311
25312    private String getOatDir(PackageParser.Package pkg) {
25313        if (!pkg.canHaveOatDir()) {
25314            return null;
25315        }
25316        File codePath = new File(pkg.codePath);
25317        if (codePath.isDirectory()) {
25318            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25319        }
25320        return null;
25321    }
25322
25323    void deleteOatArtifactsOfPackage(String packageName) {
25324        final String[] instructionSets;
25325        final List<String> codePaths;
25326        final String oatDir;
25327        final PackageParser.Package pkg;
25328        synchronized (mPackages) {
25329            pkg = mPackages.get(packageName);
25330        }
25331        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25332        codePaths = pkg.getAllCodePaths();
25333        oatDir = getOatDir(pkg);
25334
25335        for (String codePath : codePaths) {
25336            for (String isa : instructionSets) {
25337                try {
25338                    mInstaller.deleteOdex(codePath, isa, oatDir);
25339                } catch (InstallerException e) {
25340                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25341                }
25342            }
25343        }
25344    }
25345
25346    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25347        Set<String> unusedPackages = new HashSet<>();
25348        long currentTimeInMillis = System.currentTimeMillis();
25349        synchronized (mPackages) {
25350            for (PackageParser.Package pkg : mPackages.values()) {
25351                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
25352                if (ps == null) {
25353                    continue;
25354                }
25355                PackageDexUsage.PackageUseInfo packageUseInfo = getDexManager().getPackageUseInfo(
25356                        pkg.packageName);
25357                if (PackageManagerServiceUtils
25358                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25359                                downgradeTimeThresholdMillis, packageUseInfo,
25360                                pkg.getLatestPackageUseTimeInMills(),
25361                                pkg.getLatestForegroundPackageUseTimeInMills())) {
25362                    unusedPackages.add(pkg.packageName);
25363                }
25364            }
25365        }
25366        return unusedPackages;
25367    }
25368}
25369
25370interface PackageSender {
25371    void sendPackageBroadcast(final String action, final String pkg,
25372        final Bundle extras, final int flags, final String targetPkg,
25373        final IIntentReceiver finishedReceiver, final int[] userIds);
25374    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25375        boolean includeStopped, int appId, int... userIds);
25376}
25377