PackageManagerService.java revision e92f79450a0e3a55586eb2992577d09fc997761a
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
22import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23import static android.Manifest.permission.REQUEST_INSTALL_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_SHARED_USER_INCOMPATIBLE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
54import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
56import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
57import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
58import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65import static android.content.pm.PackageManager.MATCH_ALL;
66import static android.content.pm.PackageManager.MATCH_ANY_USER;
67import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
80import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
81import static android.content.pm.PackageManager.PERMISSION_DENIED;
82import static android.content.pm.PackageManager.PERMISSION_GRANTED;
83import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
84import static android.content.pm.PackageParser.isApkFile;
85import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
86import static android.system.OsConstants.O_CREAT;
87import static android.system.OsConstants.O_RDWR;
88import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
89import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
90import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
91import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
92import static com.android.internal.util.ArrayUtils.appendInt;
93import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
94import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
95import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
96import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
97import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
98import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
99import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
100import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
101import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
103import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
104
105import android.Manifest;
106import android.annotation.NonNull;
107import android.annotation.Nullable;
108import android.app.ActivityManager;
109import android.app.AppOpsManager;
110import android.app.IActivityManager;
111import android.app.ResourcesManager;
112import android.app.admin.IDevicePolicyManager;
113import android.app.admin.SecurityLog;
114import android.app.backup.IBackupManager;
115import android.content.BroadcastReceiver;
116import android.content.ComponentName;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.IIntentReceiver;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.IntentSender.SendIntentException;
124import android.content.ServiceConnection;
125import android.content.pm.ActivityInfo;
126import android.content.pm.ApplicationInfo;
127import android.content.pm.AppsQueryHelper;
128import android.content.pm.ChangedPackages;
129import android.content.pm.ComponentInfo;
130import android.content.pm.InstantAppRequest;
131import android.content.pm.AuxiliaryResolveInfo;
132import android.content.pm.FallbackCategoryProvider;
133import android.content.pm.FeatureInfo;
134import android.content.pm.IOnPermissionsChangeListener;
135import android.content.pm.IPackageDataObserver;
136import android.content.pm.IPackageDeleteObserver;
137import android.content.pm.IPackageDeleteObserver2;
138import android.content.pm.IPackageInstallObserver2;
139import android.content.pm.IPackageInstaller;
140import android.content.pm.IPackageManager;
141import android.content.pm.IPackageMoveObserver;
142import android.content.pm.IPackageStatsObserver;
143import android.content.pm.InstantAppInfo;
144import android.content.pm.InstantAppResolveInfo;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.IntentFilterVerificationInfo;
147import android.content.pm.KeySet;
148import android.content.pm.PackageCleanItem;
149import android.content.pm.PackageInfo;
150import android.content.pm.PackageInfoLite;
151import android.content.pm.PackageInstaller;
152import android.content.pm.PackageManager;
153import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
154import android.content.pm.PackageManagerInternal;
155import android.content.pm.PackageParser;
156import android.content.pm.PackageParser.ActivityIntentInfo;
157import android.content.pm.PackageParser.PackageLite;
158import android.content.pm.PackageParser.PackageParserException;
159import android.content.pm.PackageStats;
160import android.content.pm.PackageUserState;
161import android.content.pm.ParceledListSlice;
162import android.content.pm.PermissionGroupInfo;
163import android.content.pm.PermissionInfo;
164import android.content.pm.ProviderInfo;
165import android.content.pm.ResolveInfo;
166import android.content.pm.ServiceInfo;
167import android.content.pm.SharedLibraryInfo;
168import android.content.pm.Signature;
169import android.content.pm.UserInfo;
170import android.content.pm.VerifierDeviceIdentity;
171import android.content.pm.VerifierInfo;
172import android.content.pm.VersionedPackage;
173import android.content.res.Resources;
174import android.database.ContentObserver;
175import android.graphics.Bitmap;
176import android.hardware.display.DisplayManager;
177import android.net.Uri;
178import android.os.Binder;
179import android.os.Build;
180import android.os.Bundle;
181import android.os.Debug;
182import android.os.Environment;
183import android.os.Environment.UserEnvironment;
184import android.os.FileUtils;
185import android.os.Handler;
186import android.os.IBinder;
187import android.os.Looper;
188import android.os.Message;
189import android.os.Parcel;
190import android.os.ParcelFileDescriptor;
191import android.os.PatternMatcher;
192import android.os.Process;
193import android.os.RemoteCallbackList;
194import android.os.RemoteException;
195import android.os.ResultReceiver;
196import android.os.SELinux;
197import android.os.ServiceManager;
198import android.os.ShellCallback;
199import android.os.SystemClock;
200import android.os.SystemProperties;
201import android.os.Trace;
202import android.os.UserHandle;
203import android.os.UserManager;
204import android.os.UserManagerInternal;
205import android.os.storage.IStorageManager;
206import android.os.storage.StorageEventListener;
207import android.os.storage.StorageManager;
208import android.os.storage.StorageManagerInternal;
209import android.os.storage.VolumeInfo;
210import android.os.storage.VolumeRecord;
211import android.provider.Settings.Global;
212import android.provider.Settings.Secure;
213import android.security.KeyStore;
214import android.security.SystemKeyStore;
215import android.service.pm.PackageServiceDumpProto;
216import android.system.ErrnoException;
217import android.system.Os;
218import android.text.TextUtils;
219import android.text.format.DateUtils;
220import android.util.ArrayMap;
221import android.util.ArraySet;
222import android.util.Base64;
223import android.util.BootTimingsTraceLog;
224import android.util.DisplayMetrics;
225import android.util.EventLog;
226import android.util.ExceptionUtils;
227import android.util.Log;
228import android.util.LogPrinter;
229import android.util.MathUtils;
230import android.util.PackageUtils;
231import android.util.Pair;
232import android.util.PrintStreamPrinter;
233import android.util.Slog;
234import android.util.SparseArray;
235import android.util.SparseBooleanArray;
236import android.util.SparseIntArray;
237import android.util.Xml;
238import android.util.jar.StrictJarFile;
239import android.util.proto.ProtoOutputStream;
240import android.view.Display;
241
242import com.android.internal.R;
243import com.android.internal.annotations.GuardedBy;
244import com.android.internal.app.IMediaContainerService;
245import com.android.internal.app.ResolverActivity;
246import com.android.internal.content.NativeLibraryHelper;
247import com.android.internal.content.PackageHelper;
248import com.android.internal.logging.MetricsLogger;
249import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
250import com.android.internal.os.IParcelFileDescriptorFactory;
251import com.android.internal.os.RoSystemProperties;
252import com.android.internal.os.SomeArgs;
253import com.android.internal.os.Zygote;
254import com.android.internal.telephony.CarrierAppUtils;
255import com.android.internal.util.ArrayUtils;
256import com.android.internal.util.ConcurrentUtils;
257import com.android.internal.util.DumpUtils;
258import com.android.internal.util.FastPrintWriter;
259import com.android.internal.util.FastXmlSerializer;
260import com.android.internal.util.IndentingPrintWriter;
261import com.android.internal.util.Preconditions;
262import com.android.internal.util.XmlUtils;
263import com.android.server.AttributeCache;
264import com.android.server.DeviceIdleController;
265import com.android.server.EventLogTags;
266import com.android.server.FgThread;
267import com.android.server.IntentResolver;
268import com.android.server.LocalServices;
269import com.android.server.LockGuard;
270import com.android.server.ServiceThread;
271import com.android.server.SystemConfig;
272import com.android.server.SystemServerInitThreadPool;
273import com.android.server.Watchdog;
274import com.android.server.net.NetworkPolicyManagerInternal;
275import com.android.server.pm.Installer.InstallerException;
276import com.android.server.pm.PermissionsState.PermissionState;
277import com.android.server.pm.Settings.DatabaseVersion;
278import com.android.server.pm.Settings.VersionInfo;
279import com.android.server.pm.dex.DexManager;
280import com.android.server.storage.DeviceStorageMonitorInternal;
281
282import dalvik.system.CloseGuard;
283import dalvik.system.DexFile;
284import dalvik.system.VMRuntime;
285
286import libcore.io.IoUtils;
287import libcore.util.EmptyArray;
288
289import org.xmlpull.v1.XmlPullParser;
290import org.xmlpull.v1.XmlPullParserException;
291import org.xmlpull.v1.XmlSerializer;
292
293import java.io.BufferedOutputStream;
294import java.io.BufferedReader;
295import java.io.ByteArrayInputStream;
296import java.io.ByteArrayOutputStream;
297import java.io.File;
298import java.io.FileDescriptor;
299import java.io.FileInputStream;
300import java.io.FileOutputStream;
301import java.io.FileReader;
302import java.io.FilenameFilter;
303import java.io.IOException;
304import java.io.PrintWriter;
305import java.nio.charset.StandardCharsets;
306import java.security.DigestInputStream;
307import java.security.MessageDigest;
308import java.security.NoSuchAlgorithmException;
309import java.security.PublicKey;
310import java.security.SecureRandom;
311import java.security.cert.Certificate;
312import java.security.cert.CertificateEncodingException;
313import java.security.cert.CertificateException;
314import java.text.SimpleDateFormat;
315import java.util.ArrayList;
316import java.util.Arrays;
317import java.util.Collection;
318import java.util.Collections;
319import java.util.Comparator;
320import java.util.Date;
321import java.util.HashMap;
322import java.util.HashSet;
323import java.util.Iterator;
324import java.util.List;
325import java.util.Map;
326import java.util.Objects;
327import java.util.Set;
328import java.util.concurrent.CountDownLatch;
329import java.util.concurrent.Future;
330import java.util.concurrent.TimeUnit;
331import java.util.concurrent.atomic.AtomicBoolean;
332import java.util.concurrent.atomic.AtomicInteger;
333
334/**
335 * Keep track of all those APKs everywhere.
336 * <p>
337 * Internally there are two important locks:
338 * <ul>
339 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
340 * and other related state. It is a fine-grained lock that should only be held
341 * momentarily, as it's one of the most contended locks in the system.
342 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
343 * operations typically involve heavy lifting of application data on disk. Since
344 * {@code installd} is single-threaded, and it's operations can often be slow,
345 * this lock should never be acquired while already holding {@link #mPackages}.
346 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
347 * holding {@link #mInstallLock}.
348 * </ul>
349 * Many internal methods rely on the caller to hold the appropriate locks, and
350 * this contract is expressed through method name suffixes:
351 * <ul>
352 * <li>fooLI(): the caller must hold {@link #mInstallLock}
353 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
354 * being modified must be frozen
355 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
356 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
357 * </ul>
358 * <p>
359 * Because this class is very central to the platform's security; please run all
360 * CTS and unit tests whenever making modifications:
361 *
362 * <pre>
363 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
364 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
365 * </pre>
366 */
367public class PackageManagerService extends IPackageManager.Stub
368        implements PackageSender {
369    static final String TAG = "PackageManager";
370    static final boolean DEBUG_SETTINGS = false;
371    static final boolean DEBUG_PREFERRED = false;
372    static final boolean DEBUG_UPGRADE = false;
373    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
374    private static final boolean DEBUG_BACKUP = false;
375    private static final boolean DEBUG_INSTALL = false;
376    private static final boolean DEBUG_REMOVE = false;
377    private static final boolean DEBUG_BROADCASTS = false;
378    private static final boolean DEBUG_SHOW_INFO = false;
379    private static final boolean DEBUG_PACKAGE_INFO = false;
380    private static final boolean DEBUG_INTENT_MATCHING = false;
381    private static final boolean DEBUG_PACKAGE_SCANNING = false;
382    private static final boolean DEBUG_VERIFY = false;
383    private static final boolean DEBUG_FILTERS = false;
384
385    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
386    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
387    // user, but by default initialize to this.
388    public static final boolean DEBUG_DEXOPT = false;
389
390    private static final boolean DEBUG_ABI_SELECTION = false;
391    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
392    private static final boolean DEBUG_TRIAGED_MISSING = false;
393    private static final boolean DEBUG_APP_DATA = false;
394
395    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
396    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
397
398    private static final boolean HIDE_EPHEMERAL_APIS = false;
399
400    private static final boolean ENABLE_FREE_CACHE_V2 =
401            SystemProperties.getBoolean("fw.free_cache_v2", true);
402
403    private static final int RADIO_UID = Process.PHONE_UID;
404    private static final int LOG_UID = Process.LOG_UID;
405    private static final int NFC_UID = Process.NFC_UID;
406    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
407    private static final int SHELL_UID = Process.SHELL_UID;
408
409    // Cap the size of permission trees that 3rd party apps can define
410    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
411
412    // Suffix used during package installation when copying/moving
413    // package apks to install directory.
414    private static final String INSTALL_PACKAGE_SUFFIX = "-";
415
416    static final int SCAN_NO_DEX = 1<<1;
417    static final int SCAN_FORCE_DEX = 1<<2;
418    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
419    static final int SCAN_NEW_INSTALL = 1<<4;
420    static final int SCAN_UPDATE_TIME = 1<<5;
421    static final int SCAN_BOOTING = 1<<6;
422    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
423    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
424    static final int SCAN_REPLACING = 1<<9;
425    static final int SCAN_REQUIRE_KNOWN = 1<<10;
426    static final int SCAN_MOVE = 1<<11;
427    static final int SCAN_INITIAL = 1<<12;
428    static final int SCAN_CHECK_ONLY = 1<<13;
429    static final int SCAN_DONT_KILL_APP = 1<<14;
430    static final int SCAN_IGNORE_FROZEN = 1<<15;
431    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
432    static final int SCAN_AS_INSTANT_APP = 1<<17;
433    static final int SCAN_AS_FULL_APP = 1<<18;
434    /** Should not be with the scan flags */
435    static final int FLAGS_REMOVE_CHATTY = 1<<31;
436
437    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
438
439    private static final int[] EMPTY_INT_ARRAY = new int[0];
440
441    /**
442     * Timeout (in milliseconds) after which the watchdog should declare that
443     * our handler thread is wedged.  The usual default for such things is one
444     * minute but we sometimes do very lengthy I/O operations on this thread,
445     * such as installing multi-gigabyte applications, so ours needs to be longer.
446     */
447    private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
448
449    /**
450     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
451     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
452     * settings entry if available, otherwise we use the hardcoded default.  If it's been
453     * more than this long since the last fstrim, we force one during the boot sequence.
454     *
455     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
456     * one gets run at the next available charging+idle time.  This final mandatory
457     * no-fstrim check kicks in only of the other scheduling criteria is never met.
458     */
459    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
460
461    /**
462     * Whether verification is enabled by default.
463     */
464    private static final boolean DEFAULT_VERIFY_ENABLE = true;
465
466    /**
467     * The default maximum time to wait for the verification agent to return in
468     * milliseconds.
469     */
470    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
471
472    /**
473     * The default response for package verification timeout.
474     *
475     * This can be either PackageManager.VERIFICATION_ALLOW or
476     * PackageManager.VERIFICATION_REJECT.
477     */
478    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
479
480    static final String PLATFORM_PACKAGE_NAME = "android";
481
482    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
483
484    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
485            DEFAULT_CONTAINER_PACKAGE,
486            "com.android.defcontainer.DefaultContainerService");
487
488    private static final String KILL_APP_REASON_GIDS_CHANGED =
489            "permission grant or revoke changed gids";
490
491    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
492            "permissions revoked";
493
494    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
495
496    private static final String PACKAGE_SCHEME = "package";
497
498    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
499
500    /** Permission grant: not grant the permission. */
501    private static final int GRANT_DENIED = 1;
502
503    /** Permission grant: grant the permission as an install permission. */
504    private static final int GRANT_INSTALL = 2;
505
506    /** Permission grant: grant the permission as a runtime one. */
507    private static final int GRANT_RUNTIME = 3;
508
509    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
510    private static final int GRANT_UPGRADE = 4;
511
512    /** Canonical intent used to identify what counts as a "web browser" app */
513    private static final Intent sBrowserIntent;
514    static {
515        sBrowserIntent = new Intent();
516        sBrowserIntent.setAction(Intent.ACTION_VIEW);
517        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
518        sBrowserIntent.setData(Uri.parse("http:"));
519    }
520
521    /**
522     * The set of all protected actions [i.e. those actions for which a high priority
523     * intent filter is disallowed].
524     */
525    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
526    static {
527        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
528        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
529        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
530        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
531    }
532
533    // Compilation reasons.
534    public static final int REASON_FIRST_BOOT = 0;
535    public static final int REASON_BOOT = 1;
536    public static final int REASON_INSTALL = 2;
537    public static final int REASON_BACKGROUND_DEXOPT = 3;
538    public static final int REASON_AB_OTA = 4;
539
540    public static final int REASON_LAST = REASON_AB_OTA;
541
542    /** All dangerous permission names in the same order as the events in MetricsEvent */
543    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
544            Manifest.permission.READ_CALENDAR,
545            Manifest.permission.WRITE_CALENDAR,
546            Manifest.permission.CAMERA,
547            Manifest.permission.READ_CONTACTS,
548            Manifest.permission.WRITE_CONTACTS,
549            Manifest.permission.GET_ACCOUNTS,
550            Manifest.permission.ACCESS_FINE_LOCATION,
551            Manifest.permission.ACCESS_COARSE_LOCATION,
552            Manifest.permission.RECORD_AUDIO,
553            Manifest.permission.READ_PHONE_STATE,
554            Manifest.permission.CALL_PHONE,
555            Manifest.permission.READ_CALL_LOG,
556            Manifest.permission.WRITE_CALL_LOG,
557            Manifest.permission.ADD_VOICEMAIL,
558            Manifest.permission.USE_SIP,
559            Manifest.permission.PROCESS_OUTGOING_CALLS,
560            Manifest.permission.READ_CELL_BROADCASTS,
561            Manifest.permission.BODY_SENSORS,
562            Manifest.permission.SEND_SMS,
563            Manifest.permission.RECEIVE_SMS,
564            Manifest.permission.READ_SMS,
565            Manifest.permission.RECEIVE_WAP_PUSH,
566            Manifest.permission.RECEIVE_MMS,
567            Manifest.permission.READ_EXTERNAL_STORAGE,
568            Manifest.permission.WRITE_EXTERNAL_STORAGE,
569            Manifest.permission.READ_PHONE_NUMBERS,
570            Manifest.permission.ANSWER_PHONE_CALLS);
571
572
573    /**
574     * Version number for the package parser cache. Increment this whenever the format or
575     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
576     */
577    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
578
579    /**
580     * Whether the package parser cache is enabled.
581     */
582    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
583
584    final ServiceThread mHandlerThread;
585
586    final PackageHandler mHandler;
587
588    private final ProcessLoggingHandler mProcessLoggingHandler;
589
590    /**
591     * Messages for {@link #mHandler} that need to wait for system ready before
592     * being dispatched.
593     */
594    private ArrayList<Message> mPostSystemReadyMessages;
595
596    final int mSdkVersion = Build.VERSION.SDK_INT;
597
598    final Context mContext;
599    final boolean mFactoryTest;
600    final boolean mOnlyCore;
601    final DisplayMetrics mMetrics;
602    final int mDefParseFlags;
603    final String[] mSeparateProcesses;
604    final boolean mIsUpgrade;
605    final boolean mIsPreNUpgrade;
606    final boolean mIsPreNMR1Upgrade;
607
608    // Have we told the Activity Manager to whitelist the default container service by uid yet?
609    @GuardedBy("mPackages")
610    boolean mDefaultContainerWhitelisted = false;
611
612    @GuardedBy("mPackages")
613    private boolean mDexOptDialogShown;
614
615    /** The location for ASEC container files on internal storage. */
616    final String mAsecInternalPath;
617
618    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
619    // LOCK HELD.  Can be called with mInstallLock held.
620    @GuardedBy("mInstallLock")
621    final Installer mInstaller;
622
623    /** Directory where installed third-party apps stored */
624    final File mAppInstallDir;
625
626    /**
627     * Directory to which applications installed internally have their
628     * 32 bit native libraries copied.
629     */
630    private File mAppLib32InstallDir;
631
632    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
633    // apps.
634    final File mDrmAppPrivateInstallDir;
635
636    // ----------------------------------------------------------------
637
638    // Lock for state used when installing and doing other long running
639    // operations.  Methods that must be called with this lock held have
640    // the suffix "LI".
641    final Object mInstallLock = new Object();
642
643    // ----------------------------------------------------------------
644
645    // Keys are String (package name), values are Package.  This also serves
646    // as the lock for the global state.  Methods that must be called with
647    // this lock held have the prefix "LP".
648    @GuardedBy("mPackages")
649    final ArrayMap<String, PackageParser.Package> mPackages =
650            new ArrayMap<String, PackageParser.Package>();
651
652    final ArrayMap<String, Set<String>> mKnownCodebase =
653            new ArrayMap<String, Set<String>>();
654
655    // Keys are isolated uids and values are the uid of the application
656    // that created the isolated proccess.
657    @GuardedBy("mPackages")
658    final SparseIntArray mIsolatedOwners = new SparseIntArray();
659
660    // List of APK paths to load for each user and package. This data is never
661    // persisted by the package manager. Instead, the overlay manager will
662    // ensure the data is up-to-date in runtime.
663    @GuardedBy("mPackages")
664    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
665        new SparseArray<ArrayMap<String, ArrayList<String>>>();
666
667    /**
668     * Tracks new system packages [received in an OTA] that we expect to
669     * find updated user-installed versions. Keys are package name, values
670     * are package location.
671     */
672    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
673    /**
674     * Tracks high priority intent filters for protected actions. During boot, certain
675     * filter actions are protected and should never be allowed to have a high priority
676     * intent filter for them. However, there is one, and only one exception -- the
677     * setup wizard. It must be able to define a high priority intent filter for these
678     * actions to ensure there are no escapes from the wizard. We need to delay processing
679     * of these during boot as we need to look at all of the system packages in order
680     * to know which component is the setup wizard.
681     */
682    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
683    /**
684     * Whether or not processing protected filters should be deferred.
685     */
686    private boolean mDeferProtectedFilters = true;
687
688    /**
689     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
690     */
691    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
692    /**
693     * Whether or not system app permissions should be promoted from install to runtime.
694     */
695    boolean mPromoteSystemApps;
696
697    @GuardedBy("mPackages")
698    final Settings mSettings;
699
700    /**
701     * Set of package names that are currently "frozen", which means active
702     * surgery is being done on the code/data for that package. The platform
703     * will refuse to launch frozen packages to avoid race conditions.
704     *
705     * @see PackageFreezer
706     */
707    @GuardedBy("mPackages")
708    final ArraySet<String> mFrozenPackages = new ArraySet<>();
709
710    final ProtectedPackages mProtectedPackages;
711
712    boolean mFirstBoot;
713
714    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
715
716    // System configuration read by SystemConfig.
717    final int[] mGlobalGids;
718    final SparseArray<ArraySet<String>> mSystemPermissions;
719    @GuardedBy("mAvailableFeatures")
720    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
721
722    // If mac_permissions.xml was found for seinfo labeling.
723    boolean mFoundPolicyFile;
724
725    private final InstantAppRegistry mInstantAppRegistry;
726
727    @GuardedBy("mPackages")
728    int mChangedPackagesSequenceNumber;
729    /**
730     * List of changed [installed, removed or updated] packages.
731     * mapping from user id -> sequence number -> package name
732     */
733    @GuardedBy("mPackages")
734    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
735    /**
736     * The sequence number of the last change to a package.
737     * mapping from user id -> package name -> sequence number
738     */
739    @GuardedBy("mPackages")
740    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
741
742    final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
743        @Override public boolean hasFeature(String feature) {
744            return PackageManagerService.this.hasSystemFeature(feature, 0);
745        }
746    };
747
748    public static final class SharedLibraryEntry {
749        public final String path;
750        public final String apk;
751        public final SharedLibraryInfo info;
752
753        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
754                String declaringPackageName, int declaringPackageVersionCode) {
755            path = _path;
756            apk = _apk;
757            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
758                    declaringPackageName, declaringPackageVersionCode), null);
759        }
760    }
761
762    // Currently known shared libraries.
763    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
764    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
765            new ArrayMap<>();
766
767    // All available activities, for your resolving pleasure.
768    final ActivityIntentResolver mActivities =
769            new ActivityIntentResolver();
770
771    // All available receivers, for your resolving pleasure.
772    final ActivityIntentResolver mReceivers =
773            new ActivityIntentResolver();
774
775    // All available services, for your resolving pleasure.
776    final ServiceIntentResolver mServices = new ServiceIntentResolver();
777
778    // All available providers, for your resolving pleasure.
779    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
780
781    // Mapping from provider base names (first directory in content URI codePath)
782    // to the provider information.
783    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
784            new ArrayMap<String, PackageParser.Provider>();
785
786    // Mapping from instrumentation class names to info about them.
787    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
788            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
789
790    // Mapping from permission names to info about them.
791    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
792            new ArrayMap<String, PackageParser.PermissionGroup>();
793
794    // Packages whose data we have transfered into another package, thus
795    // should no longer exist.
796    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
797
798    // Broadcast actions that are only available to the system.
799    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
800
801    /** List of packages waiting for verification. */
802    final SparseArray<PackageVerificationState> mPendingVerification
803            = new SparseArray<PackageVerificationState>();
804
805    /** Set of packages associated with each app op permission. */
806    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
807
808    final PackageInstallerService mInstallerService;
809
810    private final PackageDexOptimizer mPackageDexOptimizer;
811    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
812    // is used by other apps).
813    private final DexManager mDexManager;
814
815    private AtomicInteger mNextMoveId = new AtomicInteger();
816    private final MoveCallbacks mMoveCallbacks;
817
818    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
819
820    // Cache of users who need badging.
821    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
822
823    /** Token for keys in mPendingVerification. */
824    private int mPendingVerificationToken = 0;
825
826    volatile boolean mSystemReady;
827    volatile boolean mSafeMode;
828    volatile boolean mHasSystemUidErrors;
829    private volatile boolean mEphemeralAppsDisabled;
830
831    ApplicationInfo mAndroidApplication;
832    final ActivityInfo mResolveActivity = new ActivityInfo();
833    final ResolveInfo mResolveInfo = new ResolveInfo();
834    ComponentName mResolveComponentName;
835    PackageParser.Package mPlatformPackage;
836    ComponentName mCustomResolverComponentName;
837
838    boolean mResolverReplaced = false;
839
840    private final @Nullable ComponentName mIntentFilterVerifierComponent;
841    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
842
843    private int mIntentFilterVerificationToken = 0;
844
845    /** The service connection to the ephemeral resolver */
846    final EphemeralResolverConnection mInstantAppResolverConnection;
847    /** Component used to show resolver settings for Instant Apps */
848    final ComponentName mInstantAppResolverSettingsComponent;
849
850    /** Activity used to install instant applications */
851    ActivityInfo mInstantAppInstallerActivity;
852    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
853
854    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
855            = new SparseArray<IntentFilterVerificationState>();
856
857    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
858
859    // List of packages names to keep cached, even if they are uninstalled for all users
860    private List<String> mKeepUninstalledPackages;
861
862    private UserManagerInternal mUserManagerInternal;
863
864    private DeviceIdleController.LocalService mDeviceIdleController;
865
866    private File mCacheDir;
867
868    private ArraySet<String> mPrivappPermissionsViolations;
869
870    private Future<?> mPrepareAppDataFuture;
871
872    private static class IFVerificationParams {
873        PackageParser.Package pkg;
874        boolean replacing;
875        int userId;
876        int verifierUid;
877
878        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
879                int _userId, int _verifierUid) {
880            pkg = _pkg;
881            replacing = _replacing;
882            userId = _userId;
883            replacing = _replacing;
884            verifierUid = _verifierUid;
885        }
886    }
887
888    private interface IntentFilterVerifier<T extends IntentFilter> {
889        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
890                                               T filter, String packageName);
891        void startVerifications(int userId);
892        void receiveVerificationResponse(int verificationId);
893    }
894
895    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
896        private Context mContext;
897        private ComponentName mIntentFilterVerifierComponent;
898        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
899
900        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
901            mContext = context;
902            mIntentFilterVerifierComponent = verifierComponent;
903        }
904
905        private String getDefaultScheme() {
906            return IntentFilter.SCHEME_HTTPS;
907        }
908
909        @Override
910        public void startVerifications(int userId) {
911            // Launch verifications requests
912            int count = mCurrentIntentFilterVerifications.size();
913            for (int n=0; n<count; n++) {
914                int verificationId = mCurrentIntentFilterVerifications.get(n);
915                final IntentFilterVerificationState ivs =
916                        mIntentFilterVerificationStates.get(verificationId);
917
918                String packageName = ivs.getPackageName();
919
920                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
921                final int filterCount = filters.size();
922                ArraySet<String> domainsSet = new ArraySet<>();
923                for (int m=0; m<filterCount; m++) {
924                    PackageParser.ActivityIntentInfo filter = filters.get(m);
925                    domainsSet.addAll(filter.getHostsList());
926                }
927                synchronized (mPackages) {
928                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
929                            packageName, domainsSet) != null) {
930                        scheduleWriteSettingsLocked();
931                    }
932                }
933                sendVerificationRequest(userId, verificationId, ivs);
934            }
935            mCurrentIntentFilterVerifications.clear();
936        }
937
938        private void sendVerificationRequest(int userId, int verificationId,
939                IntentFilterVerificationState ivs) {
940
941            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
942            verificationIntent.putExtra(
943                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
944                    verificationId);
945            verificationIntent.putExtra(
946                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
947                    getDefaultScheme());
948            verificationIntent.putExtra(
949                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
950                    ivs.getHostsString());
951            verificationIntent.putExtra(
952                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
953                    ivs.getPackageName());
954            verificationIntent.setComponent(mIntentFilterVerifierComponent);
955            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
956
957            DeviceIdleController.LocalService idleController = getDeviceIdleController();
958            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
959                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
960                    userId, false, "intent filter verifier");
961
962            UserHandle user = new UserHandle(userId);
963            mContext.sendBroadcastAsUser(verificationIntent, user);
964            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
965                    "Sending IntentFilter verification broadcast");
966        }
967
968        public void receiveVerificationResponse(int verificationId) {
969            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
970
971            final boolean verified = ivs.isVerified();
972
973            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
974            final int count = filters.size();
975            if (DEBUG_DOMAIN_VERIFICATION) {
976                Slog.i(TAG, "Received verification response " + verificationId
977                        + " for " + count + " filters, verified=" + verified);
978            }
979            for (int n=0; n<count; n++) {
980                PackageParser.ActivityIntentInfo filter = filters.get(n);
981                filter.setVerified(verified);
982
983                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
984                        + " verified with result:" + verified + " and hosts:"
985                        + ivs.getHostsString());
986            }
987
988            mIntentFilterVerificationStates.remove(verificationId);
989
990            final String packageName = ivs.getPackageName();
991            IntentFilterVerificationInfo ivi = null;
992
993            synchronized (mPackages) {
994                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
995            }
996            if (ivi == null) {
997                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
998                        + verificationId + " packageName:" + packageName);
999                return;
1000            }
1001            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1002                    "Updating IntentFilterVerificationInfo for package " + packageName
1003                            +" verificationId:" + verificationId);
1004
1005            synchronized (mPackages) {
1006                if (verified) {
1007                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1008                } else {
1009                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1010                }
1011                scheduleWriteSettingsLocked();
1012
1013                final int userId = ivs.getUserId();
1014                if (userId != UserHandle.USER_ALL) {
1015                    final int userStatus =
1016                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1017
1018                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1019                    boolean needUpdate = false;
1020
1021                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1022                    // already been set by the User thru the Disambiguation dialog
1023                    switch (userStatus) {
1024                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1025                            if (verified) {
1026                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1027                            } else {
1028                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1029                            }
1030                            needUpdate = true;
1031                            break;
1032
1033                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1034                            if (verified) {
1035                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1036                                needUpdate = true;
1037                            }
1038                            break;
1039
1040                        default:
1041                            // Nothing to do
1042                    }
1043
1044                    if (needUpdate) {
1045                        mSettings.updateIntentFilterVerificationStatusLPw(
1046                                packageName, updatedStatus, userId);
1047                        scheduleWritePackageRestrictionsLocked(userId);
1048                    }
1049                }
1050            }
1051        }
1052
1053        @Override
1054        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1055                    ActivityIntentInfo filter, String packageName) {
1056            if (!hasValidDomains(filter)) {
1057                return false;
1058            }
1059            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1060            if (ivs == null) {
1061                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1062                        packageName);
1063            }
1064            if (DEBUG_DOMAIN_VERIFICATION) {
1065                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1066            }
1067            ivs.addFilter(filter);
1068            return true;
1069        }
1070
1071        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1072                int userId, int verificationId, String packageName) {
1073            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1074                    verifierUid, userId, packageName);
1075            ivs.setPendingState();
1076            synchronized (mPackages) {
1077                mIntentFilterVerificationStates.append(verificationId, ivs);
1078                mCurrentIntentFilterVerifications.add(verificationId);
1079            }
1080            return ivs;
1081        }
1082    }
1083
1084    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1085        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1086                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1087                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1088    }
1089
1090    // Set of pending broadcasts for aggregating enable/disable of components.
1091    static class PendingPackageBroadcasts {
1092        // for each user id, a map of <package name -> components within that package>
1093        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1094
1095        public PendingPackageBroadcasts() {
1096            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1097        }
1098
1099        public ArrayList<String> get(int userId, String packageName) {
1100            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1101            return packages.get(packageName);
1102        }
1103
1104        public void put(int userId, String packageName, ArrayList<String> components) {
1105            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1106            packages.put(packageName, components);
1107        }
1108
1109        public void remove(int userId, String packageName) {
1110            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1111            if (packages != null) {
1112                packages.remove(packageName);
1113            }
1114        }
1115
1116        public void remove(int userId) {
1117            mUidMap.remove(userId);
1118        }
1119
1120        public int userIdCount() {
1121            return mUidMap.size();
1122        }
1123
1124        public int userIdAt(int n) {
1125            return mUidMap.keyAt(n);
1126        }
1127
1128        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1129            return mUidMap.get(userId);
1130        }
1131
1132        public int size() {
1133            // total number of pending broadcast entries across all userIds
1134            int num = 0;
1135            for (int i = 0; i< mUidMap.size(); i++) {
1136                num += mUidMap.valueAt(i).size();
1137            }
1138            return num;
1139        }
1140
1141        public void clear() {
1142            mUidMap.clear();
1143        }
1144
1145        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1146            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1147            if (map == null) {
1148                map = new ArrayMap<String, ArrayList<String>>();
1149                mUidMap.put(userId, map);
1150            }
1151            return map;
1152        }
1153    }
1154    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1155
1156    // Service Connection to remote media container service to copy
1157    // package uri's from external media onto secure containers
1158    // or internal storage.
1159    private IMediaContainerService mContainerService = null;
1160
1161    static final int SEND_PENDING_BROADCAST = 1;
1162    static final int MCS_BOUND = 3;
1163    static final int END_COPY = 4;
1164    static final int INIT_COPY = 5;
1165    static final int MCS_UNBIND = 6;
1166    static final int START_CLEANING_PACKAGE = 7;
1167    static final int FIND_INSTALL_LOC = 8;
1168    static final int POST_INSTALL = 9;
1169    static final int MCS_RECONNECT = 10;
1170    static final int MCS_GIVE_UP = 11;
1171    static final int UPDATED_MEDIA_STATUS = 12;
1172    static final int WRITE_SETTINGS = 13;
1173    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1174    static final int PACKAGE_VERIFIED = 15;
1175    static final int CHECK_PENDING_VERIFICATION = 16;
1176    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1177    static final int INTENT_FILTER_VERIFIED = 18;
1178    static final int WRITE_PACKAGE_LIST = 19;
1179    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1180
1181    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1182
1183    // Delay time in millisecs
1184    static final int BROADCAST_DELAY = 10 * 1000;
1185
1186    static UserManagerService sUserManager;
1187
1188    // Stores a list of users whose package restrictions file needs to be updated
1189    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1190
1191    final private DefaultContainerConnection mDefContainerConn =
1192            new DefaultContainerConnection();
1193    class DefaultContainerConnection implements ServiceConnection {
1194        public void onServiceConnected(ComponentName name, IBinder service) {
1195            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1196            final IMediaContainerService imcs = IMediaContainerService.Stub
1197                    .asInterface(Binder.allowBlocking(service));
1198            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1199        }
1200
1201        public void onServiceDisconnected(ComponentName name) {
1202            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1203        }
1204    }
1205
1206    // Recordkeeping of restore-after-install operations that are currently in flight
1207    // between the Package Manager and the Backup Manager
1208    static class PostInstallData {
1209        public InstallArgs args;
1210        public PackageInstalledInfo res;
1211
1212        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1213            args = _a;
1214            res = _r;
1215        }
1216    }
1217
1218    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1219    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1220
1221    // XML tags for backup/restore of various bits of state
1222    private static final String TAG_PREFERRED_BACKUP = "pa";
1223    private static final String TAG_DEFAULT_APPS = "da";
1224    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1225
1226    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1227    private static final String TAG_ALL_GRANTS = "rt-grants";
1228    private static final String TAG_GRANT = "grant";
1229    private static final String ATTR_PACKAGE_NAME = "pkg";
1230
1231    private static final String TAG_PERMISSION = "perm";
1232    private static final String ATTR_PERMISSION_NAME = "name";
1233    private static final String ATTR_IS_GRANTED = "g";
1234    private static final String ATTR_USER_SET = "set";
1235    private static final String ATTR_USER_FIXED = "fixed";
1236    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1237
1238    // System/policy permission grants are not backed up
1239    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1240            FLAG_PERMISSION_POLICY_FIXED
1241            | FLAG_PERMISSION_SYSTEM_FIXED
1242            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1243
1244    // And we back up these user-adjusted states
1245    private static final int USER_RUNTIME_GRANT_MASK =
1246            FLAG_PERMISSION_USER_SET
1247            | FLAG_PERMISSION_USER_FIXED
1248            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1249
1250    final @Nullable String mRequiredVerifierPackage;
1251    final @NonNull String mRequiredInstallerPackage;
1252    final @NonNull String mRequiredUninstallerPackage;
1253    final @Nullable String mSetupWizardPackage;
1254    final @Nullable String mStorageManagerPackage;
1255    final @NonNull String mServicesSystemSharedLibraryPackageName;
1256    final @NonNull String mSharedSystemSharedLibraryPackageName;
1257
1258    final boolean mPermissionReviewRequired;
1259
1260    private final PackageUsage mPackageUsage = new PackageUsage();
1261    private final CompilerStats mCompilerStats = new CompilerStats();
1262
1263    class PackageHandler extends Handler {
1264        private boolean mBound = false;
1265        final ArrayList<HandlerParams> mPendingInstalls =
1266            new ArrayList<HandlerParams>();
1267
1268        private boolean connectToService() {
1269            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1270                    " DefaultContainerService");
1271            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1272            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1273            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1274                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1275                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1276                mBound = true;
1277                return true;
1278            }
1279            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1280            return false;
1281        }
1282
1283        private void disconnectService() {
1284            mContainerService = null;
1285            mBound = false;
1286            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1287            mContext.unbindService(mDefContainerConn);
1288            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1289        }
1290
1291        PackageHandler(Looper looper) {
1292            super(looper);
1293        }
1294
1295        public void handleMessage(Message msg) {
1296            try {
1297                doHandleMessage(msg);
1298            } finally {
1299                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1300            }
1301        }
1302
1303        void doHandleMessage(Message msg) {
1304            switch (msg.what) {
1305                case INIT_COPY: {
1306                    HandlerParams params = (HandlerParams) msg.obj;
1307                    int idx = mPendingInstalls.size();
1308                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1309                    // If a bind was already initiated we dont really
1310                    // need to do anything. The pending install
1311                    // will be processed later on.
1312                    if (!mBound) {
1313                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1314                                System.identityHashCode(mHandler));
1315                        // If this is the only one pending we might
1316                        // have to bind to the service again.
1317                        if (!connectToService()) {
1318                            Slog.e(TAG, "Failed to bind to media container service");
1319                            params.serviceError();
1320                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1321                                    System.identityHashCode(mHandler));
1322                            if (params.traceMethod != null) {
1323                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1324                                        params.traceCookie);
1325                            }
1326                            return;
1327                        } else {
1328                            // Once we bind to the service, the first
1329                            // pending request will be processed.
1330                            mPendingInstalls.add(idx, params);
1331                        }
1332                    } else {
1333                        mPendingInstalls.add(idx, params);
1334                        // Already bound to the service. Just make
1335                        // sure we trigger off processing the first request.
1336                        if (idx == 0) {
1337                            mHandler.sendEmptyMessage(MCS_BOUND);
1338                        }
1339                    }
1340                    break;
1341                }
1342                case MCS_BOUND: {
1343                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1344                    if (msg.obj != null) {
1345                        mContainerService = (IMediaContainerService) msg.obj;
1346                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1347                                System.identityHashCode(mHandler));
1348                    }
1349                    if (mContainerService == null) {
1350                        if (!mBound) {
1351                            // Something seriously wrong since we are not bound and we are not
1352                            // waiting for connection. Bail out.
1353                            Slog.e(TAG, "Cannot bind to media container service");
1354                            for (HandlerParams params : mPendingInstalls) {
1355                                // Indicate service bind error
1356                                params.serviceError();
1357                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1358                                        System.identityHashCode(params));
1359                                if (params.traceMethod != null) {
1360                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1361                                            params.traceMethod, params.traceCookie);
1362                                }
1363                                return;
1364                            }
1365                            mPendingInstalls.clear();
1366                        } else {
1367                            Slog.w(TAG, "Waiting to connect to media container service");
1368                        }
1369                    } else if (mPendingInstalls.size() > 0) {
1370                        HandlerParams params = mPendingInstalls.get(0);
1371                        if (params != null) {
1372                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1373                                    System.identityHashCode(params));
1374                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1375                            if (params.startCopy()) {
1376                                // We are done...  look for more work or to
1377                                // go idle.
1378                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1379                                        "Checking for more work or unbind...");
1380                                // Delete pending install
1381                                if (mPendingInstalls.size() > 0) {
1382                                    mPendingInstalls.remove(0);
1383                                }
1384                                if (mPendingInstalls.size() == 0) {
1385                                    if (mBound) {
1386                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1387                                                "Posting delayed MCS_UNBIND");
1388                                        removeMessages(MCS_UNBIND);
1389                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1390                                        // Unbind after a little delay, to avoid
1391                                        // continual thrashing.
1392                                        sendMessageDelayed(ubmsg, 10000);
1393                                    }
1394                                } else {
1395                                    // There are more pending requests in queue.
1396                                    // Just post MCS_BOUND message to trigger processing
1397                                    // of next pending install.
1398                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1399                                            "Posting MCS_BOUND for next work");
1400                                    mHandler.sendEmptyMessage(MCS_BOUND);
1401                                }
1402                            }
1403                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1404                        }
1405                    } else {
1406                        // Should never happen ideally.
1407                        Slog.w(TAG, "Empty queue");
1408                    }
1409                    break;
1410                }
1411                case MCS_RECONNECT: {
1412                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1413                    if (mPendingInstalls.size() > 0) {
1414                        if (mBound) {
1415                            disconnectService();
1416                        }
1417                        if (!connectToService()) {
1418                            Slog.e(TAG, "Failed to bind to media container service");
1419                            for (HandlerParams params : mPendingInstalls) {
1420                                // Indicate service bind error
1421                                params.serviceError();
1422                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1423                                        System.identityHashCode(params));
1424                            }
1425                            mPendingInstalls.clear();
1426                        }
1427                    }
1428                    break;
1429                }
1430                case MCS_UNBIND: {
1431                    // If there is no actual work left, then time to unbind.
1432                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1433
1434                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1435                        if (mBound) {
1436                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1437
1438                            disconnectService();
1439                        }
1440                    } else if (mPendingInstalls.size() > 0) {
1441                        // There are more pending requests in queue.
1442                        // Just post MCS_BOUND message to trigger processing
1443                        // of next pending install.
1444                        mHandler.sendEmptyMessage(MCS_BOUND);
1445                    }
1446
1447                    break;
1448                }
1449                case MCS_GIVE_UP: {
1450                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1451                    HandlerParams params = mPendingInstalls.remove(0);
1452                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1453                            System.identityHashCode(params));
1454                    break;
1455                }
1456                case SEND_PENDING_BROADCAST: {
1457                    String packages[];
1458                    ArrayList<String> components[];
1459                    int size = 0;
1460                    int uids[];
1461                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1462                    synchronized (mPackages) {
1463                        if (mPendingBroadcasts == null) {
1464                            return;
1465                        }
1466                        size = mPendingBroadcasts.size();
1467                        if (size <= 0) {
1468                            // Nothing to be done. Just return
1469                            return;
1470                        }
1471                        packages = new String[size];
1472                        components = new ArrayList[size];
1473                        uids = new int[size];
1474                        int i = 0;  // filling out the above arrays
1475
1476                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1477                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1478                            Iterator<Map.Entry<String, ArrayList<String>>> it
1479                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1480                                            .entrySet().iterator();
1481                            while (it.hasNext() && i < size) {
1482                                Map.Entry<String, ArrayList<String>> ent = it.next();
1483                                packages[i] = ent.getKey();
1484                                components[i] = ent.getValue();
1485                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1486                                uids[i] = (ps != null)
1487                                        ? UserHandle.getUid(packageUserId, ps.appId)
1488                                        : -1;
1489                                i++;
1490                            }
1491                        }
1492                        size = i;
1493                        mPendingBroadcasts.clear();
1494                    }
1495                    // Send broadcasts
1496                    for (int i = 0; i < size; i++) {
1497                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1498                    }
1499                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1500                    break;
1501                }
1502                case START_CLEANING_PACKAGE: {
1503                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1504                    final String packageName = (String)msg.obj;
1505                    final int userId = msg.arg1;
1506                    final boolean andCode = msg.arg2 != 0;
1507                    synchronized (mPackages) {
1508                        if (userId == UserHandle.USER_ALL) {
1509                            int[] users = sUserManager.getUserIds();
1510                            for (int user : users) {
1511                                mSettings.addPackageToCleanLPw(
1512                                        new PackageCleanItem(user, packageName, andCode));
1513                            }
1514                        } else {
1515                            mSettings.addPackageToCleanLPw(
1516                                    new PackageCleanItem(userId, packageName, andCode));
1517                        }
1518                    }
1519                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1520                    startCleaningPackages();
1521                } break;
1522                case POST_INSTALL: {
1523                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1524
1525                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1526                    final boolean didRestore = (msg.arg2 != 0);
1527                    mRunningInstalls.delete(msg.arg1);
1528
1529                    if (data != null) {
1530                        InstallArgs args = data.args;
1531                        PackageInstalledInfo parentRes = data.res;
1532
1533                        final boolean grantPermissions = (args.installFlags
1534                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1535                        final boolean killApp = (args.installFlags
1536                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1537                        final String[] grantedPermissions = args.installGrantPermissions;
1538
1539                        // Handle the parent package
1540                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1541                                grantedPermissions, didRestore, args.installerPackageName,
1542                                args.observer);
1543
1544                        // Handle the child packages
1545                        final int childCount = (parentRes.addedChildPackages != null)
1546                                ? parentRes.addedChildPackages.size() : 0;
1547                        for (int i = 0; i < childCount; i++) {
1548                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1549                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1550                                    grantedPermissions, false, args.installerPackageName,
1551                                    args.observer);
1552                        }
1553
1554                        // Log tracing if needed
1555                        if (args.traceMethod != null) {
1556                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1557                                    args.traceCookie);
1558                        }
1559                    } else {
1560                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1561                    }
1562
1563                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1564                } break;
1565                case UPDATED_MEDIA_STATUS: {
1566                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1567                    boolean reportStatus = msg.arg1 == 1;
1568                    boolean doGc = msg.arg2 == 1;
1569                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1570                    if (doGc) {
1571                        // Force a gc to clear up stale containers.
1572                        Runtime.getRuntime().gc();
1573                    }
1574                    if (msg.obj != null) {
1575                        @SuppressWarnings("unchecked")
1576                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1577                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1578                        // Unload containers
1579                        unloadAllContainers(args);
1580                    }
1581                    if (reportStatus) {
1582                        try {
1583                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1584                                    "Invoking StorageManagerService call back");
1585                            PackageHelper.getStorageManager().finishMediaUpdate();
1586                        } catch (RemoteException e) {
1587                            Log.e(TAG, "StorageManagerService not running?");
1588                        }
1589                    }
1590                } break;
1591                case WRITE_SETTINGS: {
1592                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1593                    synchronized (mPackages) {
1594                        removeMessages(WRITE_SETTINGS);
1595                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1596                        mSettings.writeLPr();
1597                        mDirtyUsers.clear();
1598                    }
1599                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1600                } break;
1601                case WRITE_PACKAGE_RESTRICTIONS: {
1602                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1603                    synchronized (mPackages) {
1604                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1605                        for (int userId : mDirtyUsers) {
1606                            mSettings.writePackageRestrictionsLPr(userId);
1607                        }
1608                        mDirtyUsers.clear();
1609                    }
1610                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1611                } break;
1612                case WRITE_PACKAGE_LIST: {
1613                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1614                    synchronized (mPackages) {
1615                        removeMessages(WRITE_PACKAGE_LIST);
1616                        mSettings.writePackageListLPr(msg.arg1);
1617                    }
1618                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1619                } break;
1620                case CHECK_PENDING_VERIFICATION: {
1621                    final int verificationId = msg.arg1;
1622                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1623
1624                    if ((state != null) && !state.timeoutExtended()) {
1625                        final InstallArgs args = state.getInstallArgs();
1626                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1627
1628                        Slog.i(TAG, "Verification timed out for " + originUri);
1629                        mPendingVerification.remove(verificationId);
1630
1631                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1632
1633                        if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
1634                            Slog.i(TAG, "Continuing with installation of " + originUri);
1635                            state.setVerifierResponse(Binder.getCallingUid(),
1636                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1637                            broadcastPackageVerified(verificationId, originUri,
1638                                    PackageManager.VERIFICATION_ALLOW,
1639                                    state.getInstallArgs().getUser());
1640                            try {
1641                                ret = args.copyApk(mContainerService, true);
1642                            } catch (RemoteException e) {
1643                                Slog.e(TAG, "Could not contact the ContainerService");
1644                            }
1645                        } else {
1646                            broadcastPackageVerified(verificationId, originUri,
1647                                    PackageManager.VERIFICATION_REJECT,
1648                                    state.getInstallArgs().getUser());
1649                        }
1650
1651                        Trace.asyncTraceEnd(
1652                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1653
1654                        processPendingInstall(args, ret);
1655                        mHandler.sendEmptyMessage(MCS_UNBIND);
1656                    }
1657                    break;
1658                }
1659                case PACKAGE_VERIFIED: {
1660                    final int verificationId = msg.arg1;
1661
1662                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1663                    if (state == null) {
1664                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1665                        break;
1666                    }
1667
1668                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1669
1670                    state.setVerifierResponse(response.callerUid, response.code);
1671
1672                    if (state.isVerificationComplete()) {
1673                        mPendingVerification.remove(verificationId);
1674
1675                        final InstallArgs args = state.getInstallArgs();
1676                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1677
1678                        int ret;
1679                        if (state.isInstallAllowed()) {
1680                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1681                            broadcastPackageVerified(verificationId, originUri,
1682                                    response.code, state.getInstallArgs().getUser());
1683                            try {
1684                                ret = args.copyApk(mContainerService, true);
1685                            } catch (RemoteException e) {
1686                                Slog.e(TAG, "Could not contact the ContainerService");
1687                            }
1688                        } else {
1689                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1690                        }
1691
1692                        Trace.asyncTraceEnd(
1693                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1694
1695                        processPendingInstall(args, ret);
1696                        mHandler.sendEmptyMessage(MCS_UNBIND);
1697                    }
1698
1699                    break;
1700                }
1701                case START_INTENT_FILTER_VERIFICATIONS: {
1702                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1703                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1704                            params.replacing, params.pkg);
1705                    break;
1706                }
1707                case INTENT_FILTER_VERIFIED: {
1708                    final int verificationId = msg.arg1;
1709
1710                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1711                            verificationId);
1712                    if (state == null) {
1713                        Slog.w(TAG, "Invalid IntentFilter verification token "
1714                                + verificationId + " received");
1715                        break;
1716                    }
1717
1718                    final int userId = state.getUserId();
1719
1720                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1721                            "Processing IntentFilter verification with token:"
1722                            + verificationId + " and userId:" + userId);
1723
1724                    final IntentFilterVerificationResponse response =
1725                            (IntentFilterVerificationResponse) msg.obj;
1726
1727                    state.setVerifierResponse(response.callerUid, response.code);
1728
1729                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1730                            "IntentFilter verification with token:" + verificationId
1731                            + " and userId:" + userId
1732                            + " is settings verifier response with response code:"
1733                            + response.code);
1734
1735                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1736                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1737                                + response.getFailedDomainsString());
1738                    }
1739
1740                    if (state.isVerificationComplete()) {
1741                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1742                    } else {
1743                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1744                                "IntentFilter verification with token:" + verificationId
1745                                + " was not said to be complete");
1746                    }
1747
1748                    break;
1749                }
1750                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1751                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1752                            mInstantAppResolverConnection,
1753                            (InstantAppRequest) msg.obj,
1754                            mInstantAppInstallerActivity,
1755                            mHandler);
1756                }
1757            }
1758        }
1759    }
1760
1761    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1762            boolean killApp, String[] grantedPermissions,
1763            boolean launchedForRestore, String installerPackage,
1764            IPackageInstallObserver2 installObserver) {
1765        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1766            // Send the removed broadcasts
1767            if (res.removedInfo != null) {
1768                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1769            }
1770
1771            // Now that we successfully installed the package, grant runtime
1772            // permissions if requested before broadcasting the install. Also
1773            // for legacy apps in permission review mode we clear the permission
1774            // review flag which is used to emulate runtime permissions for
1775            // legacy apps.
1776            if (grantPermissions) {
1777                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1778            }
1779
1780            final boolean update = res.removedInfo != null
1781                    && res.removedInfo.removedPackage != null;
1782            final String origInstallerPackageName = res.removedInfo != null
1783                    ? res.removedInfo.installerPackageName : null;
1784
1785            // If this is the first time we have child packages for a disabled privileged
1786            // app that had no children, we grant requested runtime permissions to the new
1787            // children if the parent on the system image had them already granted.
1788            if (res.pkg.parentPackage != null) {
1789                synchronized (mPackages) {
1790                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1791                }
1792            }
1793
1794            synchronized (mPackages) {
1795                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1796            }
1797
1798            final String packageName = res.pkg.applicationInfo.packageName;
1799
1800            // Determine the set of users who are adding this package for
1801            // the first time vs. those who are seeing an update.
1802            int[] firstUsers = EMPTY_INT_ARRAY;
1803            int[] updateUsers = EMPTY_INT_ARRAY;
1804            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1805            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1806            for (int newUser : res.newUsers) {
1807                if (ps.getInstantApp(newUser)) {
1808                    continue;
1809                }
1810                if (allNewUsers) {
1811                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1812                    continue;
1813                }
1814                boolean isNew = true;
1815                for (int origUser : res.origUsers) {
1816                    if (origUser == newUser) {
1817                        isNew = false;
1818                        break;
1819                    }
1820                }
1821                if (isNew) {
1822                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1823                } else {
1824                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1825                }
1826            }
1827
1828            // Send installed broadcasts if the package is not a static shared lib.
1829            if (res.pkg.staticSharedLibName == null) {
1830                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1831
1832                // Send added for users that see the package for the first time
1833                // sendPackageAddedForNewUsers also deals with system apps
1834                int appId = UserHandle.getAppId(res.uid);
1835                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1836                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1837
1838                // Send added for users that don't see the package for the first time
1839                Bundle extras = new Bundle(1);
1840                extras.putInt(Intent.EXTRA_UID, res.uid);
1841                if (update) {
1842                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1843                }
1844                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1845                        extras, 0 /*flags*/,
1846                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1847                if (origInstallerPackageName != null) {
1848                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1849                            extras, 0 /*flags*/,
1850                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1851                }
1852
1853                // Send replaced for users that don't see the package for the first time
1854                if (update) {
1855                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1856                            packageName, extras, 0 /*flags*/,
1857                            null /*targetPackage*/, null /*finishedReceiver*/,
1858                            updateUsers);
1859                    if (origInstallerPackageName != null) {
1860                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1861                                extras, 0 /*flags*/,
1862                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1863                    }
1864                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1865                            null /*package*/, null /*extras*/, 0 /*flags*/,
1866                            packageName /*targetPackage*/,
1867                            null /*finishedReceiver*/, updateUsers);
1868                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1869                    // First-install and we did a restore, so we're responsible for the
1870                    // first-launch broadcast.
1871                    if (DEBUG_BACKUP) {
1872                        Slog.i(TAG, "Post-restore of " + packageName
1873                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1874                    }
1875                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1876                }
1877
1878                // Send broadcast package appeared if forward locked/external for all users
1879                // treat asec-hosted packages like removable media on upgrade
1880                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1881                    if (DEBUG_INSTALL) {
1882                        Slog.i(TAG, "upgrading pkg " + res.pkg
1883                                + " is ASEC-hosted -> AVAILABLE");
1884                    }
1885                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
1886                    ArrayList<String> pkgList = new ArrayList<>(1);
1887                    pkgList.add(packageName);
1888                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
1889                }
1890            }
1891
1892            // Work that needs to happen on first install within each user
1893            if (firstUsers != null && firstUsers.length > 0) {
1894                synchronized (mPackages) {
1895                    for (int userId : firstUsers) {
1896                        // If this app is a browser and it's newly-installed for some
1897                        // users, clear any default-browser state in those users. The
1898                        // app's nature doesn't depend on the user, so we can just check
1899                        // its browser nature in any user and generalize.
1900                        if (packageIsBrowser(packageName, userId)) {
1901                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
1902                        }
1903
1904                        // We may also need to apply pending (restored) runtime
1905                        // permission grants within these users.
1906                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
1907                    }
1908                }
1909            }
1910
1911            // Log current value of "unknown sources" setting
1912            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
1913                    getUnknownSourcesSettings());
1914
1915            // Force a gc to clear up things
1916            Runtime.getRuntime().gc();
1917
1918            // Remove the replaced package's older resources safely now
1919            // We delete after a gc for applications  on sdcard.
1920            if (res.removedInfo != null && res.removedInfo.args != null) {
1921                synchronized (mInstallLock) {
1922                    res.removedInfo.args.doPostDeleteLI(true);
1923                }
1924            }
1925
1926            // Notify DexManager that the package was installed for new users.
1927            // The updated users should already be indexed and the package code paths
1928            // should not change.
1929            // Don't notify the manager for ephemeral apps as they are not expected to
1930            // survive long enough to benefit of background optimizations.
1931            for (int userId : firstUsers) {
1932                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
1933                // There's a race currently where some install events may interleave with an uninstall.
1934                // This can lead to package info being null (b/36642664).
1935                if (info != null) {
1936                    mDexManager.notifyPackageInstalled(info, userId);
1937                }
1938            }
1939        }
1940
1941        // If someone is watching installs - notify them
1942        if (installObserver != null) {
1943            try {
1944                Bundle extras = extrasForInstallResult(res);
1945                installObserver.onPackageInstalled(res.name, res.returnCode,
1946                        res.returnMsg, extras);
1947            } catch (RemoteException e) {
1948                Slog.i(TAG, "Observer no longer exists.");
1949            }
1950        }
1951    }
1952
1953    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
1954            PackageParser.Package pkg) {
1955        if (pkg.parentPackage == null) {
1956            return;
1957        }
1958        if (pkg.requestedPermissions == null) {
1959            return;
1960        }
1961        final PackageSetting disabledSysParentPs = mSettings
1962                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
1963        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
1964                || !disabledSysParentPs.isPrivileged()
1965                || (disabledSysParentPs.childPackageNames != null
1966                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
1967            return;
1968        }
1969        final int[] allUserIds = sUserManager.getUserIds();
1970        final int permCount = pkg.requestedPermissions.size();
1971        for (int i = 0; i < permCount; i++) {
1972            String permission = pkg.requestedPermissions.get(i);
1973            BasePermission bp = mSettings.mPermissions.get(permission);
1974            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1975                continue;
1976            }
1977            for (int userId : allUserIds) {
1978                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
1979                        permission, userId)) {
1980                    grantRuntimePermission(pkg.packageName, permission, userId);
1981                }
1982            }
1983        }
1984    }
1985
1986    private StorageEventListener mStorageListener = new StorageEventListener() {
1987        @Override
1988        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
1989            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
1990                if (vol.state == VolumeInfo.STATE_MOUNTED) {
1991                    final String volumeUuid = vol.getFsUuid();
1992
1993                    // Clean up any users or apps that were removed or recreated
1994                    // while this volume was missing
1995                    sUserManager.reconcileUsers(volumeUuid);
1996                    reconcileApps(volumeUuid);
1997
1998                    // Clean up any install sessions that expired or were
1999                    // cancelled while this volume was missing
2000                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2001
2002                    loadPrivatePackages(vol);
2003
2004                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2005                    unloadPrivatePackages(vol);
2006                }
2007            }
2008
2009            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2010                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2011                    updateExternalMediaStatus(true, false);
2012                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2013                    updateExternalMediaStatus(false, false);
2014                }
2015            }
2016        }
2017
2018        @Override
2019        public void onVolumeForgotten(String fsUuid) {
2020            if (TextUtils.isEmpty(fsUuid)) {
2021                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2022                return;
2023            }
2024
2025            // Remove any apps installed on the forgotten volume
2026            synchronized (mPackages) {
2027                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2028                for (PackageSetting ps : packages) {
2029                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2030                    deletePackageVersioned(new VersionedPackage(ps.name,
2031                            PackageManager.VERSION_CODE_HIGHEST),
2032                            new LegacyPackageDeleteObserver(null).getBinder(),
2033                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2034                    // Try very hard to release any references to this package
2035                    // so we don't risk the system server being killed due to
2036                    // open FDs
2037                    AttributeCache.instance().removePackage(ps.name);
2038                }
2039
2040                mSettings.onVolumeForgotten(fsUuid);
2041                mSettings.writeLPr();
2042            }
2043        }
2044    };
2045
2046    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2047            String[] grantedPermissions) {
2048        for (int userId : userIds) {
2049            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2050        }
2051    }
2052
2053    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2054            String[] grantedPermissions) {
2055        SettingBase sb = (SettingBase) pkg.mExtras;
2056        if (sb == null) {
2057            return;
2058        }
2059
2060        PermissionsState permissionsState = sb.getPermissionsState();
2061
2062        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2063                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2064
2065        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2066                >= Build.VERSION_CODES.M;
2067
2068        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2069
2070        for (String permission : pkg.requestedPermissions) {
2071            final BasePermission bp;
2072            synchronized (mPackages) {
2073                bp = mSettings.mPermissions.get(permission);
2074            }
2075            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2076                    && (!instantApp || bp.isInstant())
2077                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2078                    && (grantedPermissions == null
2079                           || ArrayUtils.contains(grantedPermissions, permission))) {
2080                final int flags = permissionsState.getPermissionFlags(permission, userId);
2081                if (supportsRuntimePermissions) {
2082                    // Installer cannot change immutable permissions.
2083                    if ((flags & immutableFlags) == 0) {
2084                        grantRuntimePermission(pkg.packageName, permission, userId);
2085                    }
2086                } else if (mPermissionReviewRequired) {
2087                    // In permission review mode we clear the review flag when we
2088                    // are asked to install the app with all permissions granted.
2089                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2090                        updatePermissionFlags(permission, pkg.packageName,
2091                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2092                    }
2093                }
2094            }
2095        }
2096    }
2097
2098    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2099        Bundle extras = null;
2100        switch (res.returnCode) {
2101            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2102                extras = new Bundle();
2103                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2104                        res.origPermission);
2105                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2106                        res.origPackage);
2107                break;
2108            }
2109            case PackageManager.INSTALL_SUCCEEDED: {
2110                extras = new Bundle();
2111                extras.putBoolean(Intent.EXTRA_REPLACING,
2112                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2113                break;
2114            }
2115        }
2116        return extras;
2117    }
2118
2119    void scheduleWriteSettingsLocked() {
2120        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2121            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2122        }
2123    }
2124
2125    void scheduleWritePackageListLocked(int userId) {
2126        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2127            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2128            msg.arg1 = userId;
2129            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2130        }
2131    }
2132
2133    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2134        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2135        scheduleWritePackageRestrictionsLocked(userId);
2136    }
2137
2138    void scheduleWritePackageRestrictionsLocked(int userId) {
2139        final int[] userIds = (userId == UserHandle.USER_ALL)
2140                ? sUserManager.getUserIds() : new int[]{userId};
2141        for (int nextUserId : userIds) {
2142            if (!sUserManager.exists(nextUserId)) return;
2143            mDirtyUsers.add(nextUserId);
2144            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2145                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2146            }
2147        }
2148    }
2149
2150    public static PackageManagerService main(Context context, Installer installer,
2151            boolean factoryTest, boolean onlyCore) {
2152        // Self-check for initial settings.
2153        PackageManagerServiceCompilerMapping.checkProperties();
2154
2155        PackageManagerService m = new PackageManagerService(context, installer,
2156                factoryTest, onlyCore);
2157        m.enableSystemUserPackages();
2158        ServiceManager.addService("package", m);
2159        return m;
2160    }
2161
2162    private void enableSystemUserPackages() {
2163        if (!UserManager.isSplitSystemUser()) {
2164            return;
2165        }
2166        // For system user, enable apps based on the following conditions:
2167        // - app is whitelisted or belong to one of these groups:
2168        //   -- system app which has no launcher icons
2169        //   -- system app which has INTERACT_ACROSS_USERS permission
2170        //   -- system IME app
2171        // - app is not in the blacklist
2172        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2173        Set<String> enableApps = new ArraySet<>();
2174        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2175                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2176                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2177        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2178        enableApps.addAll(wlApps);
2179        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2180                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2181        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2182        enableApps.removeAll(blApps);
2183        Log.i(TAG, "Applications installed for system user: " + enableApps);
2184        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2185                UserHandle.SYSTEM);
2186        final int allAppsSize = allAps.size();
2187        synchronized (mPackages) {
2188            for (int i = 0; i < allAppsSize; i++) {
2189                String pName = allAps.get(i);
2190                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2191                // Should not happen, but we shouldn't be failing if it does
2192                if (pkgSetting == null) {
2193                    continue;
2194                }
2195                boolean install = enableApps.contains(pName);
2196                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2197                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2198                            + " for system user");
2199                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2200                }
2201            }
2202            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2203        }
2204    }
2205
2206    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2207        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2208                Context.DISPLAY_SERVICE);
2209        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2210    }
2211
2212    /**
2213     * Requests that files preopted on a secondary system partition be copied to the data partition
2214     * if possible.  Note that the actual copying of the files is accomplished by init for security
2215     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2216     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2217     */
2218    private static void requestCopyPreoptedFiles() {
2219        final int WAIT_TIME_MS = 100;
2220        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2221        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2222            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2223            // We will wait for up to 100 seconds.
2224            final long timeStart = SystemClock.uptimeMillis();
2225            final long timeEnd = timeStart + 100 * 1000;
2226            long timeNow = timeStart;
2227            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2228                try {
2229                    Thread.sleep(WAIT_TIME_MS);
2230                } catch (InterruptedException e) {
2231                    // Do nothing
2232                }
2233                timeNow = SystemClock.uptimeMillis();
2234                if (timeNow > timeEnd) {
2235                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2236                    Slog.wtf(TAG, "cppreopt did not finish!");
2237                    break;
2238                }
2239            }
2240
2241            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2242        }
2243    }
2244
2245    public PackageManagerService(Context context, Installer installer,
2246            boolean factoryTest, boolean onlyCore) {
2247        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2248        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2249        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2250                SystemClock.uptimeMillis());
2251
2252        if (mSdkVersion <= 0) {
2253            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2254        }
2255
2256        mContext = context;
2257
2258        mPermissionReviewRequired = context.getResources().getBoolean(
2259                R.bool.config_permissionReviewRequired);
2260
2261        mFactoryTest = factoryTest;
2262        mOnlyCore = onlyCore;
2263        mMetrics = new DisplayMetrics();
2264        mSettings = new Settings(mPackages);
2265        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2266                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2267        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2268                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2269        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2270                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2271        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2272                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2273        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2274                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2275        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2276                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2277
2278        String separateProcesses = SystemProperties.get("debug.separate_processes");
2279        if (separateProcesses != null && separateProcesses.length() > 0) {
2280            if ("*".equals(separateProcesses)) {
2281                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2282                mSeparateProcesses = null;
2283                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2284            } else {
2285                mDefParseFlags = 0;
2286                mSeparateProcesses = separateProcesses.split(",");
2287                Slog.w(TAG, "Running with debug.separate_processes: "
2288                        + separateProcesses);
2289            }
2290        } else {
2291            mDefParseFlags = 0;
2292            mSeparateProcesses = null;
2293        }
2294
2295        mInstaller = installer;
2296        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2297                "*dexopt*");
2298        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2299        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2300
2301        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2302                FgThread.get().getLooper());
2303
2304        getDefaultDisplayMetrics(context, mMetrics);
2305
2306        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2307        SystemConfig systemConfig = SystemConfig.getInstance();
2308        mGlobalGids = systemConfig.getGlobalGids();
2309        mSystemPermissions = systemConfig.getSystemPermissions();
2310        mAvailableFeatures = systemConfig.getAvailableFeatures();
2311        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2312
2313        mProtectedPackages = new ProtectedPackages(mContext);
2314
2315        synchronized (mInstallLock) {
2316        // writer
2317        synchronized (mPackages) {
2318            mHandlerThread = new ServiceThread(TAG,
2319                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2320            mHandlerThread.start();
2321            mHandler = new PackageHandler(mHandlerThread.getLooper());
2322            mProcessLoggingHandler = new ProcessLoggingHandler();
2323            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2324
2325            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2326            mInstantAppRegistry = new InstantAppRegistry(this);
2327
2328            File dataDir = Environment.getDataDirectory();
2329            mAppInstallDir = new File(dataDir, "app");
2330            mAppLib32InstallDir = new File(dataDir, "app-lib");
2331            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2332            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2333            sUserManager = new UserManagerService(context, this,
2334                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2335
2336            // Propagate permission configuration in to package manager.
2337            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2338                    = systemConfig.getPermissions();
2339            for (int i=0; i<permConfig.size(); i++) {
2340                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2341                BasePermission bp = mSettings.mPermissions.get(perm.name);
2342                if (bp == null) {
2343                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2344                    mSettings.mPermissions.put(perm.name, bp);
2345                }
2346                if (perm.gids != null) {
2347                    bp.setGids(perm.gids, perm.perUser);
2348                }
2349            }
2350
2351            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2352            final int builtInLibCount = libConfig.size();
2353            for (int i = 0; i < builtInLibCount; i++) {
2354                String name = libConfig.keyAt(i);
2355                String path = libConfig.valueAt(i);
2356                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2357                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2358            }
2359
2360            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2361
2362            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2363            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2364            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2365
2366            // Clean up orphaned packages for which the code path doesn't exist
2367            // and they are an update to a system app - caused by bug/32321269
2368            final int packageSettingCount = mSettings.mPackages.size();
2369            for (int i = packageSettingCount - 1; i >= 0; i--) {
2370                PackageSetting ps = mSettings.mPackages.valueAt(i);
2371                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2372                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2373                    mSettings.mPackages.removeAt(i);
2374                    mSettings.enableSystemPackageLPw(ps.name);
2375                }
2376            }
2377
2378            if (mFirstBoot) {
2379                requestCopyPreoptedFiles();
2380            }
2381
2382            String customResolverActivity = Resources.getSystem().getString(
2383                    R.string.config_customResolverActivity);
2384            if (TextUtils.isEmpty(customResolverActivity)) {
2385                customResolverActivity = null;
2386            } else {
2387                mCustomResolverComponentName = ComponentName.unflattenFromString(
2388                        customResolverActivity);
2389            }
2390
2391            long startTime = SystemClock.uptimeMillis();
2392
2393            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2394                    startTime);
2395
2396            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2397            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2398
2399            if (bootClassPath == null) {
2400                Slog.w(TAG, "No BOOTCLASSPATH found!");
2401            }
2402
2403            if (systemServerClassPath == null) {
2404                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2405            }
2406
2407            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2408
2409            final VersionInfo ver = mSettings.getInternalVersion();
2410            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2411            if (mIsUpgrade) {
2412                logCriticalInfo(Log.INFO,
2413                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2414            }
2415
2416            // when upgrading from pre-M, promote system app permissions from install to runtime
2417            mPromoteSystemApps =
2418                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2419
2420            // When upgrading from pre-N, we need to handle package extraction like first boot,
2421            // as there is no profiling data available.
2422            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2423
2424            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2425
2426            // save off the names of pre-existing system packages prior to scanning; we don't
2427            // want to automatically grant runtime permissions for new system apps
2428            if (mPromoteSystemApps) {
2429                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2430                while (pkgSettingIter.hasNext()) {
2431                    PackageSetting ps = pkgSettingIter.next();
2432                    if (isSystemApp(ps)) {
2433                        mExistingSystemPackages.add(ps.name);
2434                    }
2435                }
2436            }
2437
2438            mCacheDir = preparePackageParserCache(mIsUpgrade);
2439
2440            // Set flag to monitor and not change apk file paths when
2441            // scanning install directories.
2442            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2443
2444            if (mIsUpgrade || mFirstBoot) {
2445                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2446            }
2447
2448            // Collect vendor overlay packages. (Do this before scanning any apps.)
2449            // For security and version matching reason, only consider
2450            // overlay packages if they reside in the right directory.
2451            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2452                    | PackageParser.PARSE_IS_SYSTEM
2453                    | PackageParser.PARSE_IS_SYSTEM_DIR
2454                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2455
2456            // Find base frameworks (resource packages without code).
2457            scanDirTracedLI(frameworkDir, mDefParseFlags
2458                    | PackageParser.PARSE_IS_SYSTEM
2459                    | PackageParser.PARSE_IS_SYSTEM_DIR
2460                    | PackageParser.PARSE_IS_PRIVILEGED,
2461                    scanFlags | SCAN_NO_DEX, 0);
2462
2463            // Collected privileged system packages.
2464            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2465            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2466                    | PackageParser.PARSE_IS_SYSTEM
2467                    | PackageParser.PARSE_IS_SYSTEM_DIR
2468                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2469
2470            // Collect ordinary system packages.
2471            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2472            scanDirTracedLI(systemAppDir, mDefParseFlags
2473                    | PackageParser.PARSE_IS_SYSTEM
2474                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2475
2476            // Collect all vendor packages.
2477            File vendorAppDir = new File("/vendor/app");
2478            try {
2479                vendorAppDir = vendorAppDir.getCanonicalFile();
2480            } catch (IOException e) {
2481                // failed to look up canonical path, continue with original one
2482            }
2483            scanDirTracedLI(vendorAppDir, mDefParseFlags
2484                    | PackageParser.PARSE_IS_SYSTEM
2485                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2486
2487            // Collect all OEM packages.
2488            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2489            scanDirTracedLI(oemAppDir, mDefParseFlags
2490                    | PackageParser.PARSE_IS_SYSTEM
2491                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2492
2493            // Prune any system packages that no longer exist.
2494            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2495            if (!mOnlyCore) {
2496                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2497                while (psit.hasNext()) {
2498                    PackageSetting ps = psit.next();
2499
2500                    /*
2501                     * If this is not a system app, it can't be a
2502                     * disable system app.
2503                     */
2504                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2505                        continue;
2506                    }
2507
2508                    /*
2509                     * If the package is scanned, it's not erased.
2510                     */
2511                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2512                    if (scannedPkg != null) {
2513                        /*
2514                         * If the system app is both scanned and in the
2515                         * disabled packages list, then it must have been
2516                         * added via OTA. Remove it from the currently
2517                         * scanned package so the previously user-installed
2518                         * application can be scanned.
2519                         */
2520                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2521                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2522                                    + ps.name + "; removing system app.  Last known codePath="
2523                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2524                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2525                                    + scannedPkg.mVersionCode);
2526                            removePackageLI(scannedPkg, true);
2527                            mExpectingBetter.put(ps.name, ps.codePath);
2528                        }
2529
2530                        continue;
2531                    }
2532
2533                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2534                        psit.remove();
2535                        logCriticalInfo(Log.WARN, "System package " + ps.name
2536                                + " no longer exists; it's data will be wiped");
2537                        // Actual deletion of code and data will be handled by later
2538                        // reconciliation step
2539                    } else {
2540                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2541                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2542                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2543                        }
2544                    }
2545                }
2546            }
2547
2548            //look for any incomplete package installations
2549            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2550            for (int i = 0; i < deletePkgsList.size(); i++) {
2551                // Actual deletion of code and data will be handled by later
2552                // reconciliation step
2553                final String packageName = deletePkgsList.get(i).name;
2554                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2555                synchronized (mPackages) {
2556                    mSettings.removePackageLPw(packageName);
2557                }
2558            }
2559
2560            //delete tmp files
2561            deleteTempPackageFiles();
2562
2563            // Remove any shared userIDs that have no associated packages
2564            mSettings.pruneSharedUsersLPw();
2565
2566            if (!mOnlyCore) {
2567                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2568                        SystemClock.uptimeMillis());
2569                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2570
2571                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2572                        | PackageParser.PARSE_FORWARD_LOCK,
2573                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2574
2575                /**
2576                 * Remove disable package settings for any updated system
2577                 * apps that were removed via an OTA. If they're not a
2578                 * previously-updated app, remove them completely.
2579                 * Otherwise, just revoke their system-level permissions.
2580                 */
2581                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2582                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2583                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2584
2585                    String msg;
2586                    if (deletedPkg == null) {
2587                        msg = "Updated system package " + deletedAppName
2588                                + " no longer exists; it's data will be wiped";
2589                        // Actual deletion of code and data will be handled by later
2590                        // reconciliation step
2591                    } else {
2592                        msg = "Updated system app + " + deletedAppName
2593                                + " no longer present; removing system privileges for "
2594                                + deletedAppName;
2595
2596                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2597
2598                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2599                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2600                    }
2601                    logCriticalInfo(Log.WARN, msg);
2602                }
2603
2604                /**
2605                 * Make sure all system apps that we expected to appear on
2606                 * the userdata partition actually showed up. If they never
2607                 * appeared, crawl back and revive the system version.
2608                 */
2609                for (int i = 0; i < mExpectingBetter.size(); i++) {
2610                    final String packageName = mExpectingBetter.keyAt(i);
2611                    if (!mPackages.containsKey(packageName)) {
2612                        final File scanFile = mExpectingBetter.valueAt(i);
2613
2614                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2615                                + " but never showed up; reverting to system");
2616
2617                        int reparseFlags = mDefParseFlags;
2618                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2619                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2620                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2621                                    | PackageParser.PARSE_IS_PRIVILEGED;
2622                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2623                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2624                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2625                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2626                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2627                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2628                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2629                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2630                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2631                        } else {
2632                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2633                            continue;
2634                        }
2635
2636                        mSettings.enableSystemPackageLPw(packageName);
2637
2638                        try {
2639                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2640                        } catch (PackageManagerException e) {
2641                            Slog.e(TAG, "Failed to parse original system package: "
2642                                    + e.getMessage());
2643                        }
2644                    }
2645                }
2646            }
2647            mExpectingBetter.clear();
2648
2649            // Resolve the storage manager.
2650            mStorageManagerPackage = getStorageManagerPackageName();
2651
2652            // Resolve protected action filters. Only the setup wizard is allowed to
2653            // have a high priority filter for these actions.
2654            mSetupWizardPackage = getSetupWizardPackageName();
2655            if (mProtectedFilters.size() > 0) {
2656                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2657                    Slog.i(TAG, "No setup wizard;"
2658                        + " All protected intents capped to priority 0");
2659                }
2660                for (ActivityIntentInfo filter : mProtectedFilters) {
2661                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2662                        if (DEBUG_FILTERS) {
2663                            Slog.i(TAG, "Found setup wizard;"
2664                                + " allow priority " + filter.getPriority() + ";"
2665                                + " package: " + filter.activity.info.packageName
2666                                + " activity: " + filter.activity.className
2667                                + " priority: " + filter.getPriority());
2668                        }
2669                        // skip setup wizard; allow it to keep the high priority filter
2670                        continue;
2671                    }
2672                    Slog.w(TAG, "Protected action; cap priority to 0;"
2673                            + " package: " + filter.activity.info.packageName
2674                            + " activity: " + filter.activity.className
2675                            + " origPrio: " + filter.getPriority());
2676                    filter.setPriority(0);
2677                }
2678            }
2679            mDeferProtectedFilters = false;
2680            mProtectedFilters.clear();
2681
2682            // Now that we know all of the shared libraries, update all clients to have
2683            // the correct library paths.
2684            updateAllSharedLibrariesLPw(null);
2685
2686            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2687                // NOTE: We ignore potential failures here during a system scan (like
2688                // the rest of the commands above) because there's precious little we
2689                // can do about it. A settings error is reported, though.
2690                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2691            }
2692
2693            // Now that we know all the packages we are keeping,
2694            // read and update their last usage times.
2695            mPackageUsage.read(mPackages);
2696            mCompilerStats.read();
2697
2698            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2699                    SystemClock.uptimeMillis());
2700            Slog.i(TAG, "Time to scan packages: "
2701                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2702                    + " seconds");
2703
2704            // If the platform SDK has changed since the last time we booted,
2705            // we need to re-grant app permission to catch any new ones that
2706            // appear.  This is really a hack, and means that apps can in some
2707            // cases get permissions that the user didn't initially explicitly
2708            // allow...  it would be nice to have some better way to handle
2709            // this situation.
2710            int updateFlags = UPDATE_PERMISSIONS_ALL;
2711            if (ver.sdkVersion != mSdkVersion) {
2712                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2713                        + mSdkVersion + "; regranting permissions for internal storage");
2714                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2715            }
2716            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2717            ver.sdkVersion = mSdkVersion;
2718
2719            // If this is the first boot or an update from pre-M, and it is a normal
2720            // boot, then we need to initialize the default preferred apps across
2721            // all defined users.
2722            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2723                for (UserInfo user : sUserManager.getUsers(true)) {
2724                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2725                    applyFactoryDefaultBrowserLPw(user.id);
2726                    primeDomainVerificationsLPw(user.id);
2727                }
2728            }
2729
2730            // Prepare storage for system user really early during boot,
2731            // since core system apps like SettingsProvider and SystemUI
2732            // can't wait for user to start
2733            final int storageFlags;
2734            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2735                storageFlags = StorageManager.FLAG_STORAGE_DE;
2736            } else {
2737                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2738            }
2739            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2740                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2741                    true /* onlyCoreApps */);
2742            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2743                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2744                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2745                traceLog.traceBegin("AppDataFixup");
2746                try {
2747                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2748                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2749                } catch (InstallerException e) {
2750                    Slog.w(TAG, "Trouble fixing GIDs", e);
2751                }
2752                traceLog.traceEnd();
2753
2754                traceLog.traceBegin("AppDataPrepare");
2755                if (deferPackages == null || deferPackages.isEmpty()) {
2756                    return;
2757                }
2758                int count = 0;
2759                for (String pkgName : deferPackages) {
2760                    PackageParser.Package pkg = null;
2761                    synchronized (mPackages) {
2762                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2763                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2764                            pkg = ps.pkg;
2765                        }
2766                    }
2767                    if (pkg != null) {
2768                        synchronized (mInstallLock) {
2769                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2770                                    true /* maybeMigrateAppData */);
2771                        }
2772                        count++;
2773                    }
2774                }
2775                traceLog.traceEnd();
2776                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2777            }, "prepareAppData");
2778
2779            // If this is first boot after an OTA, and a normal boot, then
2780            // we need to clear code cache directories.
2781            // Note that we do *not* clear the application profiles. These remain valid
2782            // across OTAs and are used to drive profile verification (post OTA) and
2783            // profile compilation (without waiting to collect a fresh set of profiles).
2784            if (mIsUpgrade && !onlyCore) {
2785                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2786                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2787                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2788                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2789                        // No apps are running this early, so no need to freeze
2790                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2791                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2792                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2793                    }
2794                }
2795                ver.fingerprint = Build.FINGERPRINT;
2796            }
2797
2798            checkDefaultBrowser();
2799
2800            // clear only after permissions and other defaults have been updated
2801            mExistingSystemPackages.clear();
2802            mPromoteSystemApps = false;
2803
2804            // All the changes are done during package scanning.
2805            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2806
2807            // can downgrade to reader
2808            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2809            mSettings.writeLPr();
2810            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2811
2812            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2813                    SystemClock.uptimeMillis());
2814
2815            if (!mOnlyCore) {
2816                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2817                mRequiredInstallerPackage = getRequiredInstallerLPr();
2818                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2819                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2820                if (mIntentFilterVerifierComponent != null) {
2821                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2822                            mIntentFilterVerifierComponent);
2823                } else {
2824                    mIntentFilterVerifier = null;
2825                }
2826                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2827                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2828                        SharedLibraryInfo.VERSION_UNDEFINED);
2829                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2830                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2831                        SharedLibraryInfo.VERSION_UNDEFINED);
2832            } else {
2833                mRequiredVerifierPackage = null;
2834                mRequiredInstallerPackage = null;
2835                mRequiredUninstallerPackage = null;
2836                mIntentFilterVerifierComponent = null;
2837                mIntentFilterVerifier = null;
2838                mServicesSystemSharedLibraryPackageName = null;
2839                mSharedSystemSharedLibraryPackageName = null;
2840            }
2841
2842            mInstallerService = new PackageInstallerService(context, this);
2843            final Pair<ComponentName, String> instantAppResolverComponent =
2844                    getInstantAppResolverLPr();
2845            if (instantAppResolverComponent != null) {
2846                if (DEBUG_EPHEMERAL) {
2847                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2848                }
2849                mInstantAppResolverConnection = new EphemeralResolverConnection(
2850                        mContext, instantAppResolverComponent.first,
2851                        instantAppResolverComponent.second);
2852                mInstantAppResolverSettingsComponent =
2853                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2854            } else {
2855                mInstantAppResolverConnection = null;
2856                mInstantAppResolverSettingsComponent = null;
2857            }
2858            updateInstantAppInstallerLocked(null);
2859
2860            // Read and update the usage of dex files.
2861            // Do this at the end of PM init so that all the packages have their
2862            // data directory reconciled.
2863            // At this point we know the code paths of the packages, so we can validate
2864            // the disk file and build the internal cache.
2865            // The usage file is expected to be small so loading and verifying it
2866            // should take a fairly small time compare to the other activities (e.g. package
2867            // scanning).
2868            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2869            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2870            for (int userId : currentUserIds) {
2871                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2872            }
2873            mDexManager.load(userPackages);
2874        } // synchronized (mPackages)
2875        } // synchronized (mInstallLock)
2876
2877        // Now after opening every single application zip, make sure they
2878        // are all flushed.  Not really needed, but keeps things nice and
2879        // tidy.
2880        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2881        Runtime.getRuntime().gc();
2882        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2883
2884        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2885        FallbackCategoryProvider.loadFallbacks();
2886        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2887
2888        // The initial scanning above does many calls into installd while
2889        // holding the mPackages lock, but we're mostly interested in yelling
2890        // once we have a booted system.
2891        mInstaller.setWarnIfHeld(mPackages);
2892
2893        // Expose private service for system components to use.
2894        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
2895        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2896    }
2897
2898    private void updateInstantAppInstallerLocked(String modifiedPackage) {
2899        // we're only interested in updating the installer appliction when 1) it's not
2900        // already set or 2) the modified package is the installer
2901        if (mInstantAppInstallerActivity != null
2902                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
2903                        .equals(modifiedPackage)) {
2904            return;
2905        }
2906        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
2907    }
2908
2909    private static File preparePackageParserCache(boolean isUpgrade) {
2910        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
2911            return null;
2912        }
2913
2914        // Disable package parsing on eng builds to allow for faster incremental development.
2915        if ("eng".equals(Build.TYPE)) {
2916            return null;
2917        }
2918
2919        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
2920            Slog.i(TAG, "Disabling package parser cache due to system property.");
2921            return null;
2922        }
2923
2924        // The base directory for the package parser cache lives under /data/system/.
2925        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
2926                "package_cache");
2927        if (cacheBaseDir == null) {
2928            return null;
2929        }
2930
2931        // If this is a system upgrade scenario, delete the contents of the package cache dir.
2932        // This also serves to "GC" unused entries when the package cache version changes (which
2933        // can only happen during upgrades).
2934        if (isUpgrade) {
2935            FileUtils.deleteContents(cacheBaseDir);
2936        }
2937
2938
2939        // Return the versioned package cache directory. This is something like
2940        // "/data/system/package_cache/1"
2941        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2942
2943        // The following is a workaround to aid development on non-numbered userdebug
2944        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
2945        // the system partition is newer.
2946        //
2947        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
2948        // that starts with "eng." to signify that this is an engineering build and not
2949        // destined for release.
2950        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
2951            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
2952
2953            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
2954            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
2955            // in general and should not be used for production changes. In this specific case,
2956            // we know that they will work.
2957            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2958            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
2959                FileUtils.deleteContents(cacheBaseDir);
2960                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
2961            }
2962        }
2963
2964        return cacheDir;
2965    }
2966
2967    @Override
2968    public boolean isFirstBoot() {
2969        return mFirstBoot;
2970    }
2971
2972    @Override
2973    public boolean isOnlyCoreApps() {
2974        return mOnlyCore;
2975    }
2976
2977    @Override
2978    public boolean isUpgrade() {
2979        return mIsUpgrade;
2980    }
2981
2982    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
2983        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
2984
2985        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
2986                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
2987                UserHandle.USER_SYSTEM);
2988        if (matches.size() == 1) {
2989            return matches.get(0).getComponentInfo().packageName;
2990        } else if (matches.size() == 0) {
2991            Log.e(TAG, "There should probably be a verifier, but, none were found");
2992            return null;
2993        }
2994        throw new RuntimeException("There must be exactly one verifier; found " + matches);
2995    }
2996
2997    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
2998        synchronized (mPackages) {
2999            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3000            if (libraryEntry == null) {
3001                throw new IllegalStateException("Missing required shared library:" + name);
3002            }
3003            return libraryEntry.apk;
3004        }
3005    }
3006
3007    private @NonNull String getRequiredInstallerLPr() {
3008        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3009        intent.addCategory(Intent.CATEGORY_DEFAULT);
3010        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3011
3012        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3013                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3014                UserHandle.USER_SYSTEM);
3015        if (matches.size() == 1) {
3016            ResolveInfo resolveInfo = matches.get(0);
3017            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3018                throw new RuntimeException("The installer must be a privileged app");
3019            }
3020            return matches.get(0).getComponentInfo().packageName;
3021        } else {
3022            throw new RuntimeException("There must be exactly one installer; found " + matches);
3023        }
3024    }
3025
3026    private @NonNull String getRequiredUninstallerLPr() {
3027        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3028        intent.addCategory(Intent.CATEGORY_DEFAULT);
3029        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3030
3031        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3032                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3033                UserHandle.USER_SYSTEM);
3034        if (resolveInfo == null ||
3035                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3036            throw new RuntimeException("There must be exactly one uninstaller; found "
3037                    + resolveInfo);
3038        }
3039        return resolveInfo.getComponentInfo().packageName;
3040    }
3041
3042    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3043        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3044
3045        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3046                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3047                UserHandle.USER_SYSTEM);
3048        ResolveInfo best = null;
3049        final int N = matches.size();
3050        for (int i = 0; i < N; i++) {
3051            final ResolveInfo cur = matches.get(i);
3052            final String packageName = cur.getComponentInfo().packageName;
3053            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3054                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3055                continue;
3056            }
3057
3058            if (best == null || cur.priority > best.priority) {
3059                best = cur;
3060            }
3061        }
3062
3063        if (best != null) {
3064            return best.getComponentInfo().getComponentName();
3065        }
3066        Slog.w(TAG, "Intent filter verifier not found");
3067        return null;
3068    }
3069
3070    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3071        final String[] packageArray =
3072                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3073        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3074            if (DEBUG_EPHEMERAL) {
3075                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3076            }
3077            return null;
3078        }
3079
3080        final int callingUid = Binder.getCallingUid();
3081        final int resolveFlags =
3082                MATCH_DIRECT_BOOT_AWARE
3083                | MATCH_DIRECT_BOOT_UNAWARE
3084                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3085        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3086        final Intent resolverIntent = new Intent(actionName);
3087        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3088                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3089        // temporarily look for the old action
3090        if (resolvers.size() == 0) {
3091            if (DEBUG_EPHEMERAL) {
3092                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3093            }
3094            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3095            resolverIntent.setAction(actionName);
3096            resolvers = queryIntentServicesInternal(resolverIntent, null,
3097                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3098        }
3099        final int N = resolvers.size();
3100        if (N == 0) {
3101            if (DEBUG_EPHEMERAL) {
3102                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3103            }
3104            return null;
3105        }
3106
3107        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3108        for (int i = 0; i < N; i++) {
3109            final ResolveInfo info = resolvers.get(i);
3110
3111            if (info.serviceInfo == null) {
3112                continue;
3113            }
3114
3115            final String packageName = info.serviceInfo.packageName;
3116            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3117                if (DEBUG_EPHEMERAL) {
3118                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3119                            + " pkg: " + packageName + ", info:" + info);
3120                }
3121                continue;
3122            }
3123
3124            if (DEBUG_EPHEMERAL) {
3125                Slog.v(TAG, "Ephemeral resolver found;"
3126                        + " pkg: " + packageName + ", info:" + info);
3127            }
3128            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3129        }
3130        if (DEBUG_EPHEMERAL) {
3131            Slog.v(TAG, "Ephemeral resolver NOT found");
3132        }
3133        return null;
3134    }
3135
3136    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3137        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3138        intent.addCategory(Intent.CATEGORY_DEFAULT);
3139        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3140
3141        final int resolveFlags =
3142                MATCH_DIRECT_BOOT_AWARE
3143                | MATCH_DIRECT_BOOT_UNAWARE
3144                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3145        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3146                resolveFlags, UserHandle.USER_SYSTEM);
3147        // temporarily look for the old action
3148        if (matches.isEmpty()) {
3149            if (DEBUG_EPHEMERAL) {
3150                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3151            }
3152            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3153            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3154                    resolveFlags, UserHandle.USER_SYSTEM);
3155        }
3156        Iterator<ResolveInfo> iter = matches.iterator();
3157        while (iter.hasNext()) {
3158            final ResolveInfo rInfo = iter.next();
3159            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3160            if (ps != null) {
3161                final PermissionsState permissionsState = ps.getPermissionsState();
3162                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3163                    continue;
3164                }
3165            }
3166            iter.remove();
3167        }
3168        if (matches.size() == 0) {
3169            return null;
3170        } else if (matches.size() == 1) {
3171            return (ActivityInfo) matches.get(0).getComponentInfo();
3172        } else {
3173            throw new RuntimeException(
3174                    "There must be at most one ephemeral installer; found " + matches);
3175        }
3176    }
3177
3178    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3179            @NonNull ComponentName resolver) {
3180        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3181                .addCategory(Intent.CATEGORY_DEFAULT)
3182                .setPackage(resolver.getPackageName());
3183        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3184        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3185                UserHandle.USER_SYSTEM);
3186        // temporarily look for the old action
3187        if (matches.isEmpty()) {
3188            if (DEBUG_EPHEMERAL) {
3189                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3190            }
3191            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3192            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3193                    UserHandle.USER_SYSTEM);
3194        }
3195        if (matches.isEmpty()) {
3196            return null;
3197        }
3198        return matches.get(0).getComponentInfo().getComponentName();
3199    }
3200
3201    private void primeDomainVerificationsLPw(int userId) {
3202        if (DEBUG_DOMAIN_VERIFICATION) {
3203            Slog.d(TAG, "Priming domain verifications in user " + userId);
3204        }
3205
3206        SystemConfig systemConfig = SystemConfig.getInstance();
3207        ArraySet<String> packages = systemConfig.getLinkedApps();
3208
3209        for (String packageName : packages) {
3210            PackageParser.Package pkg = mPackages.get(packageName);
3211            if (pkg != null) {
3212                if (!pkg.isSystemApp()) {
3213                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3214                    continue;
3215                }
3216
3217                ArraySet<String> domains = null;
3218                for (PackageParser.Activity a : pkg.activities) {
3219                    for (ActivityIntentInfo filter : a.intents) {
3220                        if (hasValidDomains(filter)) {
3221                            if (domains == null) {
3222                                domains = new ArraySet<String>();
3223                            }
3224                            domains.addAll(filter.getHostsList());
3225                        }
3226                    }
3227                }
3228
3229                if (domains != null && domains.size() > 0) {
3230                    if (DEBUG_DOMAIN_VERIFICATION) {
3231                        Slog.v(TAG, "      + " + packageName);
3232                    }
3233                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3234                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3235                    // and then 'always' in the per-user state actually used for intent resolution.
3236                    final IntentFilterVerificationInfo ivi;
3237                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3238                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3239                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3240                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3241                } else {
3242                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3243                            + "' does not handle web links");
3244                }
3245            } else {
3246                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3247            }
3248        }
3249
3250        scheduleWritePackageRestrictionsLocked(userId);
3251        scheduleWriteSettingsLocked();
3252    }
3253
3254    private void applyFactoryDefaultBrowserLPw(int userId) {
3255        // The default browser app's package name is stored in a string resource,
3256        // with a product-specific overlay used for vendor customization.
3257        String browserPkg = mContext.getResources().getString(
3258                com.android.internal.R.string.default_browser);
3259        if (!TextUtils.isEmpty(browserPkg)) {
3260            // non-empty string => required to be a known package
3261            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3262            if (ps == null) {
3263                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3264                browserPkg = null;
3265            } else {
3266                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3267            }
3268        }
3269
3270        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3271        // default.  If there's more than one, just leave everything alone.
3272        if (browserPkg == null) {
3273            calculateDefaultBrowserLPw(userId);
3274        }
3275    }
3276
3277    private void calculateDefaultBrowserLPw(int userId) {
3278        List<String> allBrowsers = resolveAllBrowserApps(userId);
3279        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3280        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3281    }
3282
3283    private List<String> resolveAllBrowserApps(int userId) {
3284        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3285        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3286                PackageManager.MATCH_ALL, userId);
3287
3288        final int count = list.size();
3289        List<String> result = new ArrayList<String>(count);
3290        for (int i=0; i<count; i++) {
3291            ResolveInfo info = list.get(i);
3292            if (info.activityInfo == null
3293                    || !info.handleAllWebDataURI
3294                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3295                    || result.contains(info.activityInfo.packageName)) {
3296                continue;
3297            }
3298            result.add(info.activityInfo.packageName);
3299        }
3300
3301        return result;
3302    }
3303
3304    private boolean packageIsBrowser(String packageName, int userId) {
3305        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3306                PackageManager.MATCH_ALL, userId);
3307        final int N = list.size();
3308        for (int i = 0; i < N; i++) {
3309            ResolveInfo info = list.get(i);
3310            if (packageName.equals(info.activityInfo.packageName)) {
3311                return true;
3312            }
3313        }
3314        return false;
3315    }
3316
3317    private void checkDefaultBrowser() {
3318        final int myUserId = UserHandle.myUserId();
3319        final String packageName = getDefaultBrowserPackageName(myUserId);
3320        if (packageName != null) {
3321            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3322            if (info == null) {
3323                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3324                synchronized (mPackages) {
3325                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3326                }
3327            }
3328        }
3329    }
3330
3331    @Override
3332    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3333            throws RemoteException {
3334        try {
3335            return super.onTransact(code, data, reply, flags);
3336        } catch (RuntimeException e) {
3337            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3338                Slog.wtf(TAG, "Package Manager Crash", e);
3339            }
3340            throw e;
3341        }
3342    }
3343
3344    static int[] appendInts(int[] cur, int[] add) {
3345        if (add == null) return cur;
3346        if (cur == null) return add;
3347        final int N = add.length;
3348        for (int i=0; i<N; i++) {
3349            cur = appendInt(cur, add[i]);
3350        }
3351        return cur;
3352    }
3353
3354    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3355        if (!sUserManager.exists(userId)) return null;
3356        if (ps == null) {
3357            return null;
3358        }
3359        final PackageParser.Package p = ps.pkg;
3360        if (p == null) {
3361            return null;
3362        }
3363        // Filter out ephemeral app metadata:
3364        //   * The system/shell/root can see metadata for any app
3365        //   * An installed app can see metadata for 1) other installed apps
3366        //     and 2) ephemeral apps that have explicitly interacted with it
3367        //   * Ephemeral apps can only see their own data and exposed installed apps
3368        //   * Holding a signature permission allows seeing instant apps
3369        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
3370        if (callingAppId != Process.SYSTEM_UID
3371                && callingAppId != Process.SHELL_UID
3372                && callingAppId != Process.ROOT_UID
3373                && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
3374                        Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
3375            final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
3376            if (instantAppPackageName != null) {
3377                // ephemeral apps can only get information on themselves or
3378                // installed apps that are exposed.
3379                if (!instantAppPackageName.equals(p.packageName)
3380                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3381                    return null;
3382                }
3383            } else {
3384                if (ps.getInstantApp(userId)) {
3385                    // only get access to the ephemeral app if we've been granted access
3386                    if (!mInstantAppRegistry.isInstantAccessGranted(
3387                            userId, callingAppId, ps.appId)) {
3388                        return null;
3389                    }
3390                }
3391            }
3392        }
3393
3394        final PermissionsState permissionsState = ps.getPermissionsState();
3395
3396        // Compute GIDs only if requested
3397        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3398                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3399        // Compute granted permissions only if package has requested permissions
3400        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3401                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3402        final PackageUserState state = ps.readUserState(userId);
3403
3404        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3405                && ps.isSystem()) {
3406            flags |= MATCH_ANY_USER;
3407        }
3408
3409        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3410                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3411
3412        if (packageInfo == null) {
3413            return null;
3414        }
3415
3416        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3417
3418        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3419                resolveExternalPackageNameLPr(p);
3420
3421        return packageInfo;
3422    }
3423
3424    @Override
3425    public void checkPackageStartable(String packageName, int userId) {
3426        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3427
3428        synchronized (mPackages) {
3429            final PackageSetting ps = mSettings.mPackages.get(packageName);
3430            if (ps == null) {
3431                throw new SecurityException("Package " + packageName + " was not found!");
3432            }
3433
3434            if (!ps.getInstalled(userId)) {
3435                throw new SecurityException(
3436                        "Package " + packageName + " was not installed for user " + userId + "!");
3437            }
3438
3439            if (mSafeMode && !ps.isSystem()) {
3440                throw new SecurityException("Package " + packageName + " not a system app!");
3441            }
3442
3443            if (mFrozenPackages.contains(packageName)) {
3444                throw new SecurityException("Package " + packageName + " is currently frozen!");
3445            }
3446
3447            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3448                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3449                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3450            }
3451        }
3452    }
3453
3454    @Override
3455    public boolean isPackageAvailable(String packageName, int userId) {
3456        if (!sUserManager.exists(userId)) return false;
3457        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3458                false /* requireFullPermission */, false /* checkShell */, "is package available");
3459        synchronized (mPackages) {
3460            PackageParser.Package p = mPackages.get(packageName);
3461            if (p != null) {
3462                final PackageSetting ps = (PackageSetting) p.mExtras;
3463                if (ps != null) {
3464                    final PackageUserState state = ps.readUserState(userId);
3465                    if (state != null) {
3466                        return PackageParser.isAvailable(state);
3467                    }
3468                }
3469            }
3470        }
3471        return false;
3472    }
3473
3474    @Override
3475    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3476        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3477                flags, userId);
3478    }
3479
3480    @Override
3481    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3482            int flags, int userId) {
3483        return getPackageInfoInternal(versionedPackage.getPackageName(),
3484                // TODO: We will change version code to long, so in the new API it is long
3485                (int) versionedPackage.getVersionCode(), flags, userId);
3486    }
3487
3488    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3489            int flags, int userId) {
3490        if (!sUserManager.exists(userId)) return null;
3491        flags = updateFlagsForPackage(flags, userId, packageName);
3492        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3493                false /* requireFullPermission */, false /* checkShell */, "get package info");
3494
3495        // reader
3496        synchronized (mPackages) {
3497            // Normalize package name to handle renamed packages and static libs
3498            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3499
3500            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3501            if (matchFactoryOnly) {
3502                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3503                if (ps != null) {
3504                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3505                        return null;
3506                    }
3507                    return generatePackageInfo(ps, flags, userId);
3508                }
3509            }
3510
3511            PackageParser.Package p = mPackages.get(packageName);
3512            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3513                return null;
3514            }
3515            if (DEBUG_PACKAGE_INFO)
3516                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3517            if (p != null) {
3518                if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
3519                        Binder.getCallingUid(), userId)) {
3520                    return null;
3521                }
3522                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3523            }
3524            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3525                final PackageSetting ps = mSettings.mPackages.get(packageName);
3526                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3527                    return null;
3528                }
3529                return generatePackageInfo(ps, flags, userId);
3530            }
3531        }
3532        return null;
3533    }
3534
3535
3536    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId) {
3537        // System/shell/root get to see all static libs
3538        final int appId = UserHandle.getAppId(uid);
3539        if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3540                || appId == Process.ROOT_UID) {
3541            return false;
3542        }
3543
3544        // No package means no static lib as it is always on internal storage
3545        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3546            return false;
3547        }
3548
3549        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3550                ps.pkg.staticSharedLibVersion);
3551        if (libEntry == null) {
3552            return false;
3553        }
3554
3555        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3556        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3557        if (uidPackageNames == null) {
3558            return true;
3559        }
3560
3561        for (String uidPackageName : uidPackageNames) {
3562            if (ps.name.equals(uidPackageName)) {
3563                return false;
3564            }
3565            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3566            if (uidPs != null) {
3567                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3568                        libEntry.info.getName());
3569                if (index < 0) {
3570                    continue;
3571                }
3572                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3573                    return false;
3574                }
3575            }
3576        }
3577        return true;
3578    }
3579
3580    @Override
3581    public String[] currentToCanonicalPackageNames(String[] names) {
3582        String[] out = new String[names.length];
3583        // reader
3584        synchronized (mPackages) {
3585            for (int i=names.length-1; i>=0; i--) {
3586                PackageSetting ps = mSettings.mPackages.get(names[i]);
3587                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3588            }
3589        }
3590        return out;
3591    }
3592
3593    @Override
3594    public String[] canonicalToCurrentPackageNames(String[] names) {
3595        String[] out = new String[names.length];
3596        // reader
3597        synchronized (mPackages) {
3598            for (int i=names.length-1; i>=0; i--) {
3599                String cur = mSettings.getRenamedPackageLPr(names[i]);
3600                out[i] = cur != null ? cur : names[i];
3601            }
3602        }
3603        return out;
3604    }
3605
3606    @Override
3607    public int getPackageUid(String packageName, int flags, int userId) {
3608        if (!sUserManager.exists(userId)) return -1;
3609        flags = updateFlagsForPackage(flags, userId, packageName);
3610        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3611                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3612
3613        // reader
3614        synchronized (mPackages) {
3615            final PackageParser.Package p = mPackages.get(packageName);
3616            if (p != null && p.isMatch(flags)) {
3617                return UserHandle.getUid(userId, p.applicationInfo.uid);
3618            }
3619            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3620                final PackageSetting ps = mSettings.mPackages.get(packageName);
3621                if (ps != null && ps.isMatch(flags)) {
3622                    return UserHandle.getUid(userId, ps.appId);
3623                }
3624            }
3625        }
3626
3627        return -1;
3628    }
3629
3630    @Override
3631    public int[] getPackageGids(String packageName, int flags, int userId) {
3632        if (!sUserManager.exists(userId)) return null;
3633        flags = updateFlagsForPackage(flags, userId, packageName);
3634        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3635                false /* requireFullPermission */, false /* checkShell */,
3636                "getPackageGids");
3637
3638        // reader
3639        synchronized (mPackages) {
3640            final PackageParser.Package p = mPackages.get(packageName);
3641            if (p != null && p.isMatch(flags)) {
3642                PackageSetting ps = (PackageSetting) p.mExtras;
3643                // TODO: Shouldn't this be checking for package installed state for userId and
3644                // return null?
3645                return ps.getPermissionsState().computeGids(userId);
3646            }
3647            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3648                final PackageSetting ps = mSettings.mPackages.get(packageName);
3649                if (ps != null && ps.isMatch(flags)) {
3650                    return ps.getPermissionsState().computeGids(userId);
3651                }
3652            }
3653        }
3654
3655        return null;
3656    }
3657
3658    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3659        if (bp.perm != null) {
3660            return PackageParser.generatePermissionInfo(bp.perm, flags);
3661        }
3662        PermissionInfo pi = new PermissionInfo();
3663        pi.name = bp.name;
3664        pi.packageName = bp.sourcePackage;
3665        pi.nonLocalizedLabel = bp.name;
3666        pi.protectionLevel = bp.protectionLevel;
3667        return pi;
3668    }
3669
3670    @Override
3671    public PermissionInfo getPermissionInfo(String name, int flags) {
3672        // reader
3673        synchronized (mPackages) {
3674            final BasePermission p = mSettings.mPermissions.get(name);
3675            if (p != null) {
3676                return generatePermissionInfo(p, flags);
3677            }
3678            return null;
3679        }
3680    }
3681
3682    @Override
3683    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3684            int flags) {
3685        // reader
3686        synchronized (mPackages) {
3687            if (group != null && !mPermissionGroups.containsKey(group)) {
3688                // This is thrown as NameNotFoundException
3689                return null;
3690            }
3691
3692            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3693            for (BasePermission p : mSettings.mPermissions.values()) {
3694                if (group == null) {
3695                    if (p.perm == null || p.perm.info.group == null) {
3696                        out.add(generatePermissionInfo(p, flags));
3697                    }
3698                } else {
3699                    if (p.perm != null && group.equals(p.perm.info.group)) {
3700                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3701                    }
3702                }
3703            }
3704            return new ParceledListSlice<>(out);
3705        }
3706    }
3707
3708    @Override
3709    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3710        // reader
3711        synchronized (mPackages) {
3712            return PackageParser.generatePermissionGroupInfo(
3713                    mPermissionGroups.get(name), flags);
3714        }
3715    }
3716
3717    @Override
3718    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3719        // reader
3720        synchronized (mPackages) {
3721            final int N = mPermissionGroups.size();
3722            ArrayList<PermissionGroupInfo> out
3723                    = new ArrayList<PermissionGroupInfo>(N);
3724            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3725                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3726            }
3727            return new ParceledListSlice<>(out);
3728        }
3729    }
3730
3731    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3732            int uid, int userId) {
3733        if (!sUserManager.exists(userId)) return null;
3734        PackageSetting ps = mSettings.mPackages.get(packageName);
3735        if (ps != null) {
3736            if (filterSharedLibPackageLPr(ps, uid, userId)) {
3737                return null;
3738            }
3739            if (ps.pkg == null) {
3740                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3741                if (pInfo != null) {
3742                    return pInfo.applicationInfo;
3743                }
3744                return null;
3745            }
3746            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3747                    ps.readUserState(userId), userId);
3748            if (ai != null) {
3749                rebaseEnabledOverlays(ai, userId);
3750                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3751            }
3752            return ai;
3753        }
3754        return null;
3755    }
3756
3757    @Override
3758    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3759        if (!sUserManager.exists(userId)) return null;
3760        flags = updateFlagsForApplication(flags, userId, packageName);
3761        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3762                false /* requireFullPermission */, false /* checkShell */, "get application info");
3763
3764        // writer
3765        synchronized (mPackages) {
3766            // Normalize package name to handle renamed packages and static libs
3767            packageName = resolveInternalPackageNameLPr(packageName,
3768                    PackageManager.VERSION_CODE_HIGHEST);
3769
3770            PackageParser.Package p = mPackages.get(packageName);
3771            if (DEBUG_PACKAGE_INFO) Log.v(
3772                    TAG, "getApplicationInfo " + packageName
3773                    + ": " + p);
3774            if (p != null) {
3775                PackageSetting ps = mSettings.mPackages.get(packageName);
3776                if (ps == null) return null;
3777                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
3778                    return null;
3779                }
3780                // Note: isEnabledLP() does not apply here - always return info
3781                ApplicationInfo ai = PackageParser.generateApplicationInfo(
3782                        p, flags, ps.readUserState(userId), userId);
3783                if (ai != null) {
3784                    rebaseEnabledOverlays(ai, userId);
3785                    ai.packageName = resolveExternalPackageNameLPr(p);
3786                }
3787                return ai;
3788            }
3789            if ("android".equals(packageName)||"system".equals(packageName)) {
3790                return mAndroidApplication;
3791            }
3792            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3793                // Already generates the external package name
3794                return generateApplicationInfoFromSettingsLPw(packageName,
3795                        Binder.getCallingUid(), flags, userId);
3796            }
3797        }
3798        return null;
3799    }
3800
3801    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
3802        List<String> paths = new ArrayList<>();
3803        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
3804            mEnabledOverlayPaths.get(userId);
3805        if (userSpecificOverlays != null) {
3806            if (!"android".equals(ai.packageName)) {
3807                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
3808                if (frameworkOverlays != null) {
3809                    paths.addAll(frameworkOverlays);
3810                }
3811            }
3812
3813            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
3814            if (appOverlays != null) {
3815                paths.addAll(appOverlays);
3816            }
3817        }
3818        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
3819    }
3820
3821    private String normalizePackageNameLPr(String packageName) {
3822        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
3823        return normalizedPackageName != null ? normalizedPackageName : packageName;
3824    }
3825
3826    @Override
3827    public void deletePreloadsFileCache() {
3828        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
3829            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
3830        }
3831        File dir = Environment.getDataPreloadsFileCacheDirectory();
3832        Slog.i(TAG, "Deleting preloaded file cache " + dir);
3833        FileUtils.deleteContents(dir);
3834    }
3835
3836    @Override
3837    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
3838            final IPackageDataObserver observer) {
3839        mContext.enforceCallingOrSelfPermission(
3840                android.Manifest.permission.CLEAR_APP_CACHE, null);
3841        mHandler.post(() -> {
3842            boolean success = false;
3843            try {
3844                freeStorage(volumeUuid, freeStorageSize, 0);
3845                success = true;
3846            } catch (IOException e) {
3847                Slog.w(TAG, e);
3848            }
3849            if (observer != null) {
3850                try {
3851                    observer.onRemoveCompleted(null, success);
3852                } catch (RemoteException e) {
3853                    Slog.w(TAG, e);
3854                }
3855            }
3856        });
3857    }
3858
3859    @Override
3860    public void freeStorage(final String volumeUuid, final long freeStorageSize,
3861            final IntentSender pi) {
3862        mContext.enforceCallingOrSelfPermission(
3863                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
3864        mHandler.post(() -> {
3865            boolean success = false;
3866            try {
3867                freeStorage(volumeUuid, freeStorageSize, 0);
3868                success = true;
3869            } catch (IOException e) {
3870                Slog.w(TAG, e);
3871            }
3872            if (pi != null) {
3873                try {
3874                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
3875                } catch (SendIntentException e) {
3876                    Slog.w(TAG, e);
3877                }
3878            }
3879        });
3880    }
3881
3882    /**
3883     * Blocking call to clear various types of cached data across the system
3884     * until the requested bytes are available.
3885     */
3886    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
3887        final StorageManager storage = mContext.getSystemService(StorageManager.class);
3888        final File file = storage.findPathForUuid(volumeUuid);
3889        if (file.getUsableSpace() >= bytes) return;
3890
3891        if (ENABLE_FREE_CACHE_V2) {
3892            final boolean aggressive = (storageFlags
3893                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
3894            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
3895                    volumeUuid);
3896
3897            // 1. Pre-flight to determine if we have any chance to succeed
3898            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
3899            if (internalVolume && (aggressive || SystemProperties
3900                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
3901                deletePreloadsFileCache();
3902                if (file.getUsableSpace() >= bytes) return;
3903            }
3904
3905            // 3. Consider parsed APK data (aggressive only)
3906            if (internalVolume && aggressive) {
3907                FileUtils.deleteContents(mCacheDir);
3908                if (file.getUsableSpace() >= bytes) return;
3909            }
3910
3911            // 4. Consider cached app data (above quotas)
3912            try {
3913                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
3914            } catch (InstallerException ignored) {
3915            }
3916            if (file.getUsableSpace() >= bytes) return;
3917
3918            // 5. Consider shared libraries with refcount=0 and age>2h
3919            // 6. Consider dexopt output (aggressive only)
3920            // 7. Consider ephemeral apps not used in last week
3921
3922            // 8. Consider cached app data (below quotas)
3923            try {
3924                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
3925                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
3926            } catch (InstallerException ignored) {
3927            }
3928            if (file.getUsableSpace() >= bytes) return;
3929
3930            // 9. Consider DropBox entries
3931            // 10. Consider ephemeral cookies
3932
3933        } else {
3934            try {
3935                mInstaller.freeCache(volumeUuid, bytes, 0);
3936            } catch (InstallerException ignored) {
3937            }
3938            if (file.getUsableSpace() >= bytes) return;
3939        }
3940
3941        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
3942    }
3943
3944    /**
3945     * Update given flags based on encryption status of current user.
3946     */
3947    private int updateFlags(int flags, int userId) {
3948        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3949                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
3950            // Caller expressed an explicit opinion about what encryption
3951            // aware/unaware components they want to see, so fall through and
3952            // give them what they want
3953        } else {
3954            // Caller expressed no opinion, so match based on user state
3955            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
3956                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3957            } else {
3958                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
3959            }
3960        }
3961        return flags;
3962    }
3963
3964    private UserManagerInternal getUserManagerInternal() {
3965        if (mUserManagerInternal == null) {
3966            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
3967        }
3968        return mUserManagerInternal;
3969    }
3970
3971    private DeviceIdleController.LocalService getDeviceIdleController() {
3972        if (mDeviceIdleController == null) {
3973            mDeviceIdleController =
3974                    LocalServices.getService(DeviceIdleController.LocalService.class);
3975        }
3976        return mDeviceIdleController;
3977    }
3978
3979    /**
3980     * Update given flags when being used to request {@link PackageInfo}.
3981     */
3982    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
3983        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
3984        boolean triaged = true;
3985        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
3986                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
3987            // Caller is asking for component details, so they'd better be
3988            // asking for specific encryption matching behavior, or be triaged
3989            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
3990                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
3991                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3992                triaged = false;
3993            }
3994        }
3995        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
3996                | PackageManager.MATCH_SYSTEM_ONLY
3997                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
3998            triaged = false;
3999        }
4000        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4001            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4002                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4003                    + Debug.getCallers(5));
4004        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4005                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4006            // If the caller wants all packages and has a restricted profile associated with it,
4007            // then match all users. This is to make sure that launchers that need to access work
4008            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4009            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4010            flags |= PackageManager.MATCH_ANY_USER;
4011        }
4012        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4013            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4014                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4015        }
4016        return updateFlags(flags, userId);
4017    }
4018
4019    /**
4020     * Update given flags when being used to request {@link ApplicationInfo}.
4021     */
4022    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4023        return updateFlagsForPackage(flags, userId, cookie);
4024    }
4025
4026    /**
4027     * Update given flags when being used to request {@link ComponentInfo}.
4028     */
4029    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4030        if (cookie instanceof Intent) {
4031            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4032                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4033            }
4034        }
4035
4036        boolean triaged = true;
4037        // Caller is asking for component details, so they'd better be
4038        // asking for specific encryption matching behavior, or be triaged
4039        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4040                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4041                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4042            triaged = false;
4043        }
4044        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4045            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4046                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4047        }
4048
4049        return updateFlags(flags, userId);
4050    }
4051
4052    /**
4053     * Update given intent when being used to request {@link ResolveInfo}.
4054     */
4055    private Intent updateIntentForResolve(Intent intent) {
4056        if (intent.getSelector() != null) {
4057            intent = intent.getSelector();
4058        }
4059        if (DEBUG_PREFERRED) {
4060            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4061        }
4062        return intent;
4063    }
4064
4065    /**
4066     * Update given flags when being used to request {@link ResolveInfo}.
4067     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4068     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4069     * flag set. However, this flag is only honoured in three circumstances:
4070     * <ul>
4071     * <li>when called from a system process</li>
4072     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4073     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4074     * action and a {@code android.intent.category.BROWSABLE} category</li>
4075     * </ul>
4076     */
4077    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4078            boolean includeInstantApps) {
4079        // Safe mode means we shouldn't match any third-party components
4080        if (mSafeMode) {
4081            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4082        }
4083        if (getInstantAppPackageName(callingUid) != null) {
4084            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4085            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4086            flags |= PackageManager.MATCH_INSTANT;
4087        } else {
4088            // Otherwise, prevent leaking ephemeral components
4089            final boolean isSpecialProcess =
4090                    callingUid == Process.SYSTEM_UID
4091                    || callingUid == Process.SHELL_UID
4092                    || callingUid == 0;
4093            final boolean allowMatchInstant =
4094                    (includeInstantApps
4095                            && Intent.ACTION_VIEW.equals(intent.getAction())
4096                            && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
4097                            && hasWebURI(intent))
4098                    || isSpecialProcess
4099                    || mContext.checkCallingOrSelfPermission(
4100                            android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
4101            flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4102            if (!allowMatchInstant) {
4103                flags &= ~PackageManager.MATCH_INSTANT;
4104            }
4105        }
4106        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4107    }
4108
4109    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4110            int userId) {
4111        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4112        if (ret != null) {
4113            rebaseEnabledOverlays(ret.applicationInfo, userId);
4114        }
4115        return ret;
4116    }
4117
4118    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4119            PackageUserState state, int userId) {
4120        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4121        if (ai != null) {
4122            rebaseEnabledOverlays(ai.applicationInfo, userId);
4123        }
4124        return ai;
4125    }
4126
4127    @Override
4128    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4129        if (!sUserManager.exists(userId)) return null;
4130        flags = updateFlagsForComponent(flags, userId, component);
4131        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4132                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4133        synchronized (mPackages) {
4134            PackageParser.Activity a = mActivities.mActivities.get(component);
4135
4136            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4137            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4138                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4139                if (ps == null) return null;
4140                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4141            }
4142            if (mResolveComponentName.equals(component)) {
4143                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4144                        userId);
4145            }
4146        }
4147        return null;
4148    }
4149
4150    @Override
4151    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4152            String resolvedType) {
4153        synchronized (mPackages) {
4154            if (component.equals(mResolveComponentName)) {
4155                // The resolver supports EVERYTHING!
4156                return true;
4157            }
4158            PackageParser.Activity a = mActivities.mActivities.get(component);
4159            if (a == null) {
4160                return false;
4161            }
4162            for (int i=0; i<a.intents.size(); i++) {
4163                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4164                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4165                    return true;
4166                }
4167            }
4168            return false;
4169        }
4170    }
4171
4172    @Override
4173    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4174        if (!sUserManager.exists(userId)) return null;
4175        flags = updateFlagsForComponent(flags, userId, component);
4176        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4177                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4178        synchronized (mPackages) {
4179            PackageParser.Activity a = mReceivers.mActivities.get(component);
4180            if (DEBUG_PACKAGE_INFO) Log.v(
4181                TAG, "getReceiverInfo " + component + ": " + a);
4182            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4183                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4184                if (ps == null) return null;
4185                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4186            }
4187        }
4188        return null;
4189    }
4190
4191    @Override
4192    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(int flags, int userId) {
4193        if (!sUserManager.exists(userId)) return null;
4194        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4195
4196        flags = updateFlagsForPackage(flags, userId, null);
4197
4198        final boolean canSeeStaticLibraries =
4199                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4200                        == PERMISSION_GRANTED
4201                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4202                        == PERMISSION_GRANTED
4203                || mContext.checkCallingOrSelfPermission(REQUEST_INSTALL_PACKAGES)
4204                        == PERMISSION_GRANTED
4205                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4206                        == PERMISSION_GRANTED;
4207
4208        synchronized (mPackages) {
4209            List<SharedLibraryInfo> result = null;
4210
4211            final int libCount = mSharedLibraries.size();
4212            for (int i = 0; i < libCount; i++) {
4213                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4214                if (versionedLib == null) {
4215                    continue;
4216                }
4217
4218                final int versionCount = versionedLib.size();
4219                for (int j = 0; j < versionCount; j++) {
4220                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4221                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4222                        break;
4223                    }
4224                    final long identity = Binder.clearCallingIdentity();
4225                    try {
4226                        // TODO: We will change version code to long, so in the new API it is long
4227                        PackageInfo packageInfo = getPackageInfoVersioned(
4228                                libInfo.getDeclaringPackage(), flags, userId);
4229                        if (packageInfo == null) {
4230                            continue;
4231                        }
4232                    } finally {
4233                        Binder.restoreCallingIdentity(identity);
4234                    }
4235
4236                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4237                            // TODO: Remove cast for lib version once internally we support longs.
4238                            (int) libInfo.getVersion(), libInfo.getType(),
4239                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4240                            flags, userId));
4241
4242                    if (result == null) {
4243                        result = new ArrayList<>();
4244                    }
4245                    result.add(resLibInfo);
4246                }
4247            }
4248
4249            return result != null ? new ParceledListSlice<>(result) : null;
4250        }
4251    }
4252
4253    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4254            SharedLibraryInfo libInfo, int flags, int userId) {
4255        List<VersionedPackage> versionedPackages = null;
4256        final int packageCount = mSettings.mPackages.size();
4257        for (int i = 0; i < packageCount; i++) {
4258            PackageSetting ps = mSettings.mPackages.valueAt(i);
4259
4260            if (ps == null) {
4261                continue;
4262            }
4263
4264            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4265                continue;
4266            }
4267
4268            final String libName = libInfo.getName();
4269            if (libInfo.isStatic()) {
4270                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4271                if (libIdx < 0) {
4272                    continue;
4273                }
4274                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4275                    continue;
4276                }
4277                if (versionedPackages == null) {
4278                    versionedPackages = new ArrayList<>();
4279                }
4280                // If the dependent is a static shared lib, use the public package name
4281                String dependentPackageName = ps.name;
4282                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4283                    dependentPackageName = ps.pkg.manifestPackageName;
4284                }
4285                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4286            } else if (ps.pkg != null) {
4287                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4288                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4289                    if (versionedPackages == null) {
4290                        versionedPackages = new ArrayList<>();
4291                    }
4292                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4293                }
4294            }
4295        }
4296
4297        return versionedPackages;
4298    }
4299
4300    @Override
4301    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4302        if (!sUserManager.exists(userId)) return null;
4303        flags = updateFlagsForComponent(flags, userId, component);
4304        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4305                false /* requireFullPermission */, false /* checkShell */, "get service info");
4306        synchronized (mPackages) {
4307            PackageParser.Service s = mServices.mServices.get(component);
4308            if (DEBUG_PACKAGE_INFO) Log.v(
4309                TAG, "getServiceInfo " + component + ": " + s);
4310            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4311                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4312                if (ps == null) return null;
4313                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4314                        ps.readUserState(userId), userId);
4315                if (si != null) {
4316                    rebaseEnabledOverlays(si.applicationInfo, userId);
4317                }
4318                return si;
4319            }
4320        }
4321        return null;
4322    }
4323
4324    @Override
4325    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4326        if (!sUserManager.exists(userId)) return null;
4327        flags = updateFlagsForComponent(flags, userId, component);
4328        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4329                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4330        synchronized (mPackages) {
4331            PackageParser.Provider p = mProviders.mProviders.get(component);
4332            if (DEBUG_PACKAGE_INFO) Log.v(
4333                TAG, "getProviderInfo " + component + ": " + p);
4334            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4335                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4336                if (ps == null) return null;
4337                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4338                        ps.readUserState(userId), userId);
4339                if (pi != null) {
4340                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4341                }
4342                return pi;
4343            }
4344        }
4345        return null;
4346    }
4347
4348    @Override
4349    public String[] getSystemSharedLibraryNames() {
4350        synchronized (mPackages) {
4351            Set<String> libs = null;
4352            final int libCount = mSharedLibraries.size();
4353            for (int i = 0; i < libCount; i++) {
4354                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4355                if (versionedLib == null) {
4356                    continue;
4357                }
4358                final int versionCount = versionedLib.size();
4359                for (int j = 0; j < versionCount; j++) {
4360                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4361                    if (!libEntry.info.isStatic()) {
4362                        if (libs == null) {
4363                            libs = new ArraySet<>();
4364                        }
4365                        libs.add(libEntry.info.getName());
4366                        break;
4367                    }
4368                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4369                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4370                            UserHandle.getUserId(Binder.getCallingUid()))) {
4371                        if (libs == null) {
4372                            libs = new ArraySet<>();
4373                        }
4374                        libs.add(libEntry.info.getName());
4375                        break;
4376                    }
4377                }
4378            }
4379
4380            if (libs != null) {
4381                String[] libsArray = new String[libs.size()];
4382                libs.toArray(libsArray);
4383                return libsArray;
4384            }
4385
4386            return null;
4387        }
4388    }
4389
4390    @Override
4391    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4392        synchronized (mPackages) {
4393            return mServicesSystemSharedLibraryPackageName;
4394        }
4395    }
4396
4397    @Override
4398    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4399        synchronized (mPackages) {
4400            return mSharedSystemSharedLibraryPackageName;
4401        }
4402    }
4403
4404    private void updateSequenceNumberLP(String packageName, int[] userList) {
4405        for (int i = userList.length - 1; i >= 0; --i) {
4406            final int userId = userList[i];
4407            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4408            if (changedPackages == null) {
4409                changedPackages = new SparseArray<>();
4410                mChangedPackages.put(userId, changedPackages);
4411            }
4412            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4413            if (sequenceNumbers == null) {
4414                sequenceNumbers = new HashMap<>();
4415                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4416            }
4417            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4418            if (sequenceNumber != null) {
4419                changedPackages.remove(sequenceNumber);
4420            }
4421            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4422            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4423        }
4424        mChangedPackagesSequenceNumber++;
4425    }
4426
4427    @Override
4428    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4429        synchronized (mPackages) {
4430            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4431                return null;
4432            }
4433            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4434            if (changedPackages == null) {
4435                return null;
4436            }
4437            final List<String> packageNames =
4438                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4439            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4440                final String packageName = changedPackages.get(i);
4441                if (packageName != null) {
4442                    packageNames.add(packageName);
4443                }
4444            }
4445            return packageNames.isEmpty()
4446                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4447        }
4448    }
4449
4450    @Override
4451    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4452        ArrayList<FeatureInfo> res;
4453        synchronized (mAvailableFeatures) {
4454            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4455            res.addAll(mAvailableFeatures.values());
4456        }
4457        final FeatureInfo fi = new FeatureInfo();
4458        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4459                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4460        res.add(fi);
4461
4462        return new ParceledListSlice<>(res);
4463    }
4464
4465    @Override
4466    public boolean hasSystemFeature(String name, int version) {
4467        synchronized (mAvailableFeatures) {
4468            final FeatureInfo feat = mAvailableFeatures.get(name);
4469            if (feat == null) {
4470                return false;
4471            } else {
4472                return feat.version >= version;
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public int checkPermission(String permName, String pkgName, int userId) {
4479        if (!sUserManager.exists(userId)) {
4480            return PackageManager.PERMISSION_DENIED;
4481        }
4482
4483        synchronized (mPackages) {
4484            final PackageParser.Package p = mPackages.get(pkgName);
4485            if (p != null && p.mExtras != null) {
4486                final PackageSetting ps = (PackageSetting) p.mExtras;
4487                final PermissionsState permissionsState = ps.getPermissionsState();
4488                if (permissionsState.hasPermission(permName, userId)) {
4489                    return PackageManager.PERMISSION_GRANTED;
4490                }
4491                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4492                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4493                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4494                    return PackageManager.PERMISSION_GRANTED;
4495                }
4496            }
4497        }
4498
4499        return PackageManager.PERMISSION_DENIED;
4500    }
4501
4502    @Override
4503    public int checkUidPermission(String permName, int uid) {
4504        final int userId = UserHandle.getUserId(uid);
4505
4506        if (!sUserManager.exists(userId)) {
4507            return PackageManager.PERMISSION_DENIED;
4508        }
4509
4510        synchronized (mPackages) {
4511            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4512            if (obj != null) {
4513                final SettingBase ps = (SettingBase) obj;
4514                final PermissionsState permissionsState = ps.getPermissionsState();
4515                if (permissionsState.hasPermission(permName, userId)) {
4516                    return PackageManager.PERMISSION_GRANTED;
4517                }
4518                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4519                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4520                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4521                    return PackageManager.PERMISSION_GRANTED;
4522                }
4523            } else {
4524                ArraySet<String> perms = mSystemPermissions.get(uid);
4525                if (perms != null) {
4526                    if (perms.contains(permName)) {
4527                        return PackageManager.PERMISSION_GRANTED;
4528                    }
4529                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4530                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4531                        return PackageManager.PERMISSION_GRANTED;
4532                    }
4533                }
4534            }
4535        }
4536
4537        return PackageManager.PERMISSION_DENIED;
4538    }
4539
4540    @Override
4541    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4542        if (UserHandle.getCallingUserId() != userId) {
4543            mContext.enforceCallingPermission(
4544                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4545                    "isPermissionRevokedByPolicy for user " + userId);
4546        }
4547
4548        if (checkPermission(permission, packageName, userId)
4549                == PackageManager.PERMISSION_GRANTED) {
4550            return false;
4551        }
4552
4553        final long identity = Binder.clearCallingIdentity();
4554        try {
4555            final int flags = getPermissionFlags(permission, packageName, userId);
4556            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4557        } finally {
4558            Binder.restoreCallingIdentity(identity);
4559        }
4560    }
4561
4562    @Override
4563    public String getPermissionControllerPackageName() {
4564        synchronized (mPackages) {
4565            return mRequiredInstallerPackage;
4566        }
4567    }
4568
4569    /**
4570     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4571     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4572     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4573     * @param message the message to log on security exception
4574     */
4575    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4576            boolean checkShell, String message) {
4577        if (userId < 0) {
4578            throw new IllegalArgumentException("Invalid userId " + userId);
4579        }
4580        if (checkShell) {
4581            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4582        }
4583        if (userId == UserHandle.getUserId(callingUid)) return;
4584        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4585            if (requireFullPermission) {
4586                mContext.enforceCallingOrSelfPermission(
4587                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4588            } else {
4589                try {
4590                    mContext.enforceCallingOrSelfPermission(
4591                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4592                } catch (SecurityException se) {
4593                    mContext.enforceCallingOrSelfPermission(
4594                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4595                }
4596            }
4597        }
4598    }
4599
4600    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4601        if (callingUid == Process.SHELL_UID) {
4602            if (userHandle >= 0
4603                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4604                throw new SecurityException("Shell does not have permission to access user "
4605                        + userHandle);
4606            } else if (userHandle < 0) {
4607                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4608                        + Debug.getCallers(3));
4609            }
4610        }
4611    }
4612
4613    private BasePermission findPermissionTreeLP(String permName) {
4614        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4615            if (permName.startsWith(bp.name) &&
4616                    permName.length() > bp.name.length() &&
4617                    permName.charAt(bp.name.length()) == '.') {
4618                return bp;
4619            }
4620        }
4621        return null;
4622    }
4623
4624    private BasePermission checkPermissionTreeLP(String permName) {
4625        if (permName != null) {
4626            BasePermission bp = findPermissionTreeLP(permName);
4627            if (bp != null) {
4628                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4629                    return bp;
4630                }
4631                throw new SecurityException("Calling uid "
4632                        + Binder.getCallingUid()
4633                        + " is not allowed to add to permission tree "
4634                        + bp.name + " owned by uid " + bp.uid);
4635            }
4636        }
4637        throw new SecurityException("No permission tree found for " + permName);
4638    }
4639
4640    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4641        if (s1 == null) {
4642            return s2 == null;
4643        }
4644        if (s2 == null) {
4645            return false;
4646        }
4647        if (s1.getClass() != s2.getClass()) {
4648            return false;
4649        }
4650        return s1.equals(s2);
4651    }
4652
4653    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4654        if (pi1.icon != pi2.icon) return false;
4655        if (pi1.logo != pi2.logo) return false;
4656        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4657        if (!compareStrings(pi1.name, pi2.name)) return false;
4658        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4659        // We'll take care of setting this one.
4660        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4661        // These are not currently stored in settings.
4662        //if (!compareStrings(pi1.group, pi2.group)) return false;
4663        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4664        //if (pi1.labelRes != pi2.labelRes) return false;
4665        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4666        return true;
4667    }
4668
4669    int permissionInfoFootprint(PermissionInfo info) {
4670        int size = info.name.length();
4671        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4672        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4673        return size;
4674    }
4675
4676    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4677        int size = 0;
4678        for (BasePermission perm : mSettings.mPermissions.values()) {
4679            if (perm.uid == tree.uid) {
4680                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4681            }
4682        }
4683        return size;
4684    }
4685
4686    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4687        // We calculate the max size of permissions defined by this uid and throw
4688        // if that plus the size of 'info' would exceed our stated maximum.
4689        if (tree.uid != Process.SYSTEM_UID) {
4690            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4691            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4692                throw new SecurityException("Permission tree size cap exceeded");
4693            }
4694        }
4695    }
4696
4697    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4698        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4699            throw new SecurityException("Label must be specified in permission");
4700        }
4701        BasePermission tree = checkPermissionTreeLP(info.name);
4702        BasePermission bp = mSettings.mPermissions.get(info.name);
4703        boolean added = bp == null;
4704        boolean changed = true;
4705        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4706        if (added) {
4707            enforcePermissionCapLocked(info, tree);
4708            bp = new BasePermission(info.name, tree.sourcePackage,
4709                    BasePermission.TYPE_DYNAMIC);
4710        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4711            throw new SecurityException(
4712                    "Not allowed to modify non-dynamic permission "
4713                    + info.name);
4714        } else {
4715            if (bp.protectionLevel == fixedLevel
4716                    && bp.perm.owner.equals(tree.perm.owner)
4717                    && bp.uid == tree.uid
4718                    && comparePermissionInfos(bp.perm.info, info)) {
4719                changed = false;
4720            }
4721        }
4722        bp.protectionLevel = fixedLevel;
4723        info = new PermissionInfo(info);
4724        info.protectionLevel = fixedLevel;
4725        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4726        bp.perm.info.packageName = tree.perm.info.packageName;
4727        bp.uid = tree.uid;
4728        if (added) {
4729            mSettings.mPermissions.put(info.name, bp);
4730        }
4731        if (changed) {
4732            if (!async) {
4733                mSettings.writeLPr();
4734            } else {
4735                scheduleWriteSettingsLocked();
4736            }
4737        }
4738        return added;
4739    }
4740
4741    @Override
4742    public boolean addPermission(PermissionInfo info) {
4743        synchronized (mPackages) {
4744            return addPermissionLocked(info, false);
4745        }
4746    }
4747
4748    @Override
4749    public boolean addPermissionAsync(PermissionInfo info) {
4750        synchronized (mPackages) {
4751            return addPermissionLocked(info, true);
4752        }
4753    }
4754
4755    @Override
4756    public void removePermission(String name) {
4757        synchronized (mPackages) {
4758            checkPermissionTreeLP(name);
4759            BasePermission bp = mSettings.mPermissions.get(name);
4760            if (bp != null) {
4761                if (bp.type != BasePermission.TYPE_DYNAMIC) {
4762                    throw new SecurityException(
4763                            "Not allowed to modify non-dynamic permission "
4764                            + name);
4765                }
4766                mSettings.mPermissions.remove(name);
4767                mSettings.writeLPr();
4768            }
4769        }
4770    }
4771
4772    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
4773            BasePermission bp) {
4774        int index = pkg.requestedPermissions.indexOf(bp.name);
4775        if (index == -1) {
4776            throw new SecurityException("Package " + pkg.packageName
4777                    + " has not requested permission " + bp.name);
4778        }
4779        if (!bp.isRuntime() && !bp.isDevelopment()) {
4780            throw new SecurityException("Permission " + bp.name
4781                    + " is not a changeable permission type");
4782        }
4783    }
4784
4785    @Override
4786    public void grantRuntimePermission(String packageName, String name, final int userId) {
4787        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4788    }
4789
4790    private void grantRuntimePermission(String packageName, String name, final int userId,
4791            boolean overridePolicy) {
4792        if (!sUserManager.exists(userId)) {
4793            Log.e(TAG, "No such user:" + userId);
4794            return;
4795        }
4796
4797        mContext.enforceCallingOrSelfPermission(
4798                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
4799                "grantRuntimePermission");
4800
4801        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4802                true /* requireFullPermission */, true /* checkShell */,
4803                "grantRuntimePermission");
4804
4805        final int uid;
4806        final SettingBase sb;
4807
4808        synchronized (mPackages) {
4809            final PackageParser.Package pkg = mPackages.get(packageName);
4810            if (pkg == null) {
4811                throw new IllegalArgumentException("Unknown package: " + packageName);
4812            }
4813
4814            final BasePermission bp = mSettings.mPermissions.get(name);
4815            if (bp == null) {
4816                throw new IllegalArgumentException("Unknown permission: " + name);
4817            }
4818
4819            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4820
4821            // If a permission review is required for legacy apps we represent
4822            // their permissions as always granted runtime ones since we need
4823            // to keep the review required permission flag per user while an
4824            // install permission's state is shared across all users.
4825            if (mPermissionReviewRequired
4826                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4827                    && bp.isRuntime()) {
4828                return;
4829            }
4830
4831            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
4832            sb = (SettingBase) pkg.mExtras;
4833            if (sb == null) {
4834                throw new IllegalArgumentException("Unknown package: " + packageName);
4835            }
4836
4837            final PermissionsState permissionsState = sb.getPermissionsState();
4838
4839            final int flags = permissionsState.getPermissionFlags(name, userId);
4840            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4841                throw new SecurityException("Cannot grant system fixed permission "
4842                        + name + " for package " + packageName);
4843            }
4844            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4845                throw new SecurityException("Cannot grant policy fixed permission "
4846                        + name + " for package " + packageName);
4847            }
4848
4849            if (bp.isDevelopment()) {
4850                // Development permissions must be handled specially, since they are not
4851                // normal runtime permissions.  For now they apply to all users.
4852                if (permissionsState.grantInstallPermission(bp) !=
4853                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4854                    scheduleWriteSettingsLocked();
4855                }
4856                return;
4857            }
4858
4859            final PackageSetting ps = mSettings.mPackages.get(packageName);
4860            if (ps.getInstantApp(userId) && !bp.isInstant()) {
4861                throw new SecurityException("Cannot grant non-ephemeral permission"
4862                        + name + " for package " + packageName);
4863            }
4864
4865            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4866                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
4867                return;
4868            }
4869
4870            final int result = permissionsState.grantRuntimePermission(bp, userId);
4871            switch (result) {
4872                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
4873                    return;
4874                }
4875
4876                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
4877                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
4878                    mHandler.post(new Runnable() {
4879                        @Override
4880                        public void run() {
4881                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
4882                        }
4883                    });
4884                }
4885                break;
4886            }
4887
4888            if (bp.isRuntime()) {
4889                logPermissionGranted(mContext, name, packageName);
4890            }
4891
4892            mOnPermissionChangeListeners.onPermissionsChanged(uid);
4893
4894            // Not critical if that is lost - app has to request again.
4895            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
4896        }
4897
4898        // Only need to do this if user is initialized. Otherwise it's a new user
4899        // and there are no processes running as the user yet and there's no need
4900        // to make an expensive call to remount processes for the changed permissions.
4901        if (READ_EXTERNAL_STORAGE.equals(name)
4902                || WRITE_EXTERNAL_STORAGE.equals(name)) {
4903            final long token = Binder.clearCallingIdentity();
4904            try {
4905                if (sUserManager.isInitialized(userId)) {
4906                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
4907                            StorageManagerInternal.class);
4908                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
4909                }
4910            } finally {
4911                Binder.restoreCallingIdentity(token);
4912            }
4913        }
4914    }
4915
4916    @Override
4917    public void revokeRuntimePermission(String packageName, String name, int userId) {
4918        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
4919    }
4920
4921    private void revokeRuntimePermission(String packageName, String name, int userId,
4922            boolean overridePolicy) {
4923        if (!sUserManager.exists(userId)) {
4924            Log.e(TAG, "No such user:" + userId);
4925            return;
4926        }
4927
4928        mContext.enforceCallingOrSelfPermission(
4929                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
4930                "revokeRuntimePermission");
4931
4932        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4933                true /* requireFullPermission */, true /* checkShell */,
4934                "revokeRuntimePermission");
4935
4936        final int appId;
4937
4938        synchronized (mPackages) {
4939            final PackageParser.Package pkg = mPackages.get(packageName);
4940            if (pkg == null) {
4941                throw new IllegalArgumentException("Unknown package: " + packageName);
4942            }
4943
4944            final BasePermission bp = mSettings.mPermissions.get(name);
4945            if (bp == null) {
4946                throw new IllegalArgumentException("Unknown permission: " + name);
4947            }
4948
4949            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
4950
4951            // If a permission review is required for legacy apps we represent
4952            // their permissions as always granted runtime ones since we need
4953            // to keep the review required permission flag per user while an
4954            // install permission's state is shared across all users.
4955            if (mPermissionReviewRequired
4956                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
4957                    && bp.isRuntime()) {
4958                return;
4959            }
4960
4961            SettingBase sb = (SettingBase) pkg.mExtras;
4962            if (sb == null) {
4963                throw new IllegalArgumentException("Unknown package: " + packageName);
4964            }
4965
4966            final PermissionsState permissionsState = sb.getPermissionsState();
4967
4968            final int flags = permissionsState.getPermissionFlags(name, userId);
4969            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
4970                throw new SecurityException("Cannot revoke system fixed permission "
4971                        + name + " for package " + packageName);
4972            }
4973            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
4974                throw new SecurityException("Cannot revoke policy fixed permission "
4975                        + name + " for package " + packageName);
4976            }
4977
4978            if (bp.isDevelopment()) {
4979                // Development permissions must be handled specially, since they are not
4980                // normal runtime permissions.  For now they apply to all users.
4981                if (permissionsState.revokeInstallPermission(bp) !=
4982                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
4983                    scheduleWriteSettingsLocked();
4984                }
4985                return;
4986            }
4987
4988            if (permissionsState.revokeRuntimePermission(bp, userId) ==
4989                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
4990                return;
4991            }
4992
4993            if (bp.isRuntime()) {
4994                logPermissionRevoked(mContext, name, packageName);
4995            }
4996
4997            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
4998
4999            // Critical, after this call app should never have the permission.
5000            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5001
5002            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5003        }
5004
5005        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5006    }
5007
5008    /**
5009     * Get the first event id for the permission.
5010     *
5011     * <p>There are four events for each permission: <ul>
5012     *     <li>Request permission: first id + 0</li>
5013     *     <li>Grant permission: first id + 1</li>
5014     *     <li>Request for permission denied: first id + 2</li>
5015     *     <li>Revoke permission: first id + 3</li>
5016     * </ul></p>
5017     *
5018     * @param name name of the permission
5019     *
5020     * @return The first event id for the permission
5021     */
5022    private static int getBaseEventId(@NonNull String name) {
5023        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5024
5025        if (eventIdIndex == -1) {
5026            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5027                    || "user".equals(Build.TYPE)) {
5028                Log.i(TAG, "Unknown permission " + name);
5029
5030                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5031            } else {
5032                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5033                //
5034                // Also update
5035                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5036                // - metrics_constants.proto
5037                throw new IllegalStateException("Unknown permission " + name);
5038            }
5039        }
5040
5041        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5042    }
5043
5044    /**
5045     * Log that a permission was revoked.
5046     *
5047     * @param context Context of the caller
5048     * @param name name of the permission
5049     * @param packageName package permission if for
5050     */
5051    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5052            @NonNull String packageName) {
5053        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5054    }
5055
5056    /**
5057     * Log that a permission request was granted.
5058     *
5059     * @param context Context of the caller
5060     * @param name name of the permission
5061     * @param packageName package permission if for
5062     */
5063    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5064            @NonNull String packageName) {
5065        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5066    }
5067
5068    @Override
5069    public void resetRuntimePermissions() {
5070        mContext.enforceCallingOrSelfPermission(
5071                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5072                "revokeRuntimePermission");
5073
5074        int callingUid = Binder.getCallingUid();
5075        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5076            mContext.enforceCallingOrSelfPermission(
5077                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5078                    "resetRuntimePermissions");
5079        }
5080
5081        synchronized (mPackages) {
5082            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5083            for (int userId : UserManagerService.getInstance().getUserIds()) {
5084                final int packageCount = mPackages.size();
5085                for (int i = 0; i < packageCount; i++) {
5086                    PackageParser.Package pkg = mPackages.valueAt(i);
5087                    if (!(pkg.mExtras instanceof PackageSetting)) {
5088                        continue;
5089                    }
5090                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5091                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5092                }
5093            }
5094        }
5095    }
5096
5097    @Override
5098    public int getPermissionFlags(String name, String packageName, int userId) {
5099        if (!sUserManager.exists(userId)) {
5100            return 0;
5101        }
5102
5103        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5104
5105        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5106                true /* requireFullPermission */, false /* checkShell */,
5107                "getPermissionFlags");
5108
5109        synchronized (mPackages) {
5110            final PackageParser.Package pkg = mPackages.get(packageName);
5111            if (pkg == null) {
5112                return 0;
5113            }
5114
5115            final BasePermission bp = mSettings.mPermissions.get(name);
5116            if (bp == null) {
5117                return 0;
5118            }
5119
5120            SettingBase sb = (SettingBase) pkg.mExtras;
5121            if (sb == null) {
5122                return 0;
5123            }
5124
5125            PermissionsState permissionsState = sb.getPermissionsState();
5126            return permissionsState.getPermissionFlags(name, userId);
5127        }
5128    }
5129
5130    @Override
5131    public void updatePermissionFlags(String name, String packageName, int flagMask,
5132            int flagValues, int userId) {
5133        if (!sUserManager.exists(userId)) {
5134            return;
5135        }
5136
5137        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5138
5139        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5140                true /* requireFullPermission */, true /* checkShell */,
5141                "updatePermissionFlags");
5142
5143        // Only the system can change these flags and nothing else.
5144        if (getCallingUid() != Process.SYSTEM_UID) {
5145            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5146            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5147            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5148            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5149            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5150        }
5151
5152        synchronized (mPackages) {
5153            final PackageParser.Package pkg = mPackages.get(packageName);
5154            if (pkg == null) {
5155                throw new IllegalArgumentException("Unknown package: " + packageName);
5156            }
5157
5158            final BasePermission bp = mSettings.mPermissions.get(name);
5159            if (bp == null) {
5160                throw new IllegalArgumentException("Unknown permission: " + name);
5161            }
5162
5163            SettingBase sb = (SettingBase) pkg.mExtras;
5164            if (sb == null) {
5165                throw new IllegalArgumentException("Unknown package: " + packageName);
5166            }
5167
5168            PermissionsState permissionsState = sb.getPermissionsState();
5169
5170            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5171
5172            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5173                // Install and runtime permissions are stored in different places,
5174                // so figure out what permission changed and persist the change.
5175                if (permissionsState.getInstallPermissionState(name) != null) {
5176                    scheduleWriteSettingsLocked();
5177                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5178                        || hadState) {
5179                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5180                }
5181            }
5182        }
5183    }
5184
5185    /**
5186     * Update the permission flags for all packages and runtime permissions of a user in order
5187     * to allow device or profile owner to remove POLICY_FIXED.
5188     */
5189    @Override
5190    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5191        if (!sUserManager.exists(userId)) {
5192            return;
5193        }
5194
5195        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5196
5197        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5198                true /* requireFullPermission */, true /* checkShell */,
5199                "updatePermissionFlagsForAllApps");
5200
5201        // Only the system can change system fixed flags.
5202        if (getCallingUid() != Process.SYSTEM_UID) {
5203            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5204            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5205        }
5206
5207        synchronized (mPackages) {
5208            boolean changed = false;
5209            final int packageCount = mPackages.size();
5210            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5211                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5212                SettingBase sb = (SettingBase) pkg.mExtras;
5213                if (sb == null) {
5214                    continue;
5215                }
5216                PermissionsState permissionsState = sb.getPermissionsState();
5217                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5218                        userId, flagMask, flagValues);
5219            }
5220            if (changed) {
5221                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5222            }
5223        }
5224    }
5225
5226    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5227        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5228                != PackageManager.PERMISSION_GRANTED
5229            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5230                != PackageManager.PERMISSION_GRANTED) {
5231            throw new SecurityException(message + " requires "
5232                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5233                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5234        }
5235    }
5236
5237    @Override
5238    public boolean shouldShowRequestPermissionRationale(String permissionName,
5239            String packageName, int userId) {
5240        if (UserHandle.getCallingUserId() != userId) {
5241            mContext.enforceCallingPermission(
5242                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5243                    "canShowRequestPermissionRationale for user " + userId);
5244        }
5245
5246        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5247        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5248            return false;
5249        }
5250
5251        if (checkPermission(permissionName, packageName, userId)
5252                == PackageManager.PERMISSION_GRANTED) {
5253            return false;
5254        }
5255
5256        final int flags;
5257
5258        final long identity = Binder.clearCallingIdentity();
5259        try {
5260            flags = getPermissionFlags(permissionName,
5261                    packageName, userId);
5262        } finally {
5263            Binder.restoreCallingIdentity(identity);
5264        }
5265
5266        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5267                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5268                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5269
5270        if ((flags & fixedFlags) != 0) {
5271            return false;
5272        }
5273
5274        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5275    }
5276
5277    @Override
5278    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5279        mContext.enforceCallingOrSelfPermission(
5280                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5281                "addOnPermissionsChangeListener");
5282
5283        synchronized (mPackages) {
5284            mOnPermissionChangeListeners.addListenerLocked(listener);
5285        }
5286    }
5287
5288    @Override
5289    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5290        synchronized (mPackages) {
5291            mOnPermissionChangeListeners.removeListenerLocked(listener);
5292        }
5293    }
5294
5295    @Override
5296    public boolean isProtectedBroadcast(String actionName) {
5297        synchronized (mPackages) {
5298            if (mProtectedBroadcasts.contains(actionName)) {
5299                return true;
5300            } else if (actionName != null) {
5301                // TODO: remove these terrible hacks
5302                if (actionName.startsWith("android.net.netmon.lingerExpired")
5303                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5304                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5305                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5306                    return true;
5307                }
5308            }
5309        }
5310        return false;
5311    }
5312
5313    @Override
5314    public int checkSignatures(String pkg1, String pkg2) {
5315        synchronized (mPackages) {
5316            final PackageParser.Package p1 = mPackages.get(pkg1);
5317            final PackageParser.Package p2 = mPackages.get(pkg2);
5318            if (p1 == null || p1.mExtras == null
5319                    || p2 == null || p2.mExtras == null) {
5320                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5321            }
5322            return compareSignatures(p1.mSignatures, p2.mSignatures);
5323        }
5324    }
5325
5326    @Override
5327    public int checkUidSignatures(int uid1, int uid2) {
5328        // Map to base uids.
5329        uid1 = UserHandle.getAppId(uid1);
5330        uid2 = UserHandle.getAppId(uid2);
5331        // reader
5332        synchronized (mPackages) {
5333            Signature[] s1;
5334            Signature[] s2;
5335            Object obj = mSettings.getUserIdLPr(uid1);
5336            if (obj != null) {
5337                if (obj instanceof SharedUserSetting) {
5338                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5339                } else if (obj instanceof PackageSetting) {
5340                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5341                } else {
5342                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5343                }
5344            } else {
5345                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5346            }
5347            obj = mSettings.getUserIdLPr(uid2);
5348            if (obj != null) {
5349                if (obj instanceof SharedUserSetting) {
5350                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5351                } else if (obj instanceof PackageSetting) {
5352                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5353                } else {
5354                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5355                }
5356            } else {
5357                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5358            }
5359            return compareSignatures(s1, s2);
5360        }
5361    }
5362
5363    /**
5364     * This method should typically only be used when granting or revoking
5365     * permissions, since the app may immediately restart after this call.
5366     * <p>
5367     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5368     * guard your work against the app being relaunched.
5369     */
5370    private void killUid(int appId, int userId, String reason) {
5371        final long identity = Binder.clearCallingIdentity();
5372        try {
5373            IActivityManager am = ActivityManager.getService();
5374            if (am != null) {
5375                try {
5376                    am.killUid(appId, userId, reason);
5377                } catch (RemoteException e) {
5378                    /* ignore - same process */
5379                }
5380            }
5381        } finally {
5382            Binder.restoreCallingIdentity(identity);
5383        }
5384    }
5385
5386    /**
5387     * Compares two sets of signatures. Returns:
5388     * <br />
5389     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5390     * <br />
5391     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5392     * <br />
5393     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5394     * <br />
5395     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5396     * <br />
5397     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5398     */
5399    static int compareSignatures(Signature[] s1, Signature[] s2) {
5400        if (s1 == null) {
5401            return s2 == null
5402                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5403                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5404        }
5405
5406        if (s2 == null) {
5407            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5408        }
5409
5410        if (s1.length != s2.length) {
5411            return PackageManager.SIGNATURE_NO_MATCH;
5412        }
5413
5414        // Since both signature sets are of size 1, we can compare without HashSets.
5415        if (s1.length == 1) {
5416            return s1[0].equals(s2[0]) ?
5417                    PackageManager.SIGNATURE_MATCH :
5418                    PackageManager.SIGNATURE_NO_MATCH;
5419        }
5420
5421        ArraySet<Signature> set1 = new ArraySet<Signature>();
5422        for (Signature sig : s1) {
5423            set1.add(sig);
5424        }
5425        ArraySet<Signature> set2 = new ArraySet<Signature>();
5426        for (Signature sig : s2) {
5427            set2.add(sig);
5428        }
5429        // Make sure s2 contains all signatures in s1.
5430        if (set1.equals(set2)) {
5431            return PackageManager.SIGNATURE_MATCH;
5432        }
5433        return PackageManager.SIGNATURE_NO_MATCH;
5434    }
5435
5436    /**
5437     * If the database version for this type of package (internal storage or
5438     * external storage) is less than the version where package signatures
5439     * were updated, return true.
5440     */
5441    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5442        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5443        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5444    }
5445
5446    /**
5447     * Used for backward compatibility to make sure any packages with
5448     * certificate chains get upgraded to the new style. {@code existingSigs}
5449     * will be in the old format (since they were stored on disk from before the
5450     * system upgrade) and {@code scannedSigs} will be in the newer format.
5451     */
5452    private int compareSignaturesCompat(PackageSignatures existingSigs,
5453            PackageParser.Package scannedPkg) {
5454        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5455            return PackageManager.SIGNATURE_NO_MATCH;
5456        }
5457
5458        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5459        for (Signature sig : existingSigs.mSignatures) {
5460            existingSet.add(sig);
5461        }
5462        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5463        for (Signature sig : scannedPkg.mSignatures) {
5464            try {
5465                Signature[] chainSignatures = sig.getChainSignatures();
5466                for (Signature chainSig : chainSignatures) {
5467                    scannedCompatSet.add(chainSig);
5468                }
5469            } catch (CertificateEncodingException e) {
5470                scannedCompatSet.add(sig);
5471            }
5472        }
5473        /*
5474         * Make sure the expanded scanned set contains all signatures in the
5475         * existing one.
5476         */
5477        if (scannedCompatSet.equals(existingSet)) {
5478            // Migrate the old signatures to the new scheme.
5479            existingSigs.assignSignatures(scannedPkg.mSignatures);
5480            // The new KeySets will be re-added later in the scanning process.
5481            synchronized (mPackages) {
5482                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5483            }
5484            return PackageManager.SIGNATURE_MATCH;
5485        }
5486        return PackageManager.SIGNATURE_NO_MATCH;
5487    }
5488
5489    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5490        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5491        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5492    }
5493
5494    private int compareSignaturesRecover(PackageSignatures existingSigs,
5495            PackageParser.Package scannedPkg) {
5496        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5497            return PackageManager.SIGNATURE_NO_MATCH;
5498        }
5499
5500        String msg = null;
5501        try {
5502            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5503                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5504                        + scannedPkg.packageName);
5505                return PackageManager.SIGNATURE_MATCH;
5506            }
5507        } catch (CertificateException e) {
5508            msg = e.getMessage();
5509        }
5510
5511        logCriticalInfo(Log.INFO,
5512                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5513        return PackageManager.SIGNATURE_NO_MATCH;
5514    }
5515
5516    @Override
5517    public List<String> getAllPackages() {
5518        synchronized (mPackages) {
5519            return new ArrayList<String>(mPackages.keySet());
5520        }
5521    }
5522
5523    @Override
5524    public String[] getPackagesForUid(int uid) {
5525        final int userId = UserHandle.getUserId(uid);
5526        uid = UserHandle.getAppId(uid);
5527        // reader
5528        synchronized (mPackages) {
5529            Object obj = mSettings.getUserIdLPr(uid);
5530            if (obj instanceof SharedUserSetting) {
5531                final SharedUserSetting sus = (SharedUserSetting) obj;
5532                final int N = sus.packages.size();
5533                String[] res = new String[N];
5534                final Iterator<PackageSetting> it = sus.packages.iterator();
5535                int i = 0;
5536                while (it.hasNext()) {
5537                    PackageSetting ps = it.next();
5538                    if (ps.getInstalled(userId)) {
5539                        res[i++] = ps.name;
5540                    } else {
5541                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5542                    }
5543                }
5544                return res;
5545            } else if (obj instanceof PackageSetting) {
5546                final PackageSetting ps = (PackageSetting) obj;
5547                if (ps.getInstalled(userId)) {
5548                    return new String[]{ps.name};
5549                }
5550            }
5551        }
5552        return null;
5553    }
5554
5555    @Override
5556    public String getNameForUid(int uid) {
5557        // reader
5558        synchronized (mPackages) {
5559            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5560            if (obj instanceof SharedUserSetting) {
5561                final SharedUserSetting sus = (SharedUserSetting) obj;
5562                return sus.name + ":" + sus.userId;
5563            } else if (obj instanceof PackageSetting) {
5564                final PackageSetting ps = (PackageSetting) obj;
5565                return ps.name;
5566            }
5567        }
5568        return null;
5569    }
5570
5571    @Override
5572    public int getUidForSharedUser(String sharedUserName) {
5573        if(sharedUserName == null) {
5574            return -1;
5575        }
5576        // reader
5577        synchronized (mPackages) {
5578            SharedUserSetting suid;
5579            try {
5580                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5581                if (suid != null) {
5582                    return suid.userId;
5583                }
5584            } catch (PackageManagerException ignore) {
5585                // can't happen, but, still need to catch it
5586            }
5587            return -1;
5588        }
5589    }
5590
5591    @Override
5592    public int getFlagsForUid(int uid) {
5593        synchronized (mPackages) {
5594            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5595            if (obj instanceof SharedUserSetting) {
5596                final SharedUserSetting sus = (SharedUserSetting) obj;
5597                return sus.pkgFlags;
5598            } else if (obj instanceof PackageSetting) {
5599                final PackageSetting ps = (PackageSetting) obj;
5600                return ps.pkgFlags;
5601            }
5602        }
5603        return 0;
5604    }
5605
5606    @Override
5607    public int getPrivateFlagsForUid(int uid) {
5608        synchronized (mPackages) {
5609            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5610            if (obj instanceof SharedUserSetting) {
5611                final SharedUserSetting sus = (SharedUserSetting) obj;
5612                return sus.pkgPrivateFlags;
5613            } else if (obj instanceof PackageSetting) {
5614                final PackageSetting ps = (PackageSetting) obj;
5615                return ps.pkgPrivateFlags;
5616            }
5617        }
5618        return 0;
5619    }
5620
5621    @Override
5622    public boolean isUidPrivileged(int uid) {
5623        uid = UserHandle.getAppId(uid);
5624        // reader
5625        synchronized (mPackages) {
5626            Object obj = mSettings.getUserIdLPr(uid);
5627            if (obj instanceof SharedUserSetting) {
5628                final SharedUserSetting sus = (SharedUserSetting) obj;
5629                final Iterator<PackageSetting> it = sus.packages.iterator();
5630                while (it.hasNext()) {
5631                    if (it.next().isPrivileged()) {
5632                        return true;
5633                    }
5634                }
5635            } else if (obj instanceof PackageSetting) {
5636                final PackageSetting ps = (PackageSetting) obj;
5637                return ps.isPrivileged();
5638            }
5639        }
5640        return false;
5641    }
5642
5643    @Override
5644    public String[] getAppOpPermissionPackages(String permissionName) {
5645        synchronized (mPackages) {
5646            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5647            if (pkgs == null) {
5648                return null;
5649            }
5650            return pkgs.toArray(new String[pkgs.size()]);
5651        }
5652    }
5653
5654    @Override
5655    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5656            int flags, int userId) {
5657        return resolveIntentInternal(
5658                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5659    }
5660
5661    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5662            int flags, int userId, boolean includeInstantApps) {
5663        try {
5664            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5665
5666            if (!sUserManager.exists(userId)) return null;
5667            final int callingUid = Binder.getCallingUid();
5668            flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
5669            enforceCrossUserPermission(callingUid, userId,
5670                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5671
5672            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5673            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5674                    flags, userId, includeInstantApps);
5675            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5676
5677            final ResolveInfo bestChoice =
5678                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5679            return bestChoice;
5680        } finally {
5681            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5682        }
5683    }
5684
5685    @Override
5686    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5687        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5688            throw new SecurityException(
5689                    "findPersistentPreferredActivity can only be run by the system");
5690        }
5691        if (!sUserManager.exists(userId)) {
5692            return null;
5693        }
5694        final int callingUid = Binder.getCallingUid();
5695        intent = updateIntentForResolve(intent);
5696        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5697        final int flags = updateFlagsForResolve(
5698                0, userId, intent, callingUid, false /*includeInstantApps*/);
5699        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5700                userId);
5701        synchronized (mPackages) {
5702            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5703                    userId);
5704        }
5705    }
5706
5707    @Override
5708    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5709            IntentFilter filter, int match, ComponentName activity) {
5710        final int userId = UserHandle.getCallingUserId();
5711        if (DEBUG_PREFERRED) {
5712            Log.v(TAG, "setLastChosenActivity intent=" + intent
5713                + " resolvedType=" + resolvedType
5714                + " flags=" + flags
5715                + " filter=" + filter
5716                + " match=" + match
5717                + " activity=" + activity);
5718            filter.dump(new PrintStreamPrinter(System.out), "    ");
5719        }
5720        intent.setComponent(null);
5721        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5722                userId);
5723        // Find any earlier preferred or last chosen entries and nuke them
5724        findPreferredActivity(intent, resolvedType,
5725                flags, query, 0, false, true, false, userId);
5726        // Add the new activity as the last chosen for this filter
5727        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5728                "Setting last chosen");
5729    }
5730
5731    @Override
5732    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5733        final int userId = UserHandle.getCallingUserId();
5734        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5735        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5736                userId);
5737        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5738                false, false, false, userId);
5739    }
5740
5741    /**
5742     * Returns whether or not instant apps have been disabled remotely.
5743     */
5744    private boolean isEphemeralDisabled() {
5745        return mEphemeralAppsDisabled;
5746    }
5747
5748    private boolean isEphemeralAllowed(
5749            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5750            boolean skipPackageCheck) {
5751        final int callingUser = UserHandle.getCallingUserId();
5752        if (mInstantAppResolverConnection == null) {
5753            return false;
5754        }
5755        if (mInstantAppInstallerActivity == null) {
5756            return false;
5757        }
5758        if (intent.getComponent() != null) {
5759            return false;
5760        }
5761        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5762            return false;
5763        }
5764        if (!skipPackageCheck && intent.getPackage() != null) {
5765            return false;
5766        }
5767        final boolean isWebUri = hasWebURI(intent);
5768        if (!isWebUri || intent.getData().getHost() == null) {
5769            return false;
5770        }
5771        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5772        // Or if there's already an ephemeral app installed that handles the action
5773        synchronized (mPackages) {
5774            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5775            for (int n = 0; n < count; n++) {
5776                final ResolveInfo info = resolvedActivities.get(n);
5777                final String packageName = info.activityInfo.packageName;
5778                final PackageSetting ps = mSettings.mPackages.get(packageName);
5779                if (ps != null) {
5780                    // only check domain verification status if the app is not a browser
5781                    if (!info.handleAllWebDataURI) {
5782                        // Try to get the status from User settings first
5783                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5784                        final int status = (int) (packedStatus >> 32);
5785                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5786                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5787                            if (DEBUG_EPHEMERAL) {
5788                                Slog.v(TAG, "DENY instant app;"
5789                                    + " pkg: " + packageName + ", status: " + status);
5790                            }
5791                            return false;
5792                        }
5793                    }
5794                    if (ps.getInstantApp(userId)) {
5795                        if (DEBUG_EPHEMERAL) {
5796                            Slog.v(TAG, "DENY instant app installed;"
5797                                    + " pkg: " + packageName);
5798                        }
5799                        return false;
5800                    }
5801                }
5802            }
5803        }
5804        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5805        return true;
5806    }
5807
5808    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5809            Intent origIntent, String resolvedType, String callingPackage,
5810            int userId) {
5811        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5812                new InstantAppRequest(responseObj, origIntent, resolvedType,
5813                        callingPackage, userId));
5814        mHandler.sendMessage(msg);
5815    }
5816
5817    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5818            int flags, List<ResolveInfo> query, int userId) {
5819        if (query != null) {
5820            final int N = query.size();
5821            if (N == 1) {
5822                return query.get(0);
5823            } else if (N > 1) {
5824                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5825                // If there is more than one activity with the same priority,
5826                // then let the user decide between them.
5827                ResolveInfo r0 = query.get(0);
5828                ResolveInfo r1 = query.get(1);
5829                if (DEBUG_INTENT_MATCHING || debug) {
5830                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5831                            + r1.activityInfo.name + "=" + r1.priority);
5832                }
5833                // If the first activity has a higher priority, or a different
5834                // default, then it is always desirable to pick it.
5835                if (r0.priority != r1.priority
5836                        || r0.preferredOrder != r1.preferredOrder
5837                        || r0.isDefault != r1.isDefault) {
5838                    return query.get(0);
5839                }
5840                // If we have saved a preference for a preferred activity for
5841                // this Intent, use that.
5842                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5843                        flags, query, r0.priority, true, false, debug, userId);
5844                if (ri != null) {
5845                    return ri;
5846                }
5847                // If we have an ephemeral app, use it
5848                for (int i = 0; i < N; i++) {
5849                    ri = query.get(i);
5850                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5851                        return ri;
5852                    }
5853                }
5854                ri = new ResolveInfo(mResolveInfo);
5855                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5856                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5857                // If all of the options come from the same package, show the application's
5858                // label and icon instead of the generic resolver's.
5859                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5860                // and then throw away the ResolveInfo itself, meaning that the caller loses
5861                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5862                // a fallback for this case; we only set the target package's resources on
5863                // the ResolveInfo, not the ActivityInfo.
5864                final String intentPackage = intent.getPackage();
5865                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5866                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5867                    ri.resolvePackageName = intentPackage;
5868                    if (userNeedsBadging(userId)) {
5869                        ri.noResourceId = true;
5870                    } else {
5871                        ri.icon = appi.icon;
5872                    }
5873                    ri.iconResourceId = appi.icon;
5874                    ri.labelRes = appi.labelRes;
5875                }
5876                ri.activityInfo.applicationInfo = new ApplicationInfo(
5877                        ri.activityInfo.applicationInfo);
5878                if (userId != 0) {
5879                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5880                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5881                }
5882                // Make sure that the resolver is displayable in car mode
5883                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5884                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5885                return ri;
5886            }
5887        }
5888        return null;
5889    }
5890
5891    /**
5892     * Return true if the given list is not empty and all of its contents have
5893     * an activityInfo with the given package name.
5894     */
5895    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5896        if (ArrayUtils.isEmpty(list)) {
5897            return false;
5898        }
5899        for (int i = 0, N = list.size(); i < N; i++) {
5900            final ResolveInfo ri = list.get(i);
5901            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5902            if (ai == null || !packageName.equals(ai.packageName)) {
5903                return false;
5904            }
5905        }
5906        return true;
5907    }
5908
5909    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5910            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5911        final int N = query.size();
5912        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5913                .get(userId);
5914        // Get the list of persistent preferred activities that handle the intent
5915        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5916        List<PersistentPreferredActivity> pprefs = ppir != null
5917                ? ppir.queryIntent(intent, resolvedType,
5918                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5919                        userId)
5920                : null;
5921        if (pprefs != null && pprefs.size() > 0) {
5922            final int M = pprefs.size();
5923            for (int i=0; i<M; i++) {
5924                final PersistentPreferredActivity ppa = pprefs.get(i);
5925                if (DEBUG_PREFERRED || debug) {
5926                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5927                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5928                            + "\n  component=" + ppa.mComponent);
5929                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5930                }
5931                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5932                        flags | MATCH_DISABLED_COMPONENTS, userId);
5933                if (DEBUG_PREFERRED || debug) {
5934                    Slog.v(TAG, "Found persistent preferred activity:");
5935                    if (ai != null) {
5936                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5937                    } else {
5938                        Slog.v(TAG, "  null");
5939                    }
5940                }
5941                if (ai == null) {
5942                    // This previously registered persistent preferred activity
5943                    // component is no longer known. Ignore it and do NOT remove it.
5944                    continue;
5945                }
5946                for (int j=0; j<N; j++) {
5947                    final ResolveInfo ri = query.get(j);
5948                    if (!ri.activityInfo.applicationInfo.packageName
5949                            .equals(ai.applicationInfo.packageName)) {
5950                        continue;
5951                    }
5952                    if (!ri.activityInfo.name.equals(ai.name)) {
5953                        continue;
5954                    }
5955                    //  Found a persistent preference that can handle the intent.
5956                    if (DEBUG_PREFERRED || debug) {
5957                        Slog.v(TAG, "Returning persistent preferred activity: " +
5958                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5959                    }
5960                    return ri;
5961                }
5962            }
5963        }
5964        return null;
5965    }
5966
5967    // TODO: handle preferred activities missing while user has amnesia
5968    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5969            List<ResolveInfo> query, int priority, boolean always,
5970            boolean removeMatches, boolean debug, int userId) {
5971        if (!sUserManager.exists(userId)) return null;
5972        final int callingUid = Binder.getCallingUid();
5973        flags = updateFlagsForResolve(
5974                flags, userId, intent, callingUid, false /*includeInstantApps*/);
5975        intent = updateIntentForResolve(intent);
5976        // writer
5977        synchronized (mPackages) {
5978            // Try to find a matching persistent preferred activity.
5979            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5980                    debug, userId);
5981
5982            // If a persistent preferred activity matched, use it.
5983            if (pri != null) {
5984                return pri;
5985            }
5986
5987            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
5988            // Get the list of preferred activities that handle the intent
5989            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
5990            List<PreferredActivity> prefs = pir != null
5991                    ? pir.queryIntent(intent, resolvedType,
5992                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5993                            userId)
5994                    : null;
5995            if (prefs != null && prefs.size() > 0) {
5996                boolean changed = false;
5997                try {
5998                    // First figure out how good the original match set is.
5999                    // We will only allow preferred activities that came
6000                    // from the same match quality.
6001                    int match = 0;
6002
6003                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6004
6005                    final int N = query.size();
6006                    for (int j=0; j<N; j++) {
6007                        final ResolveInfo ri = query.get(j);
6008                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6009                                + ": 0x" + Integer.toHexString(match));
6010                        if (ri.match > match) {
6011                            match = ri.match;
6012                        }
6013                    }
6014
6015                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6016                            + Integer.toHexString(match));
6017
6018                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6019                    final int M = prefs.size();
6020                    for (int i=0; i<M; i++) {
6021                        final PreferredActivity pa = prefs.get(i);
6022                        if (DEBUG_PREFERRED || debug) {
6023                            Slog.v(TAG, "Checking PreferredActivity ds="
6024                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6025                                    + "\n  component=" + pa.mPref.mComponent);
6026                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6027                        }
6028                        if (pa.mPref.mMatch != match) {
6029                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6030                                    + Integer.toHexString(pa.mPref.mMatch));
6031                            continue;
6032                        }
6033                        // If it's not an "always" type preferred activity and that's what we're
6034                        // looking for, skip it.
6035                        if (always && !pa.mPref.mAlways) {
6036                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6037                            continue;
6038                        }
6039                        final ActivityInfo ai = getActivityInfo(
6040                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6041                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6042                                userId);
6043                        if (DEBUG_PREFERRED || debug) {
6044                            Slog.v(TAG, "Found preferred activity:");
6045                            if (ai != null) {
6046                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6047                            } else {
6048                                Slog.v(TAG, "  null");
6049                            }
6050                        }
6051                        if (ai == null) {
6052                            // This previously registered preferred activity
6053                            // component is no longer known.  Most likely an update
6054                            // to the app was installed and in the new version this
6055                            // component no longer exists.  Clean it up by removing
6056                            // it from the preferred activities list, and skip it.
6057                            Slog.w(TAG, "Removing dangling preferred activity: "
6058                                    + pa.mPref.mComponent);
6059                            pir.removeFilter(pa);
6060                            changed = true;
6061                            continue;
6062                        }
6063                        for (int j=0; j<N; j++) {
6064                            final ResolveInfo ri = query.get(j);
6065                            if (!ri.activityInfo.applicationInfo.packageName
6066                                    .equals(ai.applicationInfo.packageName)) {
6067                                continue;
6068                            }
6069                            if (!ri.activityInfo.name.equals(ai.name)) {
6070                                continue;
6071                            }
6072
6073                            if (removeMatches) {
6074                                pir.removeFilter(pa);
6075                                changed = true;
6076                                if (DEBUG_PREFERRED) {
6077                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6078                                }
6079                                break;
6080                            }
6081
6082                            // Okay we found a previously set preferred or last chosen app.
6083                            // If the result set is different from when this
6084                            // was created, we need to clear it and re-ask the
6085                            // user their preference, if we're looking for an "always" type entry.
6086                            if (always && !pa.mPref.sameSet(query)) {
6087                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6088                                        + intent + " type " + resolvedType);
6089                                if (DEBUG_PREFERRED) {
6090                                    Slog.v(TAG, "Removing preferred activity since set changed "
6091                                            + pa.mPref.mComponent);
6092                                }
6093                                pir.removeFilter(pa);
6094                                // Re-add the filter as a "last chosen" entry (!always)
6095                                PreferredActivity lastChosen = new PreferredActivity(
6096                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6097                                pir.addFilter(lastChosen);
6098                                changed = true;
6099                                return null;
6100                            }
6101
6102                            // Yay! Either the set matched or we're looking for the last chosen
6103                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6104                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6105                            return ri;
6106                        }
6107                    }
6108                } finally {
6109                    if (changed) {
6110                        if (DEBUG_PREFERRED) {
6111                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6112                        }
6113                        scheduleWritePackageRestrictionsLocked(userId);
6114                    }
6115                }
6116            }
6117        }
6118        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6119        return null;
6120    }
6121
6122    /*
6123     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6124     */
6125    @Override
6126    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6127            int targetUserId) {
6128        mContext.enforceCallingOrSelfPermission(
6129                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6130        List<CrossProfileIntentFilter> matches =
6131                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6132        if (matches != null) {
6133            int size = matches.size();
6134            for (int i = 0; i < size; i++) {
6135                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6136            }
6137        }
6138        if (hasWebURI(intent)) {
6139            // cross-profile app linking works only towards the parent.
6140            final int callingUid = Binder.getCallingUid();
6141            final UserInfo parent = getProfileParent(sourceUserId);
6142            synchronized(mPackages) {
6143                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6144                        false /*includeInstantApps*/);
6145                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6146                        intent, resolvedType, flags, sourceUserId, parent.id);
6147                return xpDomainInfo != null;
6148            }
6149        }
6150        return false;
6151    }
6152
6153    private UserInfo getProfileParent(int userId) {
6154        final long identity = Binder.clearCallingIdentity();
6155        try {
6156            return sUserManager.getProfileParent(userId);
6157        } finally {
6158            Binder.restoreCallingIdentity(identity);
6159        }
6160    }
6161
6162    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6163            String resolvedType, int userId) {
6164        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6165        if (resolver != null) {
6166            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6167        }
6168        return null;
6169    }
6170
6171    @Override
6172    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6173            String resolvedType, int flags, int userId) {
6174        try {
6175            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6176
6177            return new ParceledListSlice<>(
6178                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6179        } finally {
6180            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6181        }
6182    }
6183
6184    /**
6185     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6186     * instant, returns {@code null}.
6187     */
6188    private String getInstantAppPackageName(int callingUid) {
6189        // If the caller is an isolated app use the owner's uid for the lookup.
6190        if (Process.isIsolated(callingUid)) {
6191            callingUid = mIsolatedOwners.get(callingUid);
6192        }
6193        final int appId = UserHandle.getAppId(callingUid);
6194        synchronized (mPackages) {
6195            final Object obj = mSettings.getUserIdLPr(appId);
6196            if (obj instanceof PackageSetting) {
6197                final PackageSetting ps = (PackageSetting) obj;
6198                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6199                return isInstantApp ? ps.pkg.packageName : null;
6200            }
6201        }
6202        return null;
6203    }
6204
6205    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6206            String resolvedType, int flags, int userId) {
6207        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6208    }
6209
6210    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6211            String resolvedType, int flags, int userId, boolean includeInstantApps) {
6212        if (!sUserManager.exists(userId)) return Collections.emptyList();
6213        final int callingUid = Binder.getCallingUid();
6214        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6215        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
6216        enforceCrossUserPermission(callingUid, userId,
6217                false /* requireFullPermission */, false /* checkShell */,
6218                "query intent activities");
6219        ComponentName comp = intent.getComponent();
6220        if (comp == null) {
6221            if (intent.getSelector() != null) {
6222                intent = intent.getSelector();
6223                comp = intent.getComponent();
6224            }
6225        }
6226
6227        if (comp != null) {
6228            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6229            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6230            if (ai != null) {
6231                // When specifying an explicit component, we prevent the activity from being
6232                // used when either 1) the calling package is normal and the activity is within
6233                // an ephemeral application or 2) the calling package is ephemeral and the
6234                // activity is not visible to ephemeral applications.
6235                final boolean matchInstantApp =
6236                        (flags & PackageManager.MATCH_INSTANT) != 0;
6237                final boolean matchVisibleToInstantAppOnly =
6238                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6239                final boolean isCallerInstantApp =
6240                        instantAppPkgName != null;
6241                final boolean isTargetSameInstantApp =
6242                        comp.getPackageName().equals(instantAppPkgName);
6243                final boolean isTargetInstantApp =
6244                        (ai.applicationInfo.privateFlags
6245                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6246                final boolean isTargetHiddenFromInstantApp =
6247                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
6248                final boolean blockResolution =
6249                        !isTargetSameInstantApp
6250                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6251                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6252                                        && isTargetHiddenFromInstantApp));
6253                if (!blockResolution) {
6254                    final ResolveInfo ri = new ResolveInfo();
6255                    ri.activityInfo = ai;
6256                    list.add(ri);
6257                }
6258            }
6259            return applyPostResolutionFilter(list, instantAppPkgName);
6260        }
6261
6262        // reader
6263        boolean sortResult = false;
6264        boolean addEphemeral = false;
6265        List<ResolveInfo> result;
6266        final String pkgName = intent.getPackage();
6267        final boolean ephemeralDisabled = isEphemeralDisabled();
6268        synchronized (mPackages) {
6269            if (pkgName == null) {
6270                List<CrossProfileIntentFilter> matchingFilters =
6271                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6272                // Check for results that need to skip the current profile.
6273                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6274                        resolvedType, flags, userId);
6275                if (xpResolveInfo != null) {
6276                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6277                    xpResult.add(xpResolveInfo);
6278                    return applyPostResolutionFilter(
6279                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6280                }
6281
6282                // Check for results in the current profile.
6283                result = filterIfNotSystemUser(mActivities.queryIntent(
6284                        intent, resolvedType, flags, userId), userId);
6285                addEphemeral = !ephemeralDisabled
6286                        && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
6287                // Check for cross profile results.
6288                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6289                xpResolveInfo = queryCrossProfileIntents(
6290                        matchingFilters, intent, resolvedType, flags, userId,
6291                        hasNonNegativePriorityResult);
6292                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6293                    boolean isVisibleToUser = filterIfNotSystemUser(
6294                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6295                    if (isVisibleToUser) {
6296                        result.add(xpResolveInfo);
6297                        sortResult = true;
6298                    }
6299                }
6300                if (hasWebURI(intent)) {
6301                    CrossProfileDomainInfo xpDomainInfo = null;
6302                    final UserInfo parent = getProfileParent(userId);
6303                    if (parent != null) {
6304                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6305                                flags, userId, parent.id);
6306                    }
6307                    if (xpDomainInfo != null) {
6308                        if (xpResolveInfo != null) {
6309                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6310                            // in the result.
6311                            result.remove(xpResolveInfo);
6312                        }
6313                        if (result.size() == 0 && !addEphemeral) {
6314                            // No result in current profile, but found candidate in parent user.
6315                            // And we are not going to add emphemeral app, so we can return the
6316                            // result straight away.
6317                            result.add(xpDomainInfo.resolveInfo);
6318                            return applyPostResolutionFilter(result, instantAppPkgName);
6319                        }
6320                    } else if (result.size() <= 1 && !addEphemeral) {
6321                        // No result in parent user and <= 1 result in current profile, and we
6322                        // are not going to add emphemeral app, so we can return the result without
6323                        // further processing.
6324                        return applyPostResolutionFilter(result, instantAppPkgName);
6325                    }
6326                    // We have more than one candidate (combining results from current and parent
6327                    // profile), so we need filtering and sorting.
6328                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6329                            intent, flags, result, xpDomainInfo, userId);
6330                    sortResult = true;
6331                }
6332            } else {
6333                final PackageParser.Package pkg = mPackages.get(pkgName);
6334                if (pkg != null) {
6335                    return applyPostResolutionFilter(filterIfNotSystemUser(
6336                            mActivities.queryIntentForPackage(
6337                                    intent, resolvedType, flags, pkg.activities, userId),
6338                            userId), instantAppPkgName);
6339                } else {
6340                    // the caller wants to resolve for a particular package; however, there
6341                    // were no installed results, so, try to find an ephemeral result
6342                    addEphemeral = !ephemeralDisabled
6343                            && isEphemeralAllowed(
6344                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6345                    result = new ArrayList<ResolveInfo>();
6346                }
6347            }
6348        }
6349        if (addEphemeral) {
6350            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6351            final InstantAppRequest requestObject = new InstantAppRequest(
6352                    null /*responseObj*/, intent /*origIntent*/, resolvedType,
6353                    null /*callingPackage*/, userId);
6354            final AuxiliaryResolveInfo auxiliaryResponse =
6355                    InstantAppResolver.doInstantAppResolutionPhaseOne(
6356                            mContext, mInstantAppResolverConnection, requestObject);
6357            if (auxiliaryResponse != null) {
6358                if (DEBUG_EPHEMERAL) {
6359                    Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6360                }
6361                final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6362                final PackageSetting ps =
6363                        mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6364                if (ps != null) {
6365                    ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6366                            mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6367                    ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6368                    ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6369                    // make sure this resolver is the default
6370                    ephemeralInstaller.isDefault = true;
6371                    ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6372                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6373                    // add a non-generic filter
6374                    ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6375                    ephemeralInstaller.filter.addDataPath(
6376                            intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6377                    ephemeralInstaller.instantAppAvailable = true;
6378                    result.add(ephemeralInstaller);
6379                }
6380            }
6381            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6382        }
6383        if (sortResult) {
6384            Collections.sort(result, mResolvePrioritySorter);
6385        }
6386        return applyPostResolutionFilter(result, instantAppPkgName);
6387    }
6388
6389    private static class CrossProfileDomainInfo {
6390        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6391        ResolveInfo resolveInfo;
6392        /* Best domain verification status of the activities found in the other profile */
6393        int bestDomainVerificationStatus;
6394    }
6395
6396    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6397            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6398        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6399                sourceUserId)) {
6400            return null;
6401        }
6402        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6403                resolvedType, flags, parentUserId);
6404
6405        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6406            return null;
6407        }
6408        CrossProfileDomainInfo result = null;
6409        int size = resultTargetUser.size();
6410        for (int i = 0; i < size; i++) {
6411            ResolveInfo riTargetUser = resultTargetUser.get(i);
6412            // Intent filter verification is only for filters that specify a host. So don't return
6413            // those that handle all web uris.
6414            if (riTargetUser.handleAllWebDataURI) {
6415                continue;
6416            }
6417            String packageName = riTargetUser.activityInfo.packageName;
6418            PackageSetting ps = mSettings.mPackages.get(packageName);
6419            if (ps == null) {
6420                continue;
6421            }
6422            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6423            int status = (int)(verificationState >> 32);
6424            if (result == null) {
6425                result = new CrossProfileDomainInfo();
6426                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6427                        sourceUserId, parentUserId);
6428                result.bestDomainVerificationStatus = status;
6429            } else {
6430                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6431                        result.bestDomainVerificationStatus);
6432            }
6433        }
6434        // Don't consider matches with status NEVER across profiles.
6435        if (result != null && result.bestDomainVerificationStatus
6436                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6437            return null;
6438        }
6439        return result;
6440    }
6441
6442    /**
6443     * Verification statuses are ordered from the worse to the best, except for
6444     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6445     */
6446    private int bestDomainVerificationStatus(int status1, int status2) {
6447        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6448            return status2;
6449        }
6450        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6451            return status1;
6452        }
6453        return (int) MathUtils.max(status1, status2);
6454    }
6455
6456    private boolean isUserEnabled(int userId) {
6457        long callingId = Binder.clearCallingIdentity();
6458        try {
6459            UserInfo userInfo = sUserManager.getUserInfo(userId);
6460            return userInfo != null && userInfo.isEnabled();
6461        } finally {
6462            Binder.restoreCallingIdentity(callingId);
6463        }
6464    }
6465
6466    /**
6467     * Filter out activities with systemUserOnly flag set, when current user is not System.
6468     *
6469     * @return filtered list
6470     */
6471    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6472        if (userId == UserHandle.USER_SYSTEM) {
6473            return resolveInfos;
6474        }
6475        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6476            ResolveInfo info = resolveInfos.get(i);
6477            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6478                resolveInfos.remove(i);
6479            }
6480        }
6481        return resolveInfos;
6482    }
6483
6484    /**
6485     * Filters out ephemeral activities.
6486     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6487     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6488     *
6489     * @param resolveInfos The pre-filtered list of resolved activities
6490     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6491     *          is performed.
6492     * @return A filtered list of resolved activities.
6493     */
6494    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6495            String ephemeralPkgName) {
6496        // TODO: When adding on-demand split support for non-instant apps, remove this check
6497        // and always apply post filtering
6498        if (ephemeralPkgName == null) {
6499            return resolveInfos;
6500        }
6501        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6502            final ResolveInfo info = resolveInfos.get(i);
6503            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6504            // allow activities that are defined in the provided package
6505            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6506                if (info.activityInfo.splitName != null
6507                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6508                                info.activityInfo.splitName)) {
6509                    // requested activity is defined in a split that hasn't been installed yet.
6510                    // add the installer to the resolve list
6511                    if (DEBUG_EPHEMERAL) {
6512                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6513                    }
6514                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6515                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6516                            info.activityInfo.packageName, info.activityInfo.splitName,
6517                            info.activityInfo.applicationInfo.versionCode);
6518                    // make sure this resolver is the default
6519                    installerInfo.isDefault = true;
6520                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6521                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6522                    // add a non-generic filter
6523                    installerInfo.filter = new IntentFilter();
6524                    // load resources from the correct package
6525                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6526                    resolveInfos.set(i, installerInfo);
6527                }
6528                continue;
6529            }
6530            // allow activities that have been explicitly exposed to ephemeral apps
6531            if (!isEphemeralApp
6532                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
6533                continue;
6534            }
6535            resolveInfos.remove(i);
6536        }
6537        return resolveInfos;
6538    }
6539
6540    /**
6541     * @param resolveInfos list of resolve infos in descending priority order
6542     * @return if the list contains a resolve info with non-negative priority
6543     */
6544    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6545        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6546    }
6547
6548    private static boolean hasWebURI(Intent intent) {
6549        if (intent.getData() == null) {
6550            return false;
6551        }
6552        final String scheme = intent.getScheme();
6553        if (TextUtils.isEmpty(scheme)) {
6554            return false;
6555        }
6556        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6557    }
6558
6559    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6560            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6561            int userId) {
6562        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6563
6564        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6565            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6566                    candidates.size());
6567        }
6568
6569        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6570        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6571        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6572        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6573        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6574        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6575
6576        synchronized (mPackages) {
6577            final int count = candidates.size();
6578            // First, try to use linked apps. Partition the candidates into four lists:
6579            // one for the final results, one for the "do not use ever", one for "undefined status"
6580            // and finally one for "browser app type".
6581            for (int n=0; n<count; n++) {
6582                ResolveInfo info = candidates.get(n);
6583                String packageName = info.activityInfo.packageName;
6584                PackageSetting ps = mSettings.mPackages.get(packageName);
6585                if (ps != null) {
6586                    // Add to the special match all list (Browser use case)
6587                    if (info.handleAllWebDataURI) {
6588                        matchAllList.add(info);
6589                        continue;
6590                    }
6591                    // Try to get the status from User settings first
6592                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6593                    int status = (int)(packedStatus >> 32);
6594                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6595                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6596                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6597                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6598                                    + " : linkgen=" + linkGeneration);
6599                        }
6600                        // Use link-enabled generation as preferredOrder, i.e.
6601                        // prefer newly-enabled over earlier-enabled.
6602                        info.preferredOrder = linkGeneration;
6603                        alwaysList.add(info);
6604                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6605                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6606                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6607                        }
6608                        neverList.add(info);
6609                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6610                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6611                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6612                        }
6613                        alwaysAskList.add(info);
6614                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6615                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6616                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6617                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6618                        }
6619                        undefinedList.add(info);
6620                    }
6621                }
6622            }
6623
6624            // We'll want to include browser possibilities in a few cases
6625            boolean includeBrowser = false;
6626
6627            // First try to add the "always" resolution(s) for the current user, if any
6628            if (alwaysList.size() > 0) {
6629                result.addAll(alwaysList);
6630            } else {
6631                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6632                result.addAll(undefinedList);
6633                // Maybe add one for the other profile.
6634                if (xpDomainInfo != null && (
6635                        xpDomainInfo.bestDomainVerificationStatus
6636                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6637                    result.add(xpDomainInfo.resolveInfo);
6638                }
6639                includeBrowser = true;
6640            }
6641
6642            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6643            // If there were 'always' entries their preferred order has been set, so we also
6644            // back that off to make the alternatives equivalent
6645            if (alwaysAskList.size() > 0) {
6646                for (ResolveInfo i : result) {
6647                    i.preferredOrder = 0;
6648                }
6649                result.addAll(alwaysAskList);
6650                includeBrowser = true;
6651            }
6652
6653            if (includeBrowser) {
6654                // Also add browsers (all of them or only the default one)
6655                if (DEBUG_DOMAIN_VERIFICATION) {
6656                    Slog.v(TAG, "   ...including browsers in candidate set");
6657                }
6658                if ((matchFlags & MATCH_ALL) != 0) {
6659                    result.addAll(matchAllList);
6660                } else {
6661                    // Browser/generic handling case.  If there's a default browser, go straight
6662                    // to that (but only if there is no other higher-priority match).
6663                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6664                    int maxMatchPrio = 0;
6665                    ResolveInfo defaultBrowserMatch = null;
6666                    final int numCandidates = matchAllList.size();
6667                    for (int n = 0; n < numCandidates; n++) {
6668                        ResolveInfo info = matchAllList.get(n);
6669                        // track the highest overall match priority...
6670                        if (info.priority > maxMatchPrio) {
6671                            maxMatchPrio = info.priority;
6672                        }
6673                        // ...and the highest-priority default browser match
6674                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6675                            if (defaultBrowserMatch == null
6676                                    || (defaultBrowserMatch.priority < info.priority)) {
6677                                if (debug) {
6678                                    Slog.v(TAG, "Considering default browser match " + info);
6679                                }
6680                                defaultBrowserMatch = info;
6681                            }
6682                        }
6683                    }
6684                    if (defaultBrowserMatch != null
6685                            && defaultBrowserMatch.priority >= maxMatchPrio
6686                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6687                    {
6688                        if (debug) {
6689                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6690                        }
6691                        result.add(defaultBrowserMatch);
6692                    } else {
6693                        result.addAll(matchAllList);
6694                    }
6695                }
6696
6697                // If there is nothing selected, add all candidates and remove the ones that the user
6698                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6699                if (result.size() == 0) {
6700                    result.addAll(candidates);
6701                    result.removeAll(neverList);
6702                }
6703            }
6704        }
6705        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6706            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6707                    result.size());
6708            for (ResolveInfo info : result) {
6709                Slog.v(TAG, "  + " + info.activityInfo);
6710            }
6711        }
6712        return result;
6713    }
6714
6715    // Returns a packed value as a long:
6716    //
6717    // high 'int'-sized word: link status: undefined/ask/never/always.
6718    // low 'int'-sized word: relative priority among 'always' results.
6719    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6720        long result = ps.getDomainVerificationStatusForUser(userId);
6721        // if none available, get the master status
6722        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6723            if (ps.getIntentFilterVerificationInfo() != null) {
6724                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6725            }
6726        }
6727        return result;
6728    }
6729
6730    private ResolveInfo querySkipCurrentProfileIntents(
6731            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6732            int flags, int sourceUserId) {
6733        if (matchingFilters != null) {
6734            int size = matchingFilters.size();
6735            for (int i = 0; i < size; i ++) {
6736                CrossProfileIntentFilter filter = matchingFilters.get(i);
6737                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6738                    // Checking if there are activities in the target user that can handle the
6739                    // intent.
6740                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6741                            resolvedType, flags, sourceUserId);
6742                    if (resolveInfo != null) {
6743                        return resolveInfo;
6744                    }
6745                }
6746            }
6747        }
6748        return null;
6749    }
6750
6751    // Return matching ResolveInfo in target user if any.
6752    private ResolveInfo queryCrossProfileIntents(
6753            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6754            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6755        if (matchingFilters != null) {
6756            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6757            // match the same intent. For performance reasons, it is better not to
6758            // run queryIntent twice for the same userId
6759            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6760            int size = matchingFilters.size();
6761            for (int i = 0; i < size; i++) {
6762                CrossProfileIntentFilter filter = matchingFilters.get(i);
6763                int targetUserId = filter.getTargetUserId();
6764                boolean skipCurrentProfile =
6765                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6766                boolean skipCurrentProfileIfNoMatchFound =
6767                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6768                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6769                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
6770                    // Checking if there are activities in the target user that can handle the
6771                    // intent.
6772                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6773                            resolvedType, flags, sourceUserId);
6774                    if (resolveInfo != null) return resolveInfo;
6775                    alreadyTriedUserIds.put(targetUserId, true);
6776                }
6777            }
6778        }
6779        return null;
6780    }
6781
6782    /**
6783     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6784     * will forward the intent to the filter's target user.
6785     * Otherwise, returns null.
6786     */
6787    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6788            String resolvedType, int flags, int sourceUserId) {
6789        int targetUserId = filter.getTargetUserId();
6790        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6791                resolvedType, flags, targetUserId);
6792        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6793            // If all the matches in the target profile are suspended, return null.
6794            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6795                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6796                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6797                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6798                            targetUserId);
6799                }
6800            }
6801        }
6802        return null;
6803    }
6804
6805    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6806            int sourceUserId, int targetUserId) {
6807        ResolveInfo forwardingResolveInfo = new ResolveInfo();
6808        long ident = Binder.clearCallingIdentity();
6809        boolean targetIsProfile;
6810        try {
6811            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6812        } finally {
6813            Binder.restoreCallingIdentity(ident);
6814        }
6815        String className;
6816        if (targetIsProfile) {
6817            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6818        } else {
6819            className = FORWARD_INTENT_TO_PARENT;
6820        }
6821        ComponentName forwardingActivityComponentName = new ComponentName(
6822                mAndroidApplication.packageName, className);
6823        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6824                sourceUserId);
6825        if (!targetIsProfile) {
6826            forwardingActivityInfo.showUserIcon = targetUserId;
6827            forwardingResolveInfo.noResourceId = true;
6828        }
6829        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6830        forwardingResolveInfo.priority = 0;
6831        forwardingResolveInfo.preferredOrder = 0;
6832        forwardingResolveInfo.match = 0;
6833        forwardingResolveInfo.isDefault = true;
6834        forwardingResolveInfo.filter = filter;
6835        forwardingResolveInfo.targetUserId = targetUserId;
6836        return forwardingResolveInfo;
6837    }
6838
6839    @Override
6840    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
6841            Intent[] specifics, String[] specificTypes, Intent intent,
6842            String resolvedType, int flags, int userId) {
6843        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
6844                specificTypes, intent, resolvedType, flags, userId));
6845    }
6846
6847    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
6848            Intent[] specifics, String[] specificTypes, Intent intent,
6849            String resolvedType, int flags, int userId) {
6850        if (!sUserManager.exists(userId)) return Collections.emptyList();
6851        final int callingUid = Binder.getCallingUid();
6852        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
6853                false /*includeInstantApps*/);
6854        enforceCrossUserPermission(callingUid, userId,
6855                false /*requireFullPermission*/, false /*checkShell*/,
6856                "query intent activity options");
6857        final String resultsAction = intent.getAction();
6858
6859        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
6860                | PackageManager.GET_RESOLVED_FILTER, userId);
6861
6862        if (DEBUG_INTENT_MATCHING) {
6863            Log.v(TAG, "Query " + intent + ": " + results);
6864        }
6865
6866        int specificsPos = 0;
6867        int N;
6868
6869        // todo: note that the algorithm used here is O(N^2).  This
6870        // isn't a problem in our current environment, but if we start running
6871        // into situations where we have more than 5 or 10 matches then this
6872        // should probably be changed to something smarter...
6873
6874        // First we go through and resolve each of the specific items
6875        // that were supplied, taking care of removing any corresponding
6876        // duplicate items in the generic resolve list.
6877        if (specifics != null) {
6878            for (int i=0; i<specifics.length; i++) {
6879                final Intent sintent = specifics[i];
6880                if (sintent == null) {
6881                    continue;
6882                }
6883
6884                if (DEBUG_INTENT_MATCHING) {
6885                    Log.v(TAG, "Specific #" + i + ": " + sintent);
6886                }
6887
6888                String action = sintent.getAction();
6889                if (resultsAction != null && resultsAction.equals(action)) {
6890                    // If this action was explicitly requested, then don't
6891                    // remove things that have it.
6892                    action = null;
6893                }
6894
6895                ResolveInfo ri = null;
6896                ActivityInfo ai = null;
6897
6898                ComponentName comp = sintent.getComponent();
6899                if (comp == null) {
6900                    ri = resolveIntent(
6901                        sintent,
6902                        specificTypes != null ? specificTypes[i] : null,
6903                            flags, userId);
6904                    if (ri == null) {
6905                        continue;
6906                    }
6907                    if (ri == mResolveInfo) {
6908                        // ACK!  Must do something better with this.
6909                    }
6910                    ai = ri.activityInfo;
6911                    comp = new ComponentName(ai.applicationInfo.packageName,
6912                            ai.name);
6913                } else {
6914                    ai = getActivityInfo(comp, flags, userId);
6915                    if (ai == null) {
6916                        continue;
6917                    }
6918                }
6919
6920                // Look for any generic query activities that are duplicates
6921                // of this specific one, and remove them from the results.
6922                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
6923                N = results.size();
6924                int j;
6925                for (j=specificsPos; j<N; j++) {
6926                    ResolveInfo sri = results.get(j);
6927                    if ((sri.activityInfo.name.equals(comp.getClassName())
6928                            && sri.activityInfo.applicationInfo.packageName.equals(
6929                                    comp.getPackageName()))
6930                        || (action != null && sri.filter.matchAction(action))) {
6931                        results.remove(j);
6932                        if (DEBUG_INTENT_MATCHING) Log.v(
6933                            TAG, "Removing duplicate item from " + j
6934                            + " due to specific " + specificsPos);
6935                        if (ri == null) {
6936                            ri = sri;
6937                        }
6938                        j--;
6939                        N--;
6940                    }
6941                }
6942
6943                // Add this specific item to its proper place.
6944                if (ri == null) {
6945                    ri = new ResolveInfo();
6946                    ri.activityInfo = ai;
6947                }
6948                results.add(specificsPos, ri);
6949                ri.specificIndex = i;
6950                specificsPos++;
6951            }
6952        }
6953
6954        // Now we go through the remaining generic results and remove any
6955        // duplicate actions that are found here.
6956        N = results.size();
6957        for (int i=specificsPos; i<N-1; i++) {
6958            final ResolveInfo rii = results.get(i);
6959            if (rii.filter == null) {
6960                continue;
6961            }
6962
6963            // Iterate over all of the actions of this result's intent
6964            // filter...  typically this should be just one.
6965            final Iterator<String> it = rii.filter.actionsIterator();
6966            if (it == null) {
6967                continue;
6968            }
6969            while (it.hasNext()) {
6970                final String action = it.next();
6971                if (resultsAction != null && resultsAction.equals(action)) {
6972                    // If this action was explicitly requested, then don't
6973                    // remove things that have it.
6974                    continue;
6975                }
6976                for (int j=i+1; j<N; j++) {
6977                    final ResolveInfo rij = results.get(j);
6978                    if (rij.filter != null && rij.filter.hasAction(action)) {
6979                        results.remove(j);
6980                        if (DEBUG_INTENT_MATCHING) Log.v(
6981                            TAG, "Removing duplicate item from " + j
6982                            + " due to action " + action + " at " + i);
6983                        j--;
6984                        N--;
6985                    }
6986                }
6987            }
6988
6989            // If the caller didn't request filter information, drop it now
6990            // so we don't have to marshall/unmarshall it.
6991            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
6992                rii.filter = null;
6993            }
6994        }
6995
6996        // Filter out the caller activity if so requested.
6997        if (caller != null) {
6998            N = results.size();
6999            for (int i=0; i<N; i++) {
7000                ActivityInfo ainfo = results.get(i).activityInfo;
7001                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7002                        && caller.getClassName().equals(ainfo.name)) {
7003                    results.remove(i);
7004                    break;
7005                }
7006            }
7007        }
7008
7009        // If the caller didn't request filter information,
7010        // drop them now so we don't have to
7011        // marshall/unmarshall it.
7012        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7013            N = results.size();
7014            for (int i=0; i<N; i++) {
7015                results.get(i).filter = null;
7016            }
7017        }
7018
7019        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7020        return results;
7021    }
7022
7023    @Override
7024    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7025            String resolvedType, int flags, int userId) {
7026        return new ParceledListSlice<>(
7027                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7028    }
7029
7030    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7031            String resolvedType, int flags, int userId) {
7032        if (!sUserManager.exists(userId)) return Collections.emptyList();
7033        final int callingUid = Binder.getCallingUid();
7034        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7035                false /*includeInstantApps*/);
7036        ComponentName comp = intent.getComponent();
7037        if (comp == null) {
7038            if (intent.getSelector() != null) {
7039                intent = intent.getSelector();
7040                comp = intent.getComponent();
7041            }
7042        }
7043        if (comp != null) {
7044            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7045            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7046            if (ai != null) {
7047                ResolveInfo ri = new ResolveInfo();
7048                ri.activityInfo = ai;
7049                list.add(ri);
7050            }
7051            return list;
7052        }
7053
7054        // reader
7055        synchronized (mPackages) {
7056            String pkgName = intent.getPackage();
7057            if (pkgName == null) {
7058                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7059            }
7060            final PackageParser.Package pkg = mPackages.get(pkgName);
7061            if (pkg != null) {
7062                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7063                        userId);
7064            }
7065            return Collections.emptyList();
7066        }
7067    }
7068
7069    @Override
7070    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7071        final int callingUid = Binder.getCallingUid();
7072        return resolveServiceInternal(
7073                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7074    }
7075
7076    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7077            int userId, int callingUid, boolean includeInstantApps) {
7078        if (!sUserManager.exists(userId)) return null;
7079        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7080        List<ResolveInfo> query = queryIntentServicesInternal(
7081                intent, resolvedType, flags, userId, callingUid, includeInstantApps);
7082        if (query != null) {
7083            if (query.size() >= 1) {
7084                // If there is more than one service with the same priority,
7085                // just arbitrarily pick the first one.
7086                return query.get(0);
7087            }
7088        }
7089        return null;
7090    }
7091
7092    @Override
7093    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7094            String resolvedType, int flags, int userId) {
7095        final int callingUid = Binder.getCallingUid();
7096        return new ParceledListSlice<>(queryIntentServicesInternal(
7097                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7098    }
7099
7100    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7101            String resolvedType, int flags, int userId, int callingUid,
7102            boolean includeInstantApps) {
7103        if (!sUserManager.exists(userId)) return Collections.emptyList();
7104        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7105        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7106        ComponentName comp = intent.getComponent();
7107        if (comp == null) {
7108            if (intent.getSelector() != null) {
7109                intent = intent.getSelector();
7110                comp = intent.getComponent();
7111            }
7112        }
7113        if (comp != null) {
7114            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7115            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7116            if (si != null) {
7117                // When specifying an explicit component, we prevent the service from being
7118                // used when either 1) the service is in an instant application and the
7119                // caller is not the same instant application or 2) the calling package is
7120                // ephemeral and the 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 isCallerInstantApp =
7126                        instantAppPkgName != null;
7127                final boolean isTargetSameInstantApp =
7128                        comp.getPackageName().equals(instantAppPkgName);
7129                final boolean isTargetInstantApp =
7130                        (si.applicationInfo.privateFlags
7131                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7132                final boolean isTargetHiddenFromInstantApp =
7133                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7134                final boolean blockResolution =
7135                        !isTargetSameInstantApp
7136                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7137                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7138                                        && isTargetHiddenFromInstantApp));
7139                if (!blockResolution) {
7140                    final ResolveInfo ri = new ResolveInfo();
7141                    ri.serviceInfo = si;
7142                    list.add(ri);
7143                }
7144            }
7145            return list;
7146        }
7147
7148        // reader
7149        synchronized (mPackages) {
7150            String pkgName = intent.getPackage();
7151            if (pkgName == null) {
7152                return applyPostServiceResolutionFilter(
7153                        mServices.queryIntent(intent, resolvedType, flags, userId),
7154                        instantAppPkgName);
7155            }
7156            final PackageParser.Package pkg = mPackages.get(pkgName);
7157            if (pkg != null) {
7158                return applyPostServiceResolutionFilter(
7159                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7160                                userId),
7161                        instantAppPkgName);
7162            }
7163            return Collections.emptyList();
7164        }
7165    }
7166
7167    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7168            String instantAppPkgName) {
7169        // TODO: When adding on-demand split support for non-instant apps, remove this check
7170        // and always apply post filtering
7171        if (instantAppPkgName == null) {
7172            return resolveInfos;
7173        }
7174        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7175            final ResolveInfo info = resolveInfos.get(i);
7176            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7177            // allow services that are defined in the provided package
7178            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7179                if (info.serviceInfo.splitName != null
7180                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7181                                info.serviceInfo.splitName)) {
7182                    // requested service is defined in a split that hasn't been installed yet.
7183                    // add the installer to the resolve list
7184                    if (DEBUG_EPHEMERAL) {
7185                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7186                    }
7187                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7188                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7189                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7190                            info.serviceInfo.applicationInfo.versionCode);
7191                    // make sure this resolver is the default
7192                    installerInfo.isDefault = true;
7193                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7194                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7195                    // add a non-generic filter
7196                    installerInfo.filter = new IntentFilter();
7197                    // load resources from the correct package
7198                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7199                    resolveInfos.set(i, installerInfo);
7200                }
7201                continue;
7202            }
7203            // allow services that have been explicitly exposed to ephemeral apps
7204            if (!isEphemeralApp
7205                    && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7206                continue;
7207            }
7208            resolveInfos.remove(i);
7209        }
7210        return resolveInfos;
7211    }
7212
7213    @Override
7214    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7215            String resolvedType, int flags, int userId) {
7216        return new ParceledListSlice<>(
7217                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7218    }
7219
7220    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7221            Intent intent, String resolvedType, int flags, int userId) {
7222        if (!sUserManager.exists(userId)) return Collections.emptyList();
7223        final int callingUid = Binder.getCallingUid();
7224        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7225        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7226                false /*includeInstantApps*/);
7227        ComponentName comp = intent.getComponent();
7228        if (comp == null) {
7229            if (intent.getSelector() != null) {
7230                intent = intent.getSelector();
7231                comp = intent.getComponent();
7232            }
7233        }
7234        if (comp != null) {
7235            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7236            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7237            if (pi != null) {
7238                // When specifying an explicit component, we prevent the provider from being
7239                // used when either 1) the provider is in an instant application and the
7240                // caller is not the same instant application or 2) the calling package is an
7241                // instant application and the provider is not visible to instant applications.
7242                final boolean matchInstantApp =
7243                        (flags & PackageManager.MATCH_INSTANT) != 0;
7244                final boolean matchVisibleToInstantAppOnly =
7245                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7246                final boolean isCallerInstantApp =
7247                        instantAppPkgName != null;
7248                final boolean isTargetSameInstantApp =
7249                        comp.getPackageName().equals(instantAppPkgName);
7250                final boolean isTargetInstantApp =
7251                        (pi.applicationInfo.privateFlags
7252                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7253                final boolean isTargetHiddenFromInstantApp =
7254                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
7255                final boolean blockResolution =
7256                        !isTargetSameInstantApp
7257                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7258                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7259                                        && isTargetHiddenFromInstantApp));
7260                if (!blockResolution) {
7261                    final ResolveInfo ri = new ResolveInfo();
7262                    ri.providerInfo = pi;
7263                    list.add(ri);
7264                }
7265            }
7266            return list;
7267        }
7268
7269        // reader
7270        synchronized (mPackages) {
7271            String pkgName = intent.getPackage();
7272            if (pkgName == null) {
7273                return applyPostContentProviderResolutionFilter(
7274                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7275                        instantAppPkgName);
7276            }
7277            final PackageParser.Package pkg = mPackages.get(pkgName);
7278            if (pkg != null) {
7279                return applyPostContentProviderResolutionFilter(
7280                        mProviders.queryIntentForPackage(
7281                        intent, resolvedType, flags, pkg.providers, userId),
7282                        instantAppPkgName);
7283            }
7284            return Collections.emptyList();
7285        }
7286    }
7287
7288    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7289            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7290        // TODO: When adding on-demand split support for non-instant applications, remove
7291        // this check and always apply post filtering
7292        if (instantAppPkgName == null) {
7293            return resolveInfos;
7294        }
7295        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7296            final ResolveInfo info = resolveInfos.get(i);
7297            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7298            // allow providers that are defined in the provided package
7299            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7300                if (info.providerInfo.splitName != null
7301                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7302                                info.providerInfo.splitName)) {
7303                    // requested provider is defined in a split that hasn't been installed yet.
7304                    // add the installer to the resolve list
7305                    if (DEBUG_EPHEMERAL) {
7306                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7307                    }
7308                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7309                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7310                            info.providerInfo.packageName, info.providerInfo.splitName,
7311                            info.providerInfo.applicationInfo.versionCode);
7312                    // make sure this resolver is the default
7313                    installerInfo.isDefault = true;
7314                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7315                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7316                    // add a non-generic filter
7317                    installerInfo.filter = new IntentFilter();
7318                    // load resources from the correct package
7319                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7320                    resolveInfos.set(i, installerInfo);
7321                }
7322                continue;
7323            }
7324            // allow providers that have been explicitly exposed to instant applications
7325            if (!isEphemeralApp
7326                    && ((info.providerInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
7327                continue;
7328            }
7329            resolveInfos.remove(i);
7330        }
7331        return resolveInfos;
7332    }
7333
7334    @Override
7335    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7336        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7337        flags = updateFlagsForPackage(flags, userId, null);
7338        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7339        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7340                true /* requireFullPermission */, false /* checkShell */,
7341                "get installed packages");
7342
7343        // writer
7344        synchronized (mPackages) {
7345            ArrayList<PackageInfo> list;
7346            if (listUninstalled) {
7347                list = new ArrayList<>(mSettings.mPackages.size());
7348                for (PackageSetting ps : mSettings.mPackages.values()) {
7349                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7350                        continue;
7351                    }
7352                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7353                    if (pi != null) {
7354                        list.add(pi);
7355                    }
7356                }
7357            } else {
7358                list = new ArrayList<>(mPackages.size());
7359                for (PackageParser.Package p : mPackages.values()) {
7360                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7361                            Binder.getCallingUid(), userId)) {
7362                        continue;
7363                    }
7364                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7365                            p.mExtras, flags, userId);
7366                    if (pi != null) {
7367                        list.add(pi);
7368                    }
7369                }
7370            }
7371
7372            return new ParceledListSlice<>(list);
7373        }
7374    }
7375
7376    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7377            String[] permissions, boolean[] tmp, int flags, int userId) {
7378        int numMatch = 0;
7379        final PermissionsState permissionsState = ps.getPermissionsState();
7380        for (int i=0; i<permissions.length; i++) {
7381            final String permission = permissions[i];
7382            if (permissionsState.hasPermission(permission, userId)) {
7383                tmp[i] = true;
7384                numMatch++;
7385            } else {
7386                tmp[i] = false;
7387            }
7388        }
7389        if (numMatch == 0) {
7390            return;
7391        }
7392        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7393
7394        // The above might return null in cases of uninstalled apps or install-state
7395        // skew across users/profiles.
7396        if (pi != null) {
7397            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7398                if (numMatch == permissions.length) {
7399                    pi.requestedPermissions = permissions;
7400                } else {
7401                    pi.requestedPermissions = new String[numMatch];
7402                    numMatch = 0;
7403                    for (int i=0; i<permissions.length; i++) {
7404                        if (tmp[i]) {
7405                            pi.requestedPermissions[numMatch] = permissions[i];
7406                            numMatch++;
7407                        }
7408                    }
7409                }
7410            }
7411            list.add(pi);
7412        }
7413    }
7414
7415    @Override
7416    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7417            String[] permissions, int flags, int userId) {
7418        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7419        flags = updateFlagsForPackage(flags, userId, permissions);
7420        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7421                true /* requireFullPermission */, false /* checkShell */,
7422                "get packages holding permissions");
7423        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7424
7425        // writer
7426        synchronized (mPackages) {
7427            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7428            boolean[] tmpBools = new boolean[permissions.length];
7429            if (listUninstalled) {
7430                for (PackageSetting ps : mSettings.mPackages.values()) {
7431                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7432                            userId);
7433                }
7434            } else {
7435                for (PackageParser.Package pkg : mPackages.values()) {
7436                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7437                    if (ps != null) {
7438                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7439                                userId);
7440                    }
7441                }
7442            }
7443
7444            return new ParceledListSlice<PackageInfo>(list);
7445        }
7446    }
7447
7448    @Override
7449    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7450        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7451        flags = updateFlagsForApplication(flags, userId, null);
7452        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7453
7454        // writer
7455        synchronized (mPackages) {
7456            ArrayList<ApplicationInfo> list;
7457            if (listUninstalled) {
7458                list = new ArrayList<>(mSettings.mPackages.size());
7459                for (PackageSetting ps : mSettings.mPackages.values()) {
7460                    ApplicationInfo ai;
7461                    int effectiveFlags = flags;
7462                    if (ps.isSystem()) {
7463                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7464                    }
7465                    if (ps.pkg != null) {
7466                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7467                            continue;
7468                        }
7469                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7470                                ps.readUserState(userId), userId);
7471                        if (ai != null) {
7472                            rebaseEnabledOverlays(ai, userId);
7473                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7474                        }
7475                    } else {
7476                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7477                        // and already converts to externally visible package name
7478                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7479                                Binder.getCallingUid(), effectiveFlags, userId);
7480                    }
7481                    if (ai != null) {
7482                        list.add(ai);
7483                    }
7484                }
7485            } else {
7486                list = new ArrayList<>(mPackages.size());
7487                for (PackageParser.Package p : mPackages.values()) {
7488                    if (p.mExtras != null) {
7489                        PackageSetting ps = (PackageSetting) p.mExtras;
7490                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId)) {
7491                            continue;
7492                        }
7493                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7494                                ps.readUserState(userId), userId);
7495                        if (ai != null) {
7496                            rebaseEnabledOverlays(ai, userId);
7497                            ai.packageName = resolveExternalPackageNameLPr(p);
7498                            list.add(ai);
7499                        }
7500                    }
7501                }
7502            }
7503
7504            return new ParceledListSlice<>(list);
7505        }
7506    }
7507
7508    @Override
7509    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7510        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7511            return null;
7512        }
7513
7514        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7515                "getEphemeralApplications");
7516        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7517                true /* requireFullPermission */, false /* checkShell */,
7518                "getEphemeralApplications");
7519        synchronized (mPackages) {
7520            List<InstantAppInfo> instantApps = mInstantAppRegistry
7521                    .getInstantAppsLPr(userId);
7522            if (instantApps != null) {
7523                return new ParceledListSlice<>(instantApps);
7524            }
7525        }
7526        return null;
7527    }
7528
7529    @Override
7530    public boolean isInstantApp(String packageName, int userId) {
7531        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7532                true /* requireFullPermission */, false /* checkShell */,
7533                "isInstantApp");
7534        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7535            return false;
7536        }
7537        int uid = Binder.getCallingUid();
7538        if (Process.isIsolated(uid)) {
7539            uid = mIsolatedOwners.get(uid);
7540        }
7541
7542        synchronized (mPackages) {
7543            final PackageSetting ps = mSettings.mPackages.get(packageName);
7544            PackageParser.Package pkg = mPackages.get(packageName);
7545            final boolean returnAllowed =
7546                    ps != null
7547                    && (isCallerSameApp(packageName, uid)
7548                            || mContext.checkCallingOrSelfPermission(
7549                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
7550                                            == PERMISSION_GRANTED
7551                            || mInstantAppRegistry.isInstantAccessGranted(
7552                                    userId, UserHandle.getAppId(uid), ps.appId));
7553            if (returnAllowed) {
7554                return ps.getInstantApp(userId);
7555            }
7556        }
7557        return false;
7558    }
7559
7560    @Override
7561    public byte[] getInstantAppCookie(String packageName, int userId) {
7562        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7563            return null;
7564        }
7565
7566        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7567                true /* requireFullPermission */, false /* checkShell */,
7568                "getInstantAppCookie");
7569        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7570            return null;
7571        }
7572        synchronized (mPackages) {
7573            return mInstantAppRegistry.getInstantAppCookieLPw(
7574                    packageName, userId);
7575        }
7576    }
7577
7578    @Override
7579    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7580        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7581            return true;
7582        }
7583
7584        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7585                true /* requireFullPermission */, true /* checkShell */,
7586                "setInstantAppCookie");
7587        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7588            return false;
7589        }
7590        synchronized (mPackages) {
7591            return mInstantAppRegistry.setInstantAppCookieLPw(
7592                    packageName, cookie, userId);
7593        }
7594    }
7595
7596    @Override
7597    public Bitmap getInstantAppIcon(String packageName, int userId) {
7598        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7599            return null;
7600        }
7601
7602        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7603                "getInstantAppIcon");
7604
7605        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7606                true /* requireFullPermission */, false /* checkShell */,
7607                "getInstantAppIcon");
7608
7609        synchronized (mPackages) {
7610            return mInstantAppRegistry.getInstantAppIconLPw(
7611                    packageName, userId);
7612        }
7613    }
7614
7615    private boolean isCallerSameApp(String packageName, int uid) {
7616        PackageParser.Package pkg = mPackages.get(packageName);
7617        return pkg != null
7618                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7619    }
7620
7621    @Override
7622    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7623        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7624    }
7625
7626    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7627        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7628
7629        // reader
7630        synchronized (mPackages) {
7631            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7632            final int userId = UserHandle.getCallingUserId();
7633            while (i.hasNext()) {
7634                final PackageParser.Package p = i.next();
7635                if (p.applicationInfo == null) continue;
7636
7637                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7638                        && !p.applicationInfo.isDirectBootAware();
7639                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7640                        && p.applicationInfo.isDirectBootAware();
7641
7642                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7643                        && (!mSafeMode || isSystemApp(p))
7644                        && (matchesUnaware || matchesAware)) {
7645                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7646                    if (ps != null) {
7647                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7648                                ps.readUserState(userId), userId);
7649                        if (ai != null) {
7650                            rebaseEnabledOverlays(ai, userId);
7651                            finalList.add(ai);
7652                        }
7653                    }
7654                }
7655            }
7656        }
7657
7658        return finalList;
7659    }
7660
7661    @Override
7662    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7663        if (!sUserManager.exists(userId)) return null;
7664        flags = updateFlagsForComponent(flags, userId, name);
7665        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7666        // reader
7667        synchronized (mPackages) {
7668            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7669            PackageSetting ps = provider != null
7670                    ? mSettings.mPackages.get(provider.owner.packageName)
7671                    : null;
7672            if (ps != null) {
7673                final boolean isInstantApp = ps.getInstantApp(userId);
7674                // normal application; filter out instant application provider
7675                if (instantAppPkgName == null && isInstantApp) {
7676                    return null;
7677                }
7678                // instant application; filter out other instant applications
7679                if (instantAppPkgName != null
7680                        && isInstantApp
7681                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7682                    return null;
7683                }
7684                // instant application; filter out non-exposed provider
7685                if (instantAppPkgName != null
7686                        && !isInstantApp
7687                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0) {
7688                    return null;
7689                }
7690                // provider not enabled
7691                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7692                    return null;
7693                }
7694                return PackageParser.generateProviderInfo(
7695                        provider, flags, ps.readUserState(userId), userId);
7696            }
7697            return null;
7698        }
7699    }
7700
7701    /**
7702     * @deprecated
7703     */
7704    @Deprecated
7705    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7706        // reader
7707        synchronized (mPackages) {
7708            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7709                    .entrySet().iterator();
7710            final int userId = UserHandle.getCallingUserId();
7711            while (i.hasNext()) {
7712                Map.Entry<String, PackageParser.Provider> entry = i.next();
7713                PackageParser.Provider p = entry.getValue();
7714                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7715
7716                if (ps != null && p.syncable
7717                        && (!mSafeMode || (p.info.applicationInfo.flags
7718                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7719                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7720                            ps.readUserState(userId), userId);
7721                    if (info != null) {
7722                        outNames.add(entry.getKey());
7723                        outInfo.add(info);
7724                    }
7725                }
7726            }
7727        }
7728    }
7729
7730    @Override
7731    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7732            int uid, int flags, String metaDataKey) {
7733        final int userId = processName != null ? UserHandle.getUserId(uid)
7734                : UserHandle.getCallingUserId();
7735        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7736        flags = updateFlagsForComponent(flags, userId, processName);
7737
7738        ArrayList<ProviderInfo> finalList = null;
7739        // reader
7740        synchronized (mPackages) {
7741            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7742            while (i.hasNext()) {
7743                final PackageParser.Provider p = i.next();
7744                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7745                if (ps != null && p.info.authority != null
7746                        && (processName == null
7747                                || (p.info.processName.equals(processName)
7748                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7749                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7750
7751                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
7752                    // parameter.
7753                    if (metaDataKey != null
7754                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7755                        continue;
7756                    }
7757
7758                    if (finalList == null) {
7759                        finalList = new ArrayList<ProviderInfo>(3);
7760                    }
7761                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
7762                            ps.readUserState(userId), userId);
7763                    if (info != null) {
7764                        finalList.add(info);
7765                    }
7766                }
7767            }
7768        }
7769
7770        if (finalList != null) {
7771            Collections.sort(finalList, mProviderInitOrderSorter);
7772            return new ParceledListSlice<ProviderInfo>(finalList);
7773        }
7774
7775        return ParceledListSlice.emptyList();
7776    }
7777
7778    @Override
7779    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
7780        // reader
7781        synchronized (mPackages) {
7782            final PackageParser.Instrumentation i = mInstrumentation.get(name);
7783            return PackageParser.generateInstrumentationInfo(i, flags);
7784        }
7785    }
7786
7787    @Override
7788    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
7789            String targetPackage, int flags) {
7790        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
7791    }
7792
7793    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
7794            int flags) {
7795        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
7796
7797        // reader
7798        synchronized (mPackages) {
7799            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
7800            while (i.hasNext()) {
7801                final PackageParser.Instrumentation p = i.next();
7802                if (targetPackage == null
7803                        || targetPackage.equals(p.info.targetPackage)) {
7804                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
7805                            flags);
7806                    if (ii != null) {
7807                        finalList.add(ii);
7808                    }
7809                }
7810            }
7811        }
7812
7813        return finalList;
7814    }
7815
7816    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
7817        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
7818        try {
7819            scanDirLI(dir, parseFlags, scanFlags, currentTime);
7820        } finally {
7821            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7822        }
7823    }
7824
7825    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
7826        final File[] files = dir.listFiles();
7827        if (ArrayUtils.isEmpty(files)) {
7828            Log.d(TAG, "No files in app dir " + dir);
7829            return;
7830        }
7831
7832        if (DEBUG_PACKAGE_SCANNING) {
7833            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
7834                    + " flags=0x" + Integer.toHexString(parseFlags));
7835        }
7836        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
7837                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
7838
7839        // Submit files for parsing in parallel
7840        int fileCount = 0;
7841        for (File file : files) {
7842            final boolean isPackage = (isApkFile(file) || file.isDirectory())
7843                    && !PackageInstallerService.isStageName(file.getName());
7844            if (!isPackage) {
7845                // Ignore entries which are not packages
7846                continue;
7847            }
7848            parallelPackageParser.submit(file, parseFlags);
7849            fileCount++;
7850        }
7851
7852        // Process results one by one
7853        for (; fileCount > 0; fileCount--) {
7854            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
7855            Throwable throwable = parseResult.throwable;
7856            int errorCode = PackageManager.INSTALL_SUCCEEDED;
7857
7858            if (throwable == null) {
7859                // Static shared libraries have synthetic package names
7860                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
7861                    renameStaticSharedLibraryPackage(parseResult.pkg);
7862                }
7863                try {
7864                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
7865                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
7866                                currentTime, null);
7867                    }
7868                } catch (PackageManagerException e) {
7869                    errorCode = e.error;
7870                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
7871                }
7872            } else if (throwable instanceof PackageParser.PackageParserException) {
7873                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
7874                        throwable;
7875                errorCode = e.error;
7876                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
7877            } else {
7878                throw new IllegalStateException("Unexpected exception occurred while parsing "
7879                        + parseResult.scanFile, throwable);
7880            }
7881
7882            // Delete invalid userdata apps
7883            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
7884                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
7885                logCriticalInfo(Log.WARN,
7886                        "Deleting invalid package at " + parseResult.scanFile);
7887                removeCodePathLI(parseResult.scanFile);
7888            }
7889        }
7890        parallelPackageParser.close();
7891    }
7892
7893    private static File getSettingsProblemFile() {
7894        File dataDir = Environment.getDataDirectory();
7895        File systemDir = new File(dataDir, "system");
7896        File fname = new File(systemDir, "uiderrors.txt");
7897        return fname;
7898    }
7899
7900    static void reportSettingsProblem(int priority, String msg) {
7901        logCriticalInfo(priority, msg);
7902    }
7903
7904    public static void logCriticalInfo(int priority, String msg) {
7905        Slog.println(priority, TAG, msg);
7906        EventLogTags.writePmCriticalInfo(msg);
7907        try {
7908            File fname = getSettingsProblemFile();
7909            FileOutputStream out = new FileOutputStream(fname, true);
7910            PrintWriter pw = new FastPrintWriter(out);
7911            SimpleDateFormat formatter = new SimpleDateFormat();
7912            String dateString = formatter.format(new Date(System.currentTimeMillis()));
7913            pw.println(dateString + ": " + msg);
7914            pw.close();
7915            FileUtils.setPermissions(
7916                    fname.toString(),
7917                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
7918                    -1, -1);
7919        } catch (java.io.IOException e) {
7920        }
7921    }
7922
7923    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
7924        if (srcFile.isDirectory()) {
7925            final File baseFile = new File(pkg.baseCodePath);
7926            long maxModifiedTime = baseFile.lastModified();
7927            if (pkg.splitCodePaths != null) {
7928                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
7929                    final File splitFile = new File(pkg.splitCodePaths[i]);
7930                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
7931                }
7932            }
7933            return maxModifiedTime;
7934        }
7935        return srcFile.lastModified();
7936    }
7937
7938    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
7939            final int policyFlags) throws PackageManagerException {
7940        // When upgrading from pre-N MR1, verify the package time stamp using the package
7941        // directory and not the APK file.
7942        final long lastModifiedTime = mIsPreNMR1Upgrade
7943                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
7944        if (ps != null
7945                && ps.codePath.equals(srcFile)
7946                && ps.timeStamp == lastModifiedTime
7947                && !isCompatSignatureUpdateNeeded(pkg)
7948                && !isRecoverSignatureUpdateNeeded(pkg)) {
7949            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
7950            KeySetManagerService ksms = mSettings.mKeySetManagerService;
7951            ArraySet<PublicKey> signingKs;
7952            synchronized (mPackages) {
7953                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
7954            }
7955            if (ps.signatures.mSignatures != null
7956                    && ps.signatures.mSignatures.length != 0
7957                    && signingKs != null) {
7958                // Optimization: reuse the existing cached certificates
7959                // if the package appears to be unchanged.
7960                pkg.mSignatures = ps.signatures.mSignatures;
7961                pkg.mSigningKeys = signingKs;
7962                return;
7963            }
7964
7965            Slog.w(TAG, "PackageSetting for " + ps.name
7966                    + " is missing signatures.  Collecting certs again to recover them.");
7967        } else {
7968            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
7969        }
7970
7971        try {
7972            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
7973            PackageParser.collectCertificates(pkg, policyFlags);
7974        } catch (PackageParserException e) {
7975            throw PackageManagerException.from(e);
7976        } finally {
7977            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7978        }
7979    }
7980
7981    /**
7982     *  Traces a package scan.
7983     *  @see #scanPackageLI(File, int, int, long, UserHandle)
7984     */
7985    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
7986            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
7987        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
7988        try {
7989            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
7990        } finally {
7991            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7992        }
7993    }
7994
7995    /**
7996     *  Scans a package and returns the newly parsed package.
7997     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
7998     */
7999    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8000            long currentTime, UserHandle user) throws PackageManagerException {
8001        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8002        PackageParser pp = new PackageParser();
8003        pp.setSeparateProcesses(mSeparateProcesses);
8004        pp.setOnlyCoreApps(mOnlyCore);
8005        pp.setDisplayMetrics(mMetrics);
8006        pp.setCallback(mPackageParserCallback);
8007
8008        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8009            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8010        }
8011
8012        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8013        final PackageParser.Package pkg;
8014        try {
8015            pkg = pp.parsePackage(scanFile, parseFlags);
8016        } catch (PackageParserException e) {
8017            throw PackageManagerException.from(e);
8018        } finally {
8019            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8020        }
8021
8022        // Static shared libraries have synthetic package names
8023        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8024            renameStaticSharedLibraryPackage(pkg);
8025        }
8026
8027        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8028    }
8029
8030    /**
8031     *  Scans a package and returns the newly parsed package.
8032     *  @throws PackageManagerException on a parse error.
8033     */
8034    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8035            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8036            throws PackageManagerException {
8037        // If the package has children and this is the first dive in the function
8038        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8039        // packages (parent and children) would be successfully scanned before the
8040        // actual scan since scanning mutates internal state and we want to atomically
8041        // install the package and its children.
8042        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8043            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8044                scanFlags |= SCAN_CHECK_ONLY;
8045            }
8046        } else {
8047            scanFlags &= ~SCAN_CHECK_ONLY;
8048        }
8049
8050        // Scan the parent
8051        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8052                scanFlags, currentTime, user);
8053
8054        // Scan the children
8055        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8056        for (int i = 0; i < childCount; i++) {
8057            PackageParser.Package childPackage = pkg.childPackages.get(i);
8058            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8059                    currentTime, user);
8060        }
8061
8062
8063        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8064            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8065        }
8066
8067        return scannedPkg;
8068    }
8069
8070    /**
8071     *  Scans a package and returns the newly parsed package.
8072     *  @throws PackageManagerException on a parse error.
8073     */
8074    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8075            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8076            throws PackageManagerException {
8077        PackageSetting ps = null;
8078        PackageSetting updatedPkg;
8079        // reader
8080        synchronized (mPackages) {
8081            // Look to see if we already know about this package.
8082            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8083            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8084                // This package has been renamed to its original name.  Let's
8085                // use that.
8086                ps = mSettings.getPackageLPr(oldName);
8087            }
8088            // If there was no original package, see one for the real package name.
8089            if (ps == null) {
8090                ps = mSettings.getPackageLPr(pkg.packageName);
8091            }
8092            // Check to see if this package could be hiding/updating a system
8093            // package.  Must look for it either under the original or real
8094            // package name depending on our state.
8095            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8096            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8097
8098            // If this is a package we don't know about on the system partition, we
8099            // may need to remove disabled child packages on the system partition
8100            // or may need to not add child packages if the parent apk is updated
8101            // on the data partition and no longer defines this child package.
8102            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8103                // If this is a parent package for an updated system app and this system
8104                // app got an OTA update which no longer defines some of the child packages
8105                // we have to prune them from the disabled system packages.
8106                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8107                if (disabledPs != null) {
8108                    final int scannedChildCount = (pkg.childPackages != null)
8109                            ? pkg.childPackages.size() : 0;
8110                    final int disabledChildCount = disabledPs.childPackageNames != null
8111                            ? disabledPs.childPackageNames.size() : 0;
8112                    for (int i = 0; i < disabledChildCount; i++) {
8113                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8114                        boolean disabledPackageAvailable = false;
8115                        for (int j = 0; j < scannedChildCount; j++) {
8116                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8117                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8118                                disabledPackageAvailable = true;
8119                                break;
8120                            }
8121                         }
8122                         if (!disabledPackageAvailable) {
8123                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8124                         }
8125                    }
8126                }
8127            }
8128        }
8129
8130        boolean updatedPkgBetter = false;
8131        // First check if this is a system package that may involve an update
8132        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8133            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8134            // it needs to drop FLAG_PRIVILEGED.
8135            if (locationIsPrivileged(scanFile)) {
8136                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8137            } else {
8138                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8139            }
8140
8141            if (ps != null && !ps.codePath.equals(scanFile)) {
8142                // The path has changed from what was last scanned...  check the
8143                // version of the new path against what we have stored to determine
8144                // what to do.
8145                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8146                if (pkg.mVersionCode <= ps.versionCode) {
8147                    // The system package has been updated and the code path does not match
8148                    // Ignore entry. Skip it.
8149                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8150                            + " ignored: updated version " + ps.versionCode
8151                            + " better than this " + pkg.mVersionCode);
8152                    if (!updatedPkg.codePath.equals(scanFile)) {
8153                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8154                                + ps.name + " changing from " + updatedPkg.codePathString
8155                                + " to " + scanFile);
8156                        updatedPkg.codePath = scanFile;
8157                        updatedPkg.codePathString = scanFile.toString();
8158                        updatedPkg.resourcePath = scanFile;
8159                        updatedPkg.resourcePathString = scanFile.toString();
8160                    }
8161                    updatedPkg.pkg = pkg;
8162                    updatedPkg.versionCode = pkg.mVersionCode;
8163
8164                    // Update the disabled system child packages to point to the package too.
8165                    final int childCount = updatedPkg.childPackageNames != null
8166                            ? updatedPkg.childPackageNames.size() : 0;
8167                    for (int i = 0; i < childCount; i++) {
8168                        String childPackageName = updatedPkg.childPackageNames.get(i);
8169                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8170                                childPackageName);
8171                        if (updatedChildPkg != null) {
8172                            updatedChildPkg.pkg = pkg;
8173                            updatedChildPkg.versionCode = pkg.mVersionCode;
8174                        }
8175                    }
8176
8177                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8178                            + scanFile + " ignored: updated version " + ps.versionCode
8179                            + " better than this " + pkg.mVersionCode);
8180                } else {
8181                    // The current app on the system partition is better than
8182                    // what we have updated to on the data partition; switch
8183                    // back to the system partition version.
8184                    // At this point, its safely assumed that package installation for
8185                    // apps in system partition will go through. If not there won't be a working
8186                    // version of the app
8187                    // writer
8188                    synchronized (mPackages) {
8189                        // Just remove the loaded entries from package lists.
8190                        mPackages.remove(ps.name);
8191                    }
8192
8193                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8194                            + " reverting from " + ps.codePathString
8195                            + ": new version " + pkg.mVersionCode
8196                            + " better than installed " + ps.versionCode);
8197
8198                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8199                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8200                    synchronized (mInstallLock) {
8201                        args.cleanUpResourcesLI();
8202                    }
8203                    synchronized (mPackages) {
8204                        mSettings.enableSystemPackageLPw(ps.name);
8205                    }
8206                    updatedPkgBetter = true;
8207                }
8208            }
8209        }
8210
8211        if (updatedPkg != null) {
8212            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8213            // initially
8214            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8215
8216            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8217            // flag set initially
8218            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8219                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8220            }
8221        }
8222
8223        // Verify certificates against what was last scanned
8224        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8225
8226        /*
8227         * A new system app appeared, but we already had a non-system one of the
8228         * same name installed earlier.
8229         */
8230        boolean shouldHideSystemApp = false;
8231        if (updatedPkg == null && ps != null
8232                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8233            /*
8234             * Check to make sure the signatures match first. If they don't,
8235             * wipe the installed application and its data.
8236             */
8237            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8238                    != PackageManager.SIGNATURE_MATCH) {
8239                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8240                        + " signatures don't match existing userdata copy; removing");
8241                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8242                        "scanPackageInternalLI")) {
8243                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8244                }
8245                ps = null;
8246            } else {
8247                /*
8248                 * If the newly-added system app is an older version than the
8249                 * already installed version, hide it. It will be scanned later
8250                 * and re-added like an update.
8251                 */
8252                if (pkg.mVersionCode <= ps.versionCode) {
8253                    shouldHideSystemApp = true;
8254                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8255                            + " but new version " + pkg.mVersionCode + " better than installed "
8256                            + ps.versionCode + "; hiding system");
8257                } else {
8258                    /*
8259                     * The newly found system app is a newer version that the
8260                     * one previously installed. Simply remove the
8261                     * already-installed application and replace it with our own
8262                     * while keeping the application data.
8263                     */
8264                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8265                            + " reverting from " + ps.codePathString + ": new version "
8266                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8267                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8268                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8269                    synchronized (mInstallLock) {
8270                        args.cleanUpResourcesLI();
8271                    }
8272                }
8273            }
8274        }
8275
8276        // The apk is forward locked (not public) if its code and resources
8277        // are kept in different files. (except for app in either system or
8278        // vendor path).
8279        // TODO grab this value from PackageSettings
8280        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8281            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8282                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8283            }
8284        }
8285
8286        // TODO: extend to support forward-locked splits
8287        String resourcePath = null;
8288        String baseResourcePath = null;
8289        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8290            if (ps != null && ps.resourcePathString != null) {
8291                resourcePath = ps.resourcePathString;
8292                baseResourcePath = ps.resourcePathString;
8293            } else {
8294                // Should not happen at all. Just log an error.
8295                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8296            }
8297        } else {
8298            resourcePath = pkg.codePath;
8299            baseResourcePath = pkg.baseCodePath;
8300        }
8301
8302        // Set application objects path explicitly.
8303        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8304        pkg.setApplicationInfoCodePath(pkg.codePath);
8305        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8306        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8307        pkg.setApplicationInfoResourcePath(resourcePath);
8308        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8309        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8310
8311        final int userId = ((user == null) ? 0 : user.getIdentifier());
8312        if (ps != null && ps.getInstantApp(userId)) {
8313            scanFlags |= SCAN_AS_INSTANT_APP;
8314        }
8315
8316        // Note that we invoke the following method only if we are about to unpack an application
8317        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8318                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8319
8320        /*
8321         * If the system app should be overridden by a previously installed
8322         * data, hide the system app now and let the /data/app scan pick it up
8323         * again.
8324         */
8325        if (shouldHideSystemApp) {
8326            synchronized (mPackages) {
8327                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8328            }
8329        }
8330
8331        return scannedPkg;
8332    }
8333
8334    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8335        // Derive the new package synthetic package name
8336        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8337                + pkg.staticSharedLibVersion);
8338    }
8339
8340    private static String fixProcessName(String defProcessName,
8341            String processName) {
8342        if (processName == null) {
8343            return defProcessName;
8344        }
8345        return processName;
8346    }
8347
8348    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8349            throws PackageManagerException {
8350        if (pkgSetting.signatures.mSignatures != null) {
8351            // Already existing package. Make sure signatures match
8352            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8353                    == PackageManager.SIGNATURE_MATCH;
8354            if (!match) {
8355                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8356                        == PackageManager.SIGNATURE_MATCH;
8357            }
8358            if (!match) {
8359                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8360                        == PackageManager.SIGNATURE_MATCH;
8361            }
8362            if (!match) {
8363                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8364                        + pkg.packageName + " signatures do not match the "
8365                        + "previously installed version; ignoring!");
8366            }
8367        }
8368
8369        // Check for shared user signatures
8370        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8371            // Already existing package. Make sure signatures match
8372            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8373                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8374            if (!match) {
8375                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8376                        == PackageManager.SIGNATURE_MATCH;
8377            }
8378            if (!match) {
8379                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8380                        == PackageManager.SIGNATURE_MATCH;
8381            }
8382            if (!match) {
8383                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8384                        "Package " + pkg.packageName
8385                        + " has no signatures that match those in shared user "
8386                        + pkgSetting.sharedUser.name + "; ignoring!");
8387            }
8388        }
8389    }
8390
8391    /**
8392     * Enforces that only the system UID or root's UID can call a method exposed
8393     * via Binder.
8394     *
8395     * @param message used as message if SecurityException is thrown
8396     * @throws SecurityException if the caller is not system or root
8397     */
8398    private static final void enforceSystemOrRoot(String message) {
8399        final int uid = Binder.getCallingUid();
8400        if (uid != Process.SYSTEM_UID && uid != 0) {
8401            throw new SecurityException(message);
8402        }
8403    }
8404
8405    @Override
8406    public void performFstrimIfNeeded() {
8407        enforceSystemOrRoot("Only the system can request fstrim");
8408
8409        // Before everything else, see whether we need to fstrim.
8410        try {
8411            IStorageManager sm = PackageHelper.getStorageManager();
8412            if (sm != null) {
8413                boolean doTrim = false;
8414                final long interval = android.provider.Settings.Global.getLong(
8415                        mContext.getContentResolver(),
8416                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8417                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8418                if (interval > 0) {
8419                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8420                    if (timeSinceLast > interval) {
8421                        doTrim = true;
8422                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8423                                + "; running immediately");
8424                    }
8425                }
8426                if (doTrim) {
8427                    final boolean dexOptDialogShown;
8428                    synchronized (mPackages) {
8429                        dexOptDialogShown = mDexOptDialogShown;
8430                    }
8431                    if (!isFirstBoot() && dexOptDialogShown) {
8432                        try {
8433                            ActivityManager.getService().showBootMessage(
8434                                    mContext.getResources().getString(
8435                                            R.string.android_upgrading_fstrim), true);
8436                        } catch (RemoteException e) {
8437                        }
8438                    }
8439                    sm.runMaintenance();
8440                }
8441            } else {
8442                Slog.e(TAG, "storageManager service unavailable!");
8443            }
8444        } catch (RemoteException e) {
8445            // Can't happen; StorageManagerService is local
8446        }
8447    }
8448
8449    @Override
8450    public void updatePackagesIfNeeded() {
8451        enforceSystemOrRoot("Only the system can request package update");
8452
8453        // We need to re-extract after an OTA.
8454        boolean causeUpgrade = isUpgrade();
8455
8456        // First boot or factory reset.
8457        // Note: we also handle devices that are upgrading to N right now as if it is their
8458        //       first boot, as they do not have profile data.
8459        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8460
8461        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8462        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8463
8464        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8465            return;
8466        }
8467
8468        List<PackageParser.Package> pkgs;
8469        synchronized (mPackages) {
8470            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8471        }
8472
8473        final long startTime = System.nanoTime();
8474        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8475                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8476
8477        final int elapsedTimeSeconds =
8478                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8479
8480        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8481        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8482        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8483        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8484        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8485    }
8486
8487    /**
8488     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8489     * containing statistics about the invocation. The array consists of three elements,
8490     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8491     * and {@code numberOfPackagesFailed}.
8492     */
8493    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8494            String compilerFilter) {
8495
8496        int numberOfPackagesVisited = 0;
8497        int numberOfPackagesOptimized = 0;
8498        int numberOfPackagesSkipped = 0;
8499        int numberOfPackagesFailed = 0;
8500        final int numberOfPackagesToDexopt = pkgs.size();
8501
8502        for (PackageParser.Package pkg : pkgs) {
8503            numberOfPackagesVisited++;
8504
8505            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8506                if (DEBUG_DEXOPT) {
8507                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8508                }
8509                numberOfPackagesSkipped++;
8510                continue;
8511            }
8512
8513            if (DEBUG_DEXOPT) {
8514                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8515                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8516            }
8517
8518            if (showDialog) {
8519                try {
8520                    ActivityManager.getService().showBootMessage(
8521                            mContext.getResources().getString(R.string.android_upgrading_apk,
8522                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8523                } catch (RemoteException e) {
8524                }
8525                synchronized (mPackages) {
8526                    mDexOptDialogShown = true;
8527                }
8528            }
8529
8530            // If the OTA updates a system app which was previously preopted to a non-preopted state
8531            // the app might end up being verified at runtime. That's because by default the apps
8532            // are verify-profile but for preopted apps there's no profile.
8533            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8534            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8535            // filter (by default interpret-only).
8536            // Note that at this stage unused apps are already filtered.
8537            if (isSystemApp(pkg) &&
8538                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8539                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8540                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8541            }
8542
8543            // checkProfiles is false to avoid merging profiles during boot which
8544            // might interfere with background compilation (b/28612421).
8545            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8546            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8547            // trade-off worth doing to save boot time work.
8548            int dexOptStatus = performDexOptTraced(pkg.packageName,
8549                    false /* checkProfiles */,
8550                    compilerFilter,
8551                    false /* force */);
8552            switch (dexOptStatus) {
8553                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8554                    numberOfPackagesOptimized++;
8555                    break;
8556                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8557                    numberOfPackagesSkipped++;
8558                    break;
8559                case PackageDexOptimizer.DEX_OPT_FAILED:
8560                    numberOfPackagesFailed++;
8561                    break;
8562                default:
8563                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8564                    break;
8565            }
8566        }
8567
8568        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8569                numberOfPackagesFailed };
8570    }
8571
8572    @Override
8573    public void notifyPackageUse(String packageName, int reason) {
8574        synchronized (mPackages) {
8575            PackageParser.Package p = mPackages.get(packageName);
8576            if (p == null) {
8577                return;
8578            }
8579            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8580        }
8581    }
8582
8583    @Override
8584    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8585        int userId = UserHandle.getCallingUserId();
8586        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8587        if (ai == null) {
8588            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8589                + loadingPackageName + ", user=" + userId);
8590            return;
8591        }
8592        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8593    }
8594
8595    @Override
8596    public boolean performDexOpt(String packageName,
8597            boolean checkProfiles, int compileReason, boolean force) {
8598        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8599                getCompilerFilterForReason(compileReason), force);
8600        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8601    }
8602
8603    @Override
8604    public boolean performDexOptMode(String packageName,
8605            boolean checkProfiles, String targetCompilerFilter, boolean force) {
8606        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8607                targetCompilerFilter, force);
8608        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8609    }
8610
8611    private int performDexOptTraced(String packageName,
8612                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8613        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8614        try {
8615            return performDexOptInternal(packageName, checkProfiles,
8616                    targetCompilerFilter, force);
8617        } finally {
8618            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8619        }
8620    }
8621
8622    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8623    // if the package can now be considered up to date for the given filter.
8624    private int performDexOptInternal(String packageName,
8625                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8626        PackageParser.Package p;
8627        synchronized (mPackages) {
8628            p = mPackages.get(packageName);
8629            if (p == null) {
8630                // Package could not be found. Report failure.
8631                return PackageDexOptimizer.DEX_OPT_FAILED;
8632            }
8633            mPackageUsage.maybeWriteAsync(mPackages);
8634            mCompilerStats.maybeWriteAsync();
8635        }
8636        long callingId = Binder.clearCallingIdentity();
8637        try {
8638            synchronized (mInstallLock) {
8639                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8640                        targetCompilerFilter, force);
8641            }
8642        } finally {
8643            Binder.restoreCallingIdentity(callingId);
8644        }
8645    }
8646
8647    public ArraySet<String> getOptimizablePackages() {
8648        ArraySet<String> pkgs = new ArraySet<String>();
8649        synchronized (mPackages) {
8650            for (PackageParser.Package p : mPackages.values()) {
8651                if (PackageDexOptimizer.canOptimizePackage(p)) {
8652                    pkgs.add(p.packageName);
8653                }
8654            }
8655        }
8656        return pkgs;
8657    }
8658
8659    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8660            boolean checkProfiles, String targetCompilerFilter,
8661            boolean force) {
8662        // Select the dex optimizer based on the force parameter.
8663        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8664        //       allocate an object here.
8665        PackageDexOptimizer pdo = force
8666                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8667                : mPackageDexOptimizer;
8668
8669        // Dexopt all dependencies first. Note: we ignore the return value and march on
8670        // on errors.
8671        // Note that we are going to call performDexOpt on those libraries as many times as
8672        // they are referenced in packages. When we do a batch of performDexOpt (for example
8673        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
8674        // and the first package that uses the library will dexopt it. The
8675        // others will see that the compiled code for the library is up to date.
8676        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
8677        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
8678        if (!deps.isEmpty()) {
8679            for (PackageParser.Package depPackage : deps) {
8680                // TODO: Analyze and investigate if we (should) profile libraries.
8681                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
8682                        false /* checkProfiles */,
8683                        targetCompilerFilter,
8684                        getOrCreateCompilerPackageStats(depPackage),
8685                        true /* isUsedByOtherApps */);
8686            }
8687        }
8688        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
8689                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
8690                mDexManager.isUsedByOtherApps(p.packageName));
8691    }
8692
8693    // Performs dexopt on the used secondary dex files belonging to the given package.
8694    // Returns true if all dex files were process successfully (which could mean either dexopt or
8695    // skip). Returns false if any of the files caused errors.
8696    @Override
8697    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8698            boolean force) {
8699        mDexManager.reconcileSecondaryDexFiles(packageName);
8700        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
8701    }
8702
8703    public boolean performDexOptSecondary(String packageName, int compileReason,
8704            boolean force) {
8705        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
8706    }
8707
8708    /**
8709     * Reconcile the information we have about the secondary dex files belonging to
8710     * {@code packagName} and the actual dex files. For all dex files that were
8711     * deleted, update the internal records and delete the generated oat files.
8712     */
8713    @Override
8714    public void reconcileSecondaryDexFiles(String packageName) {
8715        mDexManager.reconcileSecondaryDexFiles(packageName);
8716    }
8717
8718    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
8719    // a reference there.
8720    /*package*/ DexManager getDexManager() {
8721        return mDexManager;
8722    }
8723
8724    /**
8725     * Execute the background dexopt job immediately.
8726     */
8727    @Override
8728    public boolean runBackgroundDexoptJob() {
8729        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
8730    }
8731
8732    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
8733        if (p.usesLibraries != null || p.usesOptionalLibraries != null
8734                || p.usesStaticLibraries != null) {
8735            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
8736            Set<String> collectedNames = new HashSet<>();
8737            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
8738
8739            retValue.remove(p);
8740
8741            return retValue;
8742        } else {
8743            return Collections.emptyList();
8744        }
8745    }
8746
8747    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
8748            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8749        if (!collectedNames.contains(p.packageName)) {
8750            collectedNames.add(p.packageName);
8751            collected.add(p);
8752
8753            if (p.usesLibraries != null) {
8754                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
8755                        null, collected, collectedNames);
8756            }
8757            if (p.usesOptionalLibraries != null) {
8758                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
8759                        null, collected, collectedNames);
8760            }
8761            if (p.usesStaticLibraries != null) {
8762                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
8763                        p.usesStaticLibrariesVersions, collected, collectedNames);
8764            }
8765        }
8766    }
8767
8768    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
8769            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
8770        final int libNameCount = libs.size();
8771        for (int i = 0; i < libNameCount; i++) {
8772            String libName = libs.get(i);
8773            int version = (versions != null && versions.length == libNameCount)
8774                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
8775            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
8776            if (libPkg != null) {
8777                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
8778            }
8779        }
8780    }
8781
8782    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
8783        synchronized (mPackages) {
8784            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
8785            if (libEntry != null) {
8786                return mPackages.get(libEntry.apk);
8787            }
8788            return null;
8789        }
8790    }
8791
8792    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
8793        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
8794        if (versionedLib == null) {
8795            return null;
8796        }
8797        return versionedLib.get(version);
8798    }
8799
8800    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
8801        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
8802                pkg.staticSharedLibName);
8803        if (versionedLib == null) {
8804            return null;
8805        }
8806        int previousLibVersion = -1;
8807        final int versionCount = versionedLib.size();
8808        for (int i = 0; i < versionCount; i++) {
8809            final int libVersion = versionedLib.keyAt(i);
8810            if (libVersion < pkg.staticSharedLibVersion) {
8811                previousLibVersion = Math.max(previousLibVersion, libVersion);
8812            }
8813        }
8814        if (previousLibVersion >= 0) {
8815            return versionedLib.get(previousLibVersion);
8816        }
8817        return null;
8818    }
8819
8820    public void shutdown() {
8821        mPackageUsage.writeNow(mPackages);
8822        mCompilerStats.writeNow();
8823    }
8824
8825    @Override
8826    public void dumpProfiles(String packageName) {
8827        PackageParser.Package pkg;
8828        synchronized (mPackages) {
8829            pkg = mPackages.get(packageName);
8830            if (pkg == null) {
8831                throw new IllegalArgumentException("Unknown package: " + packageName);
8832            }
8833        }
8834        /* Only the shell, root, or the app user should be able to dump profiles. */
8835        int callingUid = Binder.getCallingUid();
8836        if (callingUid != Process.SHELL_UID &&
8837            callingUid != Process.ROOT_UID &&
8838            callingUid != pkg.applicationInfo.uid) {
8839            throw new SecurityException("dumpProfiles");
8840        }
8841
8842        synchronized (mInstallLock) {
8843            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
8844            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
8845            try {
8846                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
8847                String codePaths = TextUtils.join(";", allCodePaths);
8848                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
8849            } catch (InstallerException e) {
8850                Slog.w(TAG, "Failed to dump profiles", e);
8851            }
8852            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8853        }
8854    }
8855
8856    @Override
8857    public void forceDexOpt(String packageName) {
8858        enforceSystemOrRoot("forceDexOpt");
8859
8860        PackageParser.Package pkg;
8861        synchronized (mPackages) {
8862            pkg = mPackages.get(packageName);
8863            if (pkg == null) {
8864                throw new IllegalArgumentException("Unknown package: " + packageName);
8865            }
8866        }
8867
8868        synchronized (mInstallLock) {
8869            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8870
8871            // Whoever is calling forceDexOpt wants a compiled package.
8872            // Don't use profiles since that may cause compilation to be skipped.
8873            final int res = performDexOptInternalWithDependenciesLI(pkg,
8874                    false /* checkProfiles */, getDefaultCompilerFilter(),
8875                    true /* force */);
8876
8877            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8878            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
8879                throw new IllegalStateException("Failed to dexopt: " + res);
8880            }
8881        }
8882    }
8883
8884    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
8885        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8886            Slog.w(TAG, "Unable to update from " + oldPkg.name
8887                    + " to " + newPkg.packageName
8888                    + ": old package not in system partition");
8889            return false;
8890        } else if (mPackages.get(oldPkg.name) != null) {
8891            Slog.w(TAG, "Unable to update from " + oldPkg.name
8892                    + " to " + newPkg.packageName
8893                    + ": old package still exists");
8894            return false;
8895        }
8896        return true;
8897    }
8898
8899    void removeCodePathLI(File codePath) {
8900        if (codePath.isDirectory()) {
8901            try {
8902                mInstaller.rmPackageDir(codePath.getAbsolutePath());
8903            } catch (InstallerException e) {
8904                Slog.w(TAG, "Failed to remove code path", e);
8905            }
8906        } else {
8907            codePath.delete();
8908        }
8909    }
8910
8911    private int[] resolveUserIds(int userId) {
8912        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
8913    }
8914
8915    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8916        if (pkg == null) {
8917            Slog.wtf(TAG, "Package was null!", new Throwable());
8918            return;
8919        }
8920        clearAppDataLeafLIF(pkg, userId, flags);
8921        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8922        for (int i = 0; i < childCount; i++) {
8923            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8924        }
8925    }
8926
8927    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8928        final PackageSetting ps;
8929        synchronized (mPackages) {
8930            ps = mSettings.mPackages.get(pkg.packageName);
8931        }
8932        for (int realUserId : resolveUserIds(userId)) {
8933            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8934            try {
8935                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8936                        ceDataInode);
8937            } catch (InstallerException e) {
8938                Slog.w(TAG, String.valueOf(e));
8939            }
8940        }
8941    }
8942
8943    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
8944        if (pkg == null) {
8945            Slog.wtf(TAG, "Package was null!", new Throwable());
8946            return;
8947        }
8948        destroyAppDataLeafLIF(pkg, userId, flags);
8949        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8950        for (int i = 0; i < childCount; i++) {
8951            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
8952        }
8953    }
8954
8955    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
8956        final PackageSetting ps;
8957        synchronized (mPackages) {
8958            ps = mSettings.mPackages.get(pkg.packageName);
8959        }
8960        for (int realUserId : resolveUserIds(userId)) {
8961            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
8962            try {
8963                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
8964                        ceDataInode);
8965            } catch (InstallerException e) {
8966                Slog.w(TAG, String.valueOf(e));
8967            }
8968            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
8969        }
8970    }
8971
8972    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
8973        if (pkg == null) {
8974            Slog.wtf(TAG, "Package was null!", new Throwable());
8975            return;
8976        }
8977        destroyAppProfilesLeafLIF(pkg);
8978        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8979        for (int i = 0; i < childCount; i++) {
8980            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
8981        }
8982    }
8983
8984    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
8985        try {
8986            mInstaller.destroyAppProfiles(pkg.packageName);
8987        } catch (InstallerException e) {
8988            Slog.w(TAG, String.valueOf(e));
8989        }
8990    }
8991
8992    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
8993        if (pkg == null) {
8994            Slog.wtf(TAG, "Package was null!", new Throwable());
8995            return;
8996        }
8997        clearAppProfilesLeafLIF(pkg);
8998        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8999        for (int i = 0; i < childCount; i++) {
9000            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9001        }
9002    }
9003
9004    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9005        try {
9006            mInstaller.clearAppProfiles(pkg.packageName);
9007        } catch (InstallerException e) {
9008            Slog.w(TAG, String.valueOf(e));
9009        }
9010    }
9011
9012    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9013            long lastUpdateTime) {
9014        // Set parent install/update time
9015        PackageSetting ps = (PackageSetting) pkg.mExtras;
9016        if (ps != null) {
9017            ps.firstInstallTime = firstInstallTime;
9018            ps.lastUpdateTime = lastUpdateTime;
9019        }
9020        // Set children install/update time
9021        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9022        for (int i = 0; i < childCount; i++) {
9023            PackageParser.Package childPkg = pkg.childPackages.get(i);
9024            ps = (PackageSetting) childPkg.mExtras;
9025            if (ps != null) {
9026                ps.firstInstallTime = firstInstallTime;
9027                ps.lastUpdateTime = lastUpdateTime;
9028            }
9029        }
9030    }
9031
9032    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9033            PackageParser.Package changingLib) {
9034        if (file.path != null) {
9035            usesLibraryFiles.add(file.path);
9036            return;
9037        }
9038        PackageParser.Package p = mPackages.get(file.apk);
9039        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9040            // If we are doing this while in the middle of updating a library apk,
9041            // then we need to make sure to use that new apk for determining the
9042            // dependencies here.  (We haven't yet finished committing the new apk
9043            // to the package manager state.)
9044            if (p == null || p.packageName.equals(changingLib.packageName)) {
9045                p = changingLib;
9046            }
9047        }
9048        if (p != null) {
9049            usesLibraryFiles.addAll(p.getAllCodePaths());
9050        }
9051    }
9052
9053    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9054            PackageParser.Package changingLib) throws PackageManagerException {
9055        if (pkg == null) {
9056            return;
9057        }
9058        ArraySet<String> usesLibraryFiles = null;
9059        if (pkg.usesLibraries != null) {
9060            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9061                    null, null, pkg.packageName, changingLib, true, null);
9062        }
9063        if (pkg.usesStaticLibraries != null) {
9064            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9065                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9066                    pkg.packageName, changingLib, true, usesLibraryFiles);
9067        }
9068        if (pkg.usesOptionalLibraries != null) {
9069            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9070                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9071        }
9072        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9073            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9074        } else {
9075            pkg.usesLibraryFiles = null;
9076        }
9077    }
9078
9079    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9080            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9081            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9082            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9083            throws PackageManagerException {
9084        final int libCount = requestedLibraries.size();
9085        for (int i = 0; i < libCount; i++) {
9086            final String libName = requestedLibraries.get(i);
9087            final int libVersion = requiredVersions != null ? requiredVersions[i]
9088                    : SharedLibraryInfo.VERSION_UNDEFINED;
9089            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9090            if (libEntry == null) {
9091                if (required) {
9092                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9093                            "Package " + packageName + " requires unavailable shared library "
9094                                    + libName + "; failing!");
9095                } else {
9096                    Slog.w(TAG, "Package " + packageName
9097                            + " desires unavailable shared library "
9098                            + libName + "; ignoring!");
9099                }
9100            } else {
9101                if (requiredVersions != null && requiredCertDigests != null) {
9102                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9103                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9104                            "Package " + packageName + " requires unavailable static shared"
9105                                    + " library " + libName + " version "
9106                                    + libEntry.info.getVersion() + "; failing!");
9107                    }
9108
9109                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9110                    if (libPkg == null) {
9111                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9112                                "Package " + packageName + " requires unavailable static shared"
9113                                        + " library; failing!");
9114                    }
9115
9116                    String expectedCertDigest = requiredCertDigests[i];
9117                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9118                                libPkg.mSignatures[0]);
9119                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9120                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9121                                "Package " + packageName + " requires differently signed" +
9122                                        " static shared library; failing!");
9123                    }
9124                }
9125
9126                if (outUsedLibraries == null) {
9127                    outUsedLibraries = new ArraySet<>();
9128                }
9129                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9130            }
9131        }
9132        return outUsedLibraries;
9133    }
9134
9135    private static boolean hasString(List<String> list, List<String> which) {
9136        if (list == null) {
9137            return false;
9138        }
9139        for (int i=list.size()-1; i>=0; i--) {
9140            for (int j=which.size()-1; j>=0; j--) {
9141                if (which.get(j).equals(list.get(i))) {
9142                    return true;
9143                }
9144            }
9145        }
9146        return false;
9147    }
9148
9149    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9150            PackageParser.Package changingPkg) {
9151        ArrayList<PackageParser.Package> res = null;
9152        for (PackageParser.Package pkg : mPackages.values()) {
9153            if (changingPkg != null
9154                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9155                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9156                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9157                            changingPkg.staticSharedLibName)) {
9158                return null;
9159            }
9160            if (res == null) {
9161                res = new ArrayList<>();
9162            }
9163            res.add(pkg);
9164            try {
9165                updateSharedLibrariesLPr(pkg, changingPkg);
9166            } catch (PackageManagerException e) {
9167                // If a system app update or an app and a required lib missing we
9168                // delete the package and for updated system apps keep the data as
9169                // it is better for the user to reinstall than to be in an limbo
9170                // state. Also libs disappearing under an app should never happen
9171                // - just in case.
9172                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9173                    final int flags = pkg.isUpdatedSystemApp()
9174                            ? PackageManager.DELETE_KEEP_DATA : 0;
9175                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9176                            flags , null, true, null);
9177                }
9178                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9179            }
9180        }
9181        return res;
9182    }
9183
9184    /**
9185     * Derive the value of the {@code cpuAbiOverride} based on the provided
9186     * value and an optional stored value from the package settings.
9187     */
9188    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9189        String cpuAbiOverride = null;
9190
9191        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9192            cpuAbiOverride = null;
9193        } else if (abiOverride != null) {
9194            cpuAbiOverride = abiOverride;
9195        } else if (settings != null) {
9196            cpuAbiOverride = settings.cpuAbiOverrideString;
9197        }
9198
9199        return cpuAbiOverride;
9200    }
9201
9202    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9203            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9204                    throws PackageManagerException {
9205        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9206        // If the package has children and this is the first dive in the function
9207        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9208        // whether all packages (parent and children) would be successfully scanned
9209        // before the actual scan since scanning mutates internal state and we want
9210        // to atomically install the package and its children.
9211        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9212            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9213                scanFlags |= SCAN_CHECK_ONLY;
9214            }
9215        } else {
9216            scanFlags &= ~SCAN_CHECK_ONLY;
9217        }
9218
9219        final PackageParser.Package scannedPkg;
9220        try {
9221            // Scan the parent
9222            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9223            // Scan the children
9224            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9225            for (int i = 0; i < childCount; i++) {
9226                PackageParser.Package childPkg = pkg.childPackages.get(i);
9227                scanPackageLI(childPkg, policyFlags,
9228                        scanFlags, currentTime, user);
9229            }
9230        } finally {
9231            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9232        }
9233
9234        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9235            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9236        }
9237
9238        return scannedPkg;
9239    }
9240
9241    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9242            int scanFlags, long currentTime, @Nullable UserHandle user)
9243                    throws PackageManagerException {
9244        boolean success = false;
9245        try {
9246            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9247                    currentTime, user);
9248            success = true;
9249            return res;
9250        } finally {
9251            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9252                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9253                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9254                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9255                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9256            }
9257        }
9258    }
9259
9260    /**
9261     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9262     */
9263    private static boolean apkHasCode(String fileName) {
9264        StrictJarFile jarFile = null;
9265        try {
9266            jarFile = new StrictJarFile(fileName,
9267                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9268            return jarFile.findEntry("classes.dex") != null;
9269        } catch (IOException ignore) {
9270        } finally {
9271            try {
9272                if (jarFile != null) {
9273                    jarFile.close();
9274                }
9275            } catch (IOException ignore) {}
9276        }
9277        return false;
9278    }
9279
9280    /**
9281     * Enforces code policy for the package. This ensures that if an APK has
9282     * declared hasCode="true" in its manifest that the APK actually contains
9283     * code.
9284     *
9285     * @throws PackageManagerException If bytecode could not be found when it should exist
9286     */
9287    private static void assertCodePolicy(PackageParser.Package pkg)
9288            throws PackageManagerException {
9289        final boolean shouldHaveCode =
9290                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9291        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9292            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9293                    "Package " + pkg.baseCodePath + " code is missing");
9294        }
9295
9296        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9297            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9298                final boolean splitShouldHaveCode =
9299                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9300                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9301                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9302                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9303                }
9304            }
9305        }
9306    }
9307
9308    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9309            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9310                    throws PackageManagerException {
9311        if (DEBUG_PACKAGE_SCANNING) {
9312            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9313                Log.d(TAG, "Scanning package " + pkg.packageName);
9314        }
9315
9316        applyPolicy(pkg, policyFlags);
9317
9318        assertPackageIsValid(pkg, policyFlags, scanFlags);
9319
9320        // Initialize package source and resource directories
9321        final File scanFile = new File(pkg.codePath);
9322        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9323        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9324
9325        SharedUserSetting suid = null;
9326        PackageSetting pkgSetting = null;
9327
9328        // Getting the package setting may have a side-effect, so if we
9329        // are only checking if scan would succeed, stash a copy of the
9330        // old setting to restore at the end.
9331        PackageSetting nonMutatedPs = null;
9332
9333        // We keep references to the derived CPU Abis from settings in oder to reuse
9334        // them in the case where we're not upgrading or booting for the first time.
9335        String primaryCpuAbiFromSettings = null;
9336        String secondaryCpuAbiFromSettings = null;
9337
9338        // writer
9339        synchronized (mPackages) {
9340            if (pkg.mSharedUserId != null) {
9341                // SIDE EFFECTS; may potentially allocate a new shared user
9342                suid = mSettings.getSharedUserLPw(
9343                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9344                if (DEBUG_PACKAGE_SCANNING) {
9345                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9346                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9347                                + "): packages=" + suid.packages);
9348                }
9349            }
9350
9351            // Check if we are renaming from an original package name.
9352            PackageSetting origPackage = null;
9353            String realName = null;
9354            if (pkg.mOriginalPackages != null) {
9355                // This package may need to be renamed to a previously
9356                // installed name.  Let's check on that...
9357                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9358                if (pkg.mOriginalPackages.contains(renamed)) {
9359                    // This package had originally been installed as the
9360                    // original name, and we have already taken care of
9361                    // transitioning to the new one.  Just update the new
9362                    // one to continue using the old name.
9363                    realName = pkg.mRealPackage;
9364                    if (!pkg.packageName.equals(renamed)) {
9365                        // Callers into this function may have already taken
9366                        // care of renaming the package; only do it here if
9367                        // it is not already done.
9368                        pkg.setPackageName(renamed);
9369                    }
9370                } else {
9371                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9372                        if ((origPackage = mSettings.getPackageLPr(
9373                                pkg.mOriginalPackages.get(i))) != null) {
9374                            // We do have the package already installed under its
9375                            // original name...  should we use it?
9376                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9377                                // New package is not compatible with original.
9378                                origPackage = null;
9379                                continue;
9380                            } else if (origPackage.sharedUser != null) {
9381                                // Make sure uid is compatible between packages.
9382                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9383                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9384                                            + " to " + pkg.packageName + ": old uid "
9385                                            + origPackage.sharedUser.name
9386                                            + " differs from " + pkg.mSharedUserId);
9387                                    origPackage = null;
9388                                    continue;
9389                                }
9390                                // TODO: Add case when shared user id is added [b/28144775]
9391                            } else {
9392                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9393                                        + pkg.packageName + " to old name " + origPackage.name);
9394                            }
9395                            break;
9396                        }
9397                    }
9398                }
9399            }
9400
9401            if (mTransferedPackages.contains(pkg.packageName)) {
9402                Slog.w(TAG, "Package " + pkg.packageName
9403                        + " was transferred to another, but its .apk remains");
9404            }
9405
9406            // See comments in nonMutatedPs declaration
9407            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9408                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9409                if (foundPs != null) {
9410                    nonMutatedPs = new PackageSetting(foundPs);
9411                }
9412            }
9413
9414            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9415                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9416                if (foundPs != null) {
9417                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9418                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9419                }
9420            }
9421
9422            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9423            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9424                PackageManagerService.reportSettingsProblem(Log.WARN,
9425                        "Package " + pkg.packageName + " shared user changed from "
9426                                + (pkgSetting.sharedUser != null
9427                                        ? pkgSetting.sharedUser.name : "<nothing>")
9428                                + " to "
9429                                + (suid != null ? suid.name : "<nothing>")
9430                                + "; replacing with new");
9431                pkgSetting = null;
9432            }
9433            final PackageSetting oldPkgSetting =
9434                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9435            final PackageSetting disabledPkgSetting =
9436                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9437
9438            String[] usesStaticLibraries = null;
9439            if (pkg.usesStaticLibraries != null) {
9440                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9441                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9442            }
9443
9444            if (pkgSetting == null) {
9445                final String parentPackageName = (pkg.parentPackage != null)
9446                        ? pkg.parentPackage.packageName : null;
9447                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9448                // REMOVE SharedUserSetting from method; update in a separate call
9449                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9450                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9451                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9452                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9453                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9454                        true /*allowInstall*/, instantApp, parentPackageName,
9455                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
9456                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9457                // SIDE EFFECTS; updates system state; move elsewhere
9458                if (origPackage != null) {
9459                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9460                }
9461                mSettings.addUserToSettingLPw(pkgSetting);
9462            } else {
9463                // REMOVE SharedUserSetting from method; update in a separate call.
9464                //
9465                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9466                // secondaryCpuAbi are not known at this point so we always update them
9467                // to null here, only to reset them at a later point.
9468                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9469                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9470                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9471                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9472                        UserManagerService.getInstance(), usesStaticLibraries,
9473                        pkg.usesStaticLibrariesVersions);
9474            }
9475            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9476            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9477
9478            // SIDE EFFECTS; modifies system state; move elsewhere
9479            if (pkgSetting.origPackage != null) {
9480                // If we are first transitioning from an original package,
9481                // fix up the new package's name now.  We need to do this after
9482                // looking up the package under its new name, so getPackageLP
9483                // can take care of fiddling things correctly.
9484                pkg.setPackageName(origPackage.name);
9485
9486                // File a report about this.
9487                String msg = "New package " + pkgSetting.realName
9488                        + " renamed to replace old package " + pkgSetting.name;
9489                reportSettingsProblem(Log.WARN, msg);
9490
9491                // Make a note of it.
9492                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9493                    mTransferedPackages.add(origPackage.name);
9494                }
9495
9496                // No longer need to retain this.
9497                pkgSetting.origPackage = null;
9498            }
9499
9500            // SIDE EFFECTS; modifies system state; move elsewhere
9501            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9502                // Make a note of it.
9503                mTransferedPackages.add(pkg.packageName);
9504            }
9505
9506            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9507                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9508            }
9509
9510            if ((scanFlags & SCAN_BOOTING) == 0
9511                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9512                // Check all shared libraries and map to their actual file path.
9513                // We only do this here for apps not on a system dir, because those
9514                // are the only ones that can fail an install due to this.  We
9515                // will take care of the system apps by updating all of their
9516                // library paths after the scan is done. Also during the initial
9517                // scan don't update any libs as we do this wholesale after all
9518                // apps are scanned to avoid dependency based scanning.
9519                updateSharedLibrariesLPr(pkg, null);
9520            }
9521
9522            if (mFoundPolicyFile) {
9523                SELinuxMMAC.assignSeInfoValue(pkg);
9524            }
9525            pkg.applicationInfo.uid = pkgSetting.appId;
9526            pkg.mExtras = pkgSetting;
9527
9528
9529            // Static shared libs have same package with different versions where
9530            // we internally use a synthetic package name to allow multiple versions
9531            // of the same package, therefore we need to compare signatures against
9532            // the package setting for the latest library version.
9533            PackageSetting signatureCheckPs = pkgSetting;
9534            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9535                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9536                if (libraryEntry != null) {
9537                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9538                }
9539            }
9540
9541            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9542                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9543                    // We just determined the app is signed correctly, so bring
9544                    // over the latest parsed certs.
9545                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9546                } else {
9547                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9548                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9549                                "Package " + pkg.packageName + " upgrade keys do not match the "
9550                                + "previously installed version");
9551                    } else {
9552                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9553                        String msg = "System package " + pkg.packageName
9554                                + " signature changed; retaining data.";
9555                        reportSettingsProblem(Log.WARN, msg);
9556                    }
9557                }
9558            } else {
9559                try {
9560                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9561                    verifySignaturesLP(signatureCheckPs, pkg);
9562                    // We just determined the app is signed correctly, so bring
9563                    // over the latest parsed certs.
9564                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9565                } catch (PackageManagerException e) {
9566                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9567                        throw e;
9568                    }
9569                    // The signature has changed, but this package is in the system
9570                    // image...  let's recover!
9571                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9572                    // However...  if this package is part of a shared user, but it
9573                    // doesn't match the signature of the shared user, let's fail.
9574                    // What this means is that you can't change the signatures
9575                    // associated with an overall shared user, which doesn't seem all
9576                    // that unreasonable.
9577                    if (signatureCheckPs.sharedUser != null) {
9578                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9579                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9580                            throw new PackageManagerException(
9581                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9582                                    "Signature mismatch for shared user: "
9583                                            + pkgSetting.sharedUser);
9584                        }
9585                    }
9586                    // File a report about this.
9587                    String msg = "System package " + pkg.packageName
9588                            + " signature changed; retaining data.";
9589                    reportSettingsProblem(Log.WARN, msg);
9590                }
9591            }
9592
9593            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9594                // This package wants to adopt ownership of permissions from
9595                // another package.
9596                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9597                    final String origName = pkg.mAdoptPermissions.get(i);
9598                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9599                    if (orig != null) {
9600                        if (verifyPackageUpdateLPr(orig, pkg)) {
9601                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9602                                    + pkg.packageName);
9603                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9604                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
9605                        }
9606                    }
9607                }
9608            }
9609        }
9610
9611        pkg.applicationInfo.processName = fixProcessName(
9612                pkg.applicationInfo.packageName,
9613                pkg.applicationInfo.processName);
9614
9615        if (pkg != mPlatformPackage) {
9616            // Get all of our default paths setup
9617            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9618        }
9619
9620        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9621
9622        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9623            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9624                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9625                derivePackageAbi(
9626                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9627                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9628
9629                // Some system apps still use directory structure for native libraries
9630                // in which case we might end up not detecting abi solely based on apk
9631                // structure. Try to detect abi based on directory structure.
9632                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9633                        pkg.applicationInfo.primaryCpuAbi == null) {
9634                    setBundledAppAbisAndRoots(pkg, pkgSetting);
9635                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9636                }
9637            } else {
9638                // This is not a first boot or an upgrade, don't bother deriving the
9639                // ABI during the scan. Instead, trust the value that was stored in the
9640                // package setting.
9641                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9642                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9643
9644                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9645
9646                if (DEBUG_ABI_SELECTION) {
9647                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9648                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9649                        pkg.applicationInfo.secondaryCpuAbi);
9650                }
9651            }
9652        } else {
9653            if ((scanFlags & SCAN_MOVE) != 0) {
9654                // We haven't run dex-opt for this move (since we've moved the compiled output too)
9655                // but we already have this packages package info in the PackageSetting. We just
9656                // use that and derive the native library path based on the new codepath.
9657                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9658                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9659            }
9660
9661            // Set native library paths again. For moves, the path will be updated based on the
9662            // ABIs we've determined above. For non-moves, the path will be updated based on the
9663            // ABIs we determined during compilation, but the path will depend on the final
9664            // package path (after the rename away from the stage path).
9665            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9666        }
9667
9668        // This is a special case for the "system" package, where the ABI is
9669        // dictated by the zygote configuration (and init.rc). We should keep track
9670        // of this ABI so that we can deal with "normal" applications that run under
9671        // the same UID correctly.
9672        if (mPlatformPackage == pkg) {
9673            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
9674                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
9675        }
9676
9677        // If there's a mismatch between the abi-override in the package setting
9678        // and the abiOverride specified for the install. Warn about this because we
9679        // would've already compiled the app without taking the package setting into
9680        // account.
9681        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
9682            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
9683                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
9684                        " for package " + pkg.packageName);
9685            }
9686        }
9687
9688        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
9689        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
9690        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
9691
9692        // Copy the derived override back to the parsed package, so that we can
9693        // update the package settings accordingly.
9694        pkg.cpuAbiOverride = cpuAbiOverride;
9695
9696        if (DEBUG_ABI_SELECTION) {
9697            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
9698                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
9699                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
9700        }
9701
9702        // Push the derived path down into PackageSettings so we know what to
9703        // clean up at uninstall time.
9704        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
9705
9706        if (DEBUG_ABI_SELECTION) {
9707            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
9708                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
9709                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
9710        }
9711
9712        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
9713        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
9714            // We don't do this here during boot because we can do it all
9715            // at once after scanning all existing packages.
9716            //
9717            // We also do this *before* we perform dexopt on this package, so that
9718            // we can avoid redundant dexopts, and also to make sure we've got the
9719            // code and package path correct.
9720            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
9721        }
9722
9723        if (mFactoryTest && pkg.requestedPermissions.contains(
9724                android.Manifest.permission.FACTORY_TEST)) {
9725            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
9726        }
9727
9728        if (isSystemApp(pkg)) {
9729            pkgSetting.isOrphaned = true;
9730        }
9731
9732        // Take care of first install / last update times.
9733        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
9734        if (currentTime != 0) {
9735            if (pkgSetting.firstInstallTime == 0) {
9736                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
9737            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
9738                pkgSetting.lastUpdateTime = currentTime;
9739            }
9740        } else if (pkgSetting.firstInstallTime == 0) {
9741            // We need *something*.  Take time time stamp of the file.
9742            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
9743        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
9744            if (scanFileTime != pkgSetting.timeStamp) {
9745                // A package on the system image has changed; consider this
9746                // to be an update.
9747                pkgSetting.lastUpdateTime = scanFileTime;
9748            }
9749        }
9750        pkgSetting.setTimeStamp(scanFileTime);
9751
9752        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9753            if (nonMutatedPs != null) {
9754                synchronized (mPackages) {
9755                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
9756                }
9757            }
9758        } else {
9759            final int userId = user == null ? 0 : user.getIdentifier();
9760            // Modify state for the given package setting
9761            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
9762                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
9763            if (pkgSetting.getInstantApp(userId)) {
9764                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
9765            }
9766        }
9767        return pkg;
9768    }
9769
9770    /**
9771     * Applies policy to the parsed package based upon the given policy flags.
9772     * Ensures the package is in a good state.
9773     * <p>
9774     * Implementation detail: This method must NOT have any side effect. It would
9775     * ideally be static, but, it requires locks to read system state.
9776     */
9777    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
9778        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
9779            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
9780            if (pkg.applicationInfo.isDirectBootAware()) {
9781                // we're direct boot aware; set for all components
9782                for (PackageParser.Service s : pkg.services) {
9783                    s.info.encryptionAware = s.info.directBootAware = true;
9784                }
9785                for (PackageParser.Provider p : pkg.providers) {
9786                    p.info.encryptionAware = p.info.directBootAware = true;
9787                }
9788                for (PackageParser.Activity a : pkg.activities) {
9789                    a.info.encryptionAware = a.info.directBootAware = true;
9790                }
9791                for (PackageParser.Activity r : pkg.receivers) {
9792                    r.info.encryptionAware = r.info.directBootAware = true;
9793                }
9794            }
9795        } else {
9796            // Only allow system apps to be flagged as core apps.
9797            pkg.coreApp = false;
9798            // clear flags not applicable to regular apps
9799            pkg.applicationInfo.privateFlags &=
9800                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
9801            pkg.applicationInfo.privateFlags &=
9802                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
9803        }
9804        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
9805
9806        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
9807            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9808        }
9809
9810        if (!isSystemApp(pkg)) {
9811            // Only system apps can use these features.
9812            pkg.mOriginalPackages = null;
9813            pkg.mRealPackage = null;
9814            pkg.mAdoptPermissions = null;
9815        }
9816    }
9817
9818    /**
9819     * Asserts the parsed package is valid according to the given policy. If the
9820     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
9821     * <p>
9822     * Implementation detail: This method must NOT have any side effects. It would
9823     * ideally be static, but, it requires locks to read system state.
9824     *
9825     * @throws PackageManagerException If the package fails any of the validation checks
9826     */
9827    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
9828            throws PackageManagerException {
9829        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
9830            assertCodePolicy(pkg);
9831        }
9832
9833        if (pkg.applicationInfo.getCodePath() == null ||
9834                pkg.applicationInfo.getResourcePath() == null) {
9835            // Bail out. The resource and code paths haven't been set.
9836            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9837                    "Code and resource paths haven't been set correctly");
9838        }
9839
9840        // Make sure we're not adding any bogus keyset info
9841        KeySetManagerService ksms = mSettings.mKeySetManagerService;
9842        ksms.assertScannedPackageValid(pkg);
9843
9844        synchronized (mPackages) {
9845            // The special "android" package can only be defined once
9846            if (pkg.packageName.equals("android")) {
9847                if (mAndroidApplication != null) {
9848                    Slog.w(TAG, "*************************************************");
9849                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
9850                    Slog.w(TAG, " codePath=" + pkg.codePath);
9851                    Slog.w(TAG, "*************************************************");
9852                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9853                            "Core android package being redefined.  Skipping.");
9854                }
9855            }
9856
9857            // A package name must be unique; don't allow duplicates
9858            if (mPackages.containsKey(pkg.packageName)) {
9859                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
9860                        "Application package " + pkg.packageName
9861                        + " already installed.  Skipping duplicate.");
9862            }
9863
9864            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9865                // Static libs have a synthetic package name containing the version
9866                // but we still want the base name to be unique.
9867                if (mPackages.containsKey(pkg.manifestPackageName)) {
9868                    throw new PackageManagerException(
9869                            "Duplicate static shared lib provider package");
9870                }
9871
9872                // Static shared libraries should have at least O target SDK
9873                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
9874                    throw new PackageManagerException(
9875                            "Packages declaring static-shared libs must target O SDK or higher");
9876                }
9877
9878                // Package declaring static a shared lib cannot be instant apps
9879                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
9880                    throw new PackageManagerException(
9881                            "Packages declaring static-shared libs cannot be instant apps");
9882                }
9883
9884                // Package declaring static a shared lib cannot be renamed since the package
9885                // name is synthetic and apps can't code around package manager internals.
9886                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
9887                    throw new PackageManagerException(
9888                            "Packages declaring static-shared libs cannot be renamed");
9889                }
9890
9891                // Package declaring static a shared lib cannot declare child packages
9892                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
9893                    throw new PackageManagerException(
9894                            "Packages declaring static-shared libs cannot have child packages");
9895                }
9896
9897                // Package declaring static a shared lib cannot declare dynamic libs
9898                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
9899                    throw new PackageManagerException(
9900                            "Packages declaring static-shared libs cannot declare dynamic libs");
9901                }
9902
9903                // Package declaring static a shared lib cannot declare shared users
9904                if (pkg.mSharedUserId != null) {
9905                    throw new PackageManagerException(
9906                            "Packages declaring static-shared libs cannot declare shared users");
9907                }
9908
9909                // Static shared libs cannot declare activities
9910                if (!pkg.activities.isEmpty()) {
9911                    throw new PackageManagerException(
9912                            "Static shared libs cannot declare activities");
9913                }
9914
9915                // Static shared libs cannot declare services
9916                if (!pkg.services.isEmpty()) {
9917                    throw new PackageManagerException(
9918                            "Static shared libs cannot declare services");
9919                }
9920
9921                // Static shared libs cannot declare providers
9922                if (!pkg.providers.isEmpty()) {
9923                    throw new PackageManagerException(
9924                            "Static shared libs cannot declare content providers");
9925                }
9926
9927                // Static shared libs cannot declare receivers
9928                if (!pkg.receivers.isEmpty()) {
9929                    throw new PackageManagerException(
9930                            "Static shared libs cannot declare broadcast receivers");
9931                }
9932
9933                // Static shared libs cannot declare permission groups
9934                if (!pkg.permissionGroups.isEmpty()) {
9935                    throw new PackageManagerException(
9936                            "Static shared libs cannot declare permission groups");
9937                }
9938
9939                // Static shared libs cannot declare permissions
9940                if (!pkg.permissions.isEmpty()) {
9941                    throw new PackageManagerException(
9942                            "Static shared libs cannot declare permissions");
9943                }
9944
9945                // Static shared libs cannot declare protected broadcasts
9946                if (pkg.protectedBroadcasts != null) {
9947                    throw new PackageManagerException(
9948                            "Static shared libs cannot declare protected broadcasts");
9949                }
9950
9951                // Static shared libs cannot be overlay targets
9952                if (pkg.mOverlayTarget != null) {
9953                    throw new PackageManagerException(
9954                            "Static shared libs cannot be overlay targets");
9955                }
9956
9957                // The version codes must be ordered as lib versions
9958                int minVersionCode = Integer.MIN_VALUE;
9959                int maxVersionCode = Integer.MAX_VALUE;
9960
9961                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9962                        pkg.staticSharedLibName);
9963                if (versionedLib != null) {
9964                    final int versionCount = versionedLib.size();
9965                    for (int i = 0; i < versionCount; i++) {
9966                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
9967                        // TODO: We will change version code to long, so in the new API it is long
9968                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
9969                                .getVersionCode();
9970                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
9971                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
9972                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
9973                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
9974                        } else {
9975                            minVersionCode = maxVersionCode = libVersionCode;
9976                            break;
9977                        }
9978                    }
9979                }
9980                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
9981                    throw new PackageManagerException("Static shared"
9982                            + " lib version codes must be ordered as lib versions");
9983                }
9984            }
9985
9986            // Only privileged apps and updated privileged apps can add child packages.
9987            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
9988                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
9989                    throw new PackageManagerException("Only privileged apps can add child "
9990                            + "packages. Ignoring package " + pkg.packageName);
9991                }
9992                final int childCount = pkg.childPackages.size();
9993                for (int i = 0; i < childCount; i++) {
9994                    PackageParser.Package childPkg = pkg.childPackages.get(i);
9995                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
9996                            childPkg.packageName)) {
9997                        throw new PackageManagerException("Can't override child of "
9998                                + "another disabled app. Ignoring package " + pkg.packageName);
9999                    }
10000                }
10001            }
10002
10003            // If we're only installing presumed-existing packages, require that the
10004            // scanned APK is both already known and at the path previously established
10005            // for it.  Previously unknown packages we pick up normally, but if we have an
10006            // a priori expectation about this package's install presence, enforce it.
10007            // With a singular exception for new system packages. When an OTA contains
10008            // a new system package, we allow the codepath to change from a system location
10009            // to the user-installed location. If we don't allow this change, any newer,
10010            // user-installed version of the application will be ignored.
10011            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10012                if (mExpectingBetter.containsKey(pkg.packageName)) {
10013                    logCriticalInfo(Log.WARN,
10014                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10015                } else {
10016                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10017                    if (known != null) {
10018                        if (DEBUG_PACKAGE_SCANNING) {
10019                            Log.d(TAG, "Examining " + pkg.codePath
10020                                    + " and requiring known paths " + known.codePathString
10021                                    + " & " + known.resourcePathString);
10022                        }
10023                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10024                                || !pkg.applicationInfo.getResourcePath().equals(
10025                                        known.resourcePathString)) {
10026                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10027                                    "Application package " + pkg.packageName
10028                                    + " found at " + pkg.applicationInfo.getCodePath()
10029                                    + " but expected at " + known.codePathString
10030                                    + "; ignoring.");
10031                        }
10032                    }
10033                }
10034            }
10035
10036            // Verify that this new package doesn't have any content providers
10037            // that conflict with existing packages.  Only do this if the
10038            // package isn't already installed, since we don't want to break
10039            // things that are installed.
10040            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10041                final int N = pkg.providers.size();
10042                int i;
10043                for (i=0; i<N; i++) {
10044                    PackageParser.Provider p = pkg.providers.get(i);
10045                    if (p.info.authority != null) {
10046                        String names[] = p.info.authority.split(";");
10047                        for (int j = 0; j < names.length; j++) {
10048                            if (mProvidersByAuthority.containsKey(names[j])) {
10049                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10050                                final String otherPackageName =
10051                                        ((other != null && other.getComponentName() != null) ?
10052                                                other.getComponentName().getPackageName() : "?");
10053                                throw new PackageManagerException(
10054                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10055                                        "Can't install because provider name " + names[j]
10056                                                + " (in package " + pkg.applicationInfo.packageName
10057                                                + ") is already used by " + otherPackageName);
10058                            }
10059                        }
10060                    }
10061                }
10062            }
10063        }
10064    }
10065
10066    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10067            int type, String declaringPackageName, int declaringVersionCode) {
10068        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10069        if (versionedLib == null) {
10070            versionedLib = new SparseArray<>();
10071            mSharedLibraries.put(name, versionedLib);
10072            if (type == SharedLibraryInfo.TYPE_STATIC) {
10073                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10074            }
10075        } else if (versionedLib.indexOfKey(version) >= 0) {
10076            return false;
10077        }
10078        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10079                version, type, declaringPackageName, declaringVersionCode);
10080        versionedLib.put(version, libEntry);
10081        return true;
10082    }
10083
10084    private boolean removeSharedLibraryLPw(String name, int version) {
10085        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10086        if (versionedLib == null) {
10087            return false;
10088        }
10089        final int libIdx = versionedLib.indexOfKey(version);
10090        if (libIdx < 0) {
10091            return false;
10092        }
10093        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10094        versionedLib.remove(version);
10095        if (versionedLib.size() <= 0) {
10096            mSharedLibraries.remove(name);
10097            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10098                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10099                        .getPackageName());
10100            }
10101        }
10102        return true;
10103    }
10104
10105    /**
10106     * Adds a scanned package to the system. When this method is finished, the package will
10107     * be available for query, resolution, etc...
10108     */
10109    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10110            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10111        final String pkgName = pkg.packageName;
10112        if (mCustomResolverComponentName != null &&
10113                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10114            setUpCustomResolverActivity(pkg);
10115        }
10116
10117        if (pkg.packageName.equals("android")) {
10118            synchronized (mPackages) {
10119                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10120                    // Set up information for our fall-back user intent resolution activity.
10121                    mPlatformPackage = pkg;
10122                    pkg.mVersionCode = mSdkVersion;
10123                    mAndroidApplication = pkg.applicationInfo;
10124                    if (!mResolverReplaced) {
10125                        mResolveActivity.applicationInfo = mAndroidApplication;
10126                        mResolveActivity.name = ResolverActivity.class.getName();
10127                        mResolveActivity.packageName = mAndroidApplication.packageName;
10128                        mResolveActivity.processName = "system:ui";
10129                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10130                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10131                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10132                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10133                        mResolveActivity.exported = true;
10134                        mResolveActivity.enabled = true;
10135                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10136                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10137                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10138                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10139                                | ActivityInfo.CONFIG_ORIENTATION
10140                                | ActivityInfo.CONFIG_KEYBOARD
10141                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10142                        mResolveInfo.activityInfo = mResolveActivity;
10143                        mResolveInfo.priority = 0;
10144                        mResolveInfo.preferredOrder = 0;
10145                        mResolveInfo.match = 0;
10146                        mResolveComponentName = new ComponentName(
10147                                mAndroidApplication.packageName, mResolveActivity.name);
10148                    }
10149                }
10150            }
10151        }
10152
10153        ArrayList<PackageParser.Package> clientLibPkgs = null;
10154        // writer
10155        synchronized (mPackages) {
10156            boolean hasStaticSharedLibs = false;
10157
10158            // Any app can add new static shared libraries
10159            if (pkg.staticSharedLibName != null) {
10160                // Static shared libs don't allow renaming as they have synthetic package
10161                // names to allow install of multiple versions, so use name from manifest.
10162                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10163                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10164                        pkg.manifestPackageName, pkg.mVersionCode)) {
10165                    hasStaticSharedLibs = true;
10166                } else {
10167                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10168                                + pkg.staticSharedLibName + " already exists; skipping");
10169                }
10170                // Static shared libs cannot be updated once installed since they
10171                // use synthetic package name which includes the version code, so
10172                // not need to update other packages's shared lib dependencies.
10173            }
10174
10175            if (!hasStaticSharedLibs
10176                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10177                // Only system apps can add new dynamic shared libraries.
10178                if (pkg.libraryNames != null) {
10179                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10180                        String name = pkg.libraryNames.get(i);
10181                        boolean allowed = false;
10182                        if (pkg.isUpdatedSystemApp()) {
10183                            // New library entries can only be added through the
10184                            // system image.  This is important to get rid of a lot
10185                            // of nasty edge cases: for example if we allowed a non-
10186                            // system update of the app to add a library, then uninstalling
10187                            // the update would make the library go away, and assumptions
10188                            // we made such as through app install filtering would now
10189                            // have allowed apps on the device which aren't compatible
10190                            // with it.  Better to just have the restriction here, be
10191                            // conservative, and create many fewer cases that can negatively
10192                            // impact the user experience.
10193                            final PackageSetting sysPs = mSettings
10194                                    .getDisabledSystemPkgLPr(pkg.packageName);
10195                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10196                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10197                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10198                                        allowed = true;
10199                                        break;
10200                                    }
10201                                }
10202                            }
10203                        } else {
10204                            allowed = true;
10205                        }
10206                        if (allowed) {
10207                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10208                                    SharedLibraryInfo.VERSION_UNDEFINED,
10209                                    SharedLibraryInfo.TYPE_DYNAMIC,
10210                                    pkg.packageName, pkg.mVersionCode)) {
10211                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10212                                        + name + " already exists; skipping");
10213                            }
10214                        } else {
10215                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10216                                    + name + " that is not declared on system image; skipping");
10217                        }
10218                    }
10219
10220                    if ((scanFlags & SCAN_BOOTING) == 0) {
10221                        // If we are not booting, we need to update any applications
10222                        // that are clients of our shared library.  If we are booting,
10223                        // this will all be done once the scan is complete.
10224                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10225                    }
10226                }
10227            }
10228        }
10229
10230        if ((scanFlags & SCAN_BOOTING) != 0) {
10231            // No apps can run during boot scan, so they don't need to be frozen
10232        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10233            // Caller asked to not kill app, so it's probably not frozen
10234        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10235            // Caller asked us to ignore frozen check for some reason; they
10236            // probably didn't know the package name
10237        } else {
10238            // We're doing major surgery on this package, so it better be frozen
10239            // right now to keep it from launching
10240            checkPackageFrozen(pkgName);
10241        }
10242
10243        // Also need to kill any apps that are dependent on the library.
10244        if (clientLibPkgs != null) {
10245            for (int i=0; i<clientLibPkgs.size(); i++) {
10246                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10247                killApplication(clientPkg.applicationInfo.packageName,
10248                        clientPkg.applicationInfo.uid, "update lib");
10249            }
10250        }
10251
10252        // writer
10253        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10254
10255        synchronized (mPackages) {
10256            // We don't expect installation to fail beyond this point
10257
10258            // Add the new setting to mSettings
10259            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10260            // Add the new setting to mPackages
10261            mPackages.put(pkg.applicationInfo.packageName, pkg);
10262            // Make sure we don't accidentally delete its data.
10263            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10264            while (iter.hasNext()) {
10265                PackageCleanItem item = iter.next();
10266                if (pkgName.equals(item.packageName)) {
10267                    iter.remove();
10268                }
10269            }
10270
10271            // Add the package's KeySets to the global KeySetManagerService
10272            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10273            ksms.addScannedPackageLPw(pkg);
10274
10275            int N = pkg.providers.size();
10276            StringBuilder r = null;
10277            int i;
10278            for (i=0; i<N; i++) {
10279                PackageParser.Provider p = pkg.providers.get(i);
10280                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10281                        p.info.processName);
10282                mProviders.addProvider(p);
10283                p.syncable = p.info.isSyncable;
10284                if (p.info.authority != null) {
10285                    String names[] = p.info.authority.split(";");
10286                    p.info.authority = null;
10287                    for (int j = 0; j < names.length; j++) {
10288                        if (j == 1 && p.syncable) {
10289                            // We only want the first authority for a provider to possibly be
10290                            // syncable, so if we already added this provider using a different
10291                            // authority clear the syncable flag. We copy the provider before
10292                            // changing it because the mProviders object contains a reference
10293                            // to a provider that we don't want to change.
10294                            // Only do this for the second authority since the resulting provider
10295                            // object can be the same for all future authorities for this provider.
10296                            p = new PackageParser.Provider(p);
10297                            p.syncable = false;
10298                        }
10299                        if (!mProvidersByAuthority.containsKey(names[j])) {
10300                            mProvidersByAuthority.put(names[j], p);
10301                            if (p.info.authority == null) {
10302                                p.info.authority = names[j];
10303                            } else {
10304                                p.info.authority = p.info.authority + ";" + names[j];
10305                            }
10306                            if (DEBUG_PACKAGE_SCANNING) {
10307                                if (chatty)
10308                                    Log.d(TAG, "Registered content provider: " + names[j]
10309                                            + ", className = " + p.info.name + ", isSyncable = "
10310                                            + p.info.isSyncable);
10311                            }
10312                        } else {
10313                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10314                            Slog.w(TAG, "Skipping provider name " + names[j] +
10315                                    " (in package " + pkg.applicationInfo.packageName +
10316                                    "): name already used by "
10317                                    + ((other != null && other.getComponentName() != null)
10318                                            ? other.getComponentName().getPackageName() : "?"));
10319                        }
10320                    }
10321                }
10322                if (chatty) {
10323                    if (r == null) {
10324                        r = new StringBuilder(256);
10325                    } else {
10326                        r.append(' ');
10327                    }
10328                    r.append(p.info.name);
10329                }
10330            }
10331            if (r != null) {
10332                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10333            }
10334
10335            N = pkg.services.size();
10336            r = null;
10337            for (i=0; i<N; i++) {
10338                PackageParser.Service s = pkg.services.get(i);
10339                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10340                        s.info.processName);
10341                mServices.addService(s);
10342                if (chatty) {
10343                    if (r == null) {
10344                        r = new StringBuilder(256);
10345                    } else {
10346                        r.append(' ');
10347                    }
10348                    r.append(s.info.name);
10349                }
10350            }
10351            if (r != null) {
10352                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10353            }
10354
10355            N = pkg.receivers.size();
10356            r = null;
10357            for (i=0; i<N; i++) {
10358                PackageParser.Activity a = pkg.receivers.get(i);
10359                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10360                        a.info.processName);
10361                mReceivers.addActivity(a, "receiver");
10362                if (chatty) {
10363                    if (r == null) {
10364                        r = new StringBuilder(256);
10365                    } else {
10366                        r.append(' ');
10367                    }
10368                    r.append(a.info.name);
10369                }
10370            }
10371            if (r != null) {
10372                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10373            }
10374
10375            N = pkg.activities.size();
10376            r = null;
10377            for (i=0; i<N; i++) {
10378                PackageParser.Activity a = pkg.activities.get(i);
10379                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10380                        a.info.processName);
10381                mActivities.addActivity(a, "activity");
10382                if (chatty) {
10383                    if (r == null) {
10384                        r = new StringBuilder(256);
10385                    } else {
10386                        r.append(' ');
10387                    }
10388                    r.append(a.info.name);
10389                }
10390            }
10391            if (r != null) {
10392                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10393            }
10394
10395            N = pkg.permissionGroups.size();
10396            r = null;
10397            for (i=0; i<N; i++) {
10398                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10399                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10400                final String curPackageName = cur == null ? null : cur.info.packageName;
10401                // Dont allow ephemeral apps to define new permission groups.
10402                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10403                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10404                            + pg.info.packageName
10405                            + " ignored: instant apps cannot define new permission groups.");
10406                    continue;
10407                }
10408                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10409                if (cur == null || isPackageUpdate) {
10410                    mPermissionGroups.put(pg.info.name, pg);
10411                    if (chatty) {
10412                        if (r == null) {
10413                            r = new StringBuilder(256);
10414                        } else {
10415                            r.append(' ');
10416                        }
10417                        if (isPackageUpdate) {
10418                            r.append("UPD:");
10419                        }
10420                        r.append(pg.info.name);
10421                    }
10422                } else {
10423                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10424                            + pg.info.packageName + " ignored: original from "
10425                            + cur.info.packageName);
10426                    if (chatty) {
10427                        if (r == null) {
10428                            r = new StringBuilder(256);
10429                        } else {
10430                            r.append(' ');
10431                        }
10432                        r.append("DUP:");
10433                        r.append(pg.info.name);
10434                    }
10435                }
10436            }
10437            if (r != null) {
10438                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10439            }
10440
10441            N = pkg.permissions.size();
10442            r = null;
10443            for (i=0; i<N; i++) {
10444                PackageParser.Permission p = pkg.permissions.get(i);
10445
10446                // Dont allow ephemeral apps to define new permissions.
10447                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10448                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10449                            + p.info.packageName
10450                            + " ignored: instant apps cannot define new permissions.");
10451                    continue;
10452                }
10453
10454                // Assume by default that we did not install this permission into the system.
10455                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10456
10457                // Now that permission groups have a special meaning, we ignore permission
10458                // groups for legacy apps to prevent unexpected behavior. In particular,
10459                // permissions for one app being granted to someone just becase they happen
10460                // to be in a group defined by another app (before this had no implications).
10461                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10462                    p.group = mPermissionGroups.get(p.info.group);
10463                    // Warn for a permission in an unknown group.
10464                    if (p.info.group != null && p.group == null) {
10465                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10466                                + p.info.packageName + " in an unknown group " + p.info.group);
10467                    }
10468                }
10469
10470                ArrayMap<String, BasePermission> permissionMap =
10471                        p.tree ? mSettings.mPermissionTrees
10472                                : mSettings.mPermissions;
10473                BasePermission bp = permissionMap.get(p.info.name);
10474
10475                // Allow system apps to redefine non-system permissions
10476                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10477                    final boolean currentOwnerIsSystem = (bp.perm != null
10478                            && isSystemApp(bp.perm.owner));
10479                    if (isSystemApp(p.owner)) {
10480                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10481                            // It's a built-in permission and no owner, take ownership now
10482                            bp.packageSetting = pkgSetting;
10483                            bp.perm = p;
10484                            bp.uid = pkg.applicationInfo.uid;
10485                            bp.sourcePackage = p.info.packageName;
10486                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10487                        } else if (!currentOwnerIsSystem) {
10488                            String msg = "New decl " + p.owner + " of permission  "
10489                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10490                            reportSettingsProblem(Log.WARN, msg);
10491                            bp = null;
10492                        }
10493                    }
10494                }
10495
10496                if (bp == null) {
10497                    bp = new BasePermission(p.info.name, p.info.packageName,
10498                            BasePermission.TYPE_NORMAL);
10499                    permissionMap.put(p.info.name, bp);
10500                }
10501
10502                if (bp.perm == null) {
10503                    if (bp.sourcePackage == null
10504                            || bp.sourcePackage.equals(p.info.packageName)) {
10505                        BasePermission tree = findPermissionTreeLP(p.info.name);
10506                        if (tree == null
10507                                || tree.sourcePackage.equals(p.info.packageName)) {
10508                            bp.packageSetting = pkgSetting;
10509                            bp.perm = p;
10510                            bp.uid = pkg.applicationInfo.uid;
10511                            bp.sourcePackage = p.info.packageName;
10512                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10513                            if (chatty) {
10514                                if (r == null) {
10515                                    r = new StringBuilder(256);
10516                                } else {
10517                                    r.append(' ');
10518                                }
10519                                r.append(p.info.name);
10520                            }
10521                        } else {
10522                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10523                                    + p.info.packageName + " ignored: base tree "
10524                                    + tree.name + " is from package "
10525                                    + tree.sourcePackage);
10526                        }
10527                    } else {
10528                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10529                                + p.info.packageName + " ignored: original from "
10530                                + bp.sourcePackage);
10531                    }
10532                } else if (chatty) {
10533                    if (r == null) {
10534                        r = new StringBuilder(256);
10535                    } else {
10536                        r.append(' ');
10537                    }
10538                    r.append("DUP:");
10539                    r.append(p.info.name);
10540                }
10541                if (bp.perm == p) {
10542                    bp.protectionLevel = p.info.protectionLevel;
10543                }
10544            }
10545
10546            if (r != null) {
10547                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10548            }
10549
10550            N = pkg.instrumentation.size();
10551            r = null;
10552            for (i=0; i<N; i++) {
10553                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10554                a.info.packageName = pkg.applicationInfo.packageName;
10555                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10556                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10557                a.info.splitNames = pkg.splitNames;
10558                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10559                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10560                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10561                a.info.dataDir = pkg.applicationInfo.dataDir;
10562                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10563                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10564                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10565                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10566                mInstrumentation.put(a.getComponentName(), a);
10567                if (chatty) {
10568                    if (r == null) {
10569                        r = new StringBuilder(256);
10570                    } else {
10571                        r.append(' ');
10572                    }
10573                    r.append(a.info.name);
10574                }
10575            }
10576            if (r != null) {
10577                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10578            }
10579
10580            if (pkg.protectedBroadcasts != null) {
10581                N = pkg.protectedBroadcasts.size();
10582                for (i=0; i<N; i++) {
10583                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10584                }
10585            }
10586        }
10587
10588        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10589    }
10590
10591    /**
10592     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10593     * is derived purely on the basis of the contents of {@code scanFile} and
10594     * {@code cpuAbiOverride}.
10595     *
10596     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10597     */
10598    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10599                                 String cpuAbiOverride, boolean extractLibs,
10600                                 File appLib32InstallDir)
10601            throws PackageManagerException {
10602        // Give ourselves some initial paths; we'll come back for another
10603        // pass once we've determined ABI below.
10604        setNativeLibraryPaths(pkg, appLib32InstallDir);
10605
10606        // We would never need to extract libs for forward-locked and external packages,
10607        // since the container service will do it for us. We shouldn't attempt to
10608        // extract libs from system app when it was not updated.
10609        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10610                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10611            extractLibs = false;
10612        }
10613
10614        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10615        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10616
10617        NativeLibraryHelper.Handle handle = null;
10618        try {
10619            handle = NativeLibraryHelper.Handle.create(pkg);
10620            // TODO(multiArch): This can be null for apps that didn't go through the
10621            // usual installation process. We can calculate it again, like we
10622            // do during install time.
10623            //
10624            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10625            // unnecessary.
10626            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10627
10628            // Null out the abis so that they can be recalculated.
10629            pkg.applicationInfo.primaryCpuAbi = null;
10630            pkg.applicationInfo.secondaryCpuAbi = null;
10631            if (isMultiArch(pkg.applicationInfo)) {
10632                // Warn if we've set an abiOverride for multi-lib packages..
10633                // By definition, we need to copy both 32 and 64 bit libraries for
10634                // such packages.
10635                if (pkg.cpuAbiOverride != null
10636                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10637                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10638                }
10639
10640                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10641                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10642                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10643                    if (extractLibs) {
10644                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10645                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10646                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10647                                useIsaSpecificSubdirs);
10648                    } else {
10649                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10650                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10651                    }
10652                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10653                }
10654
10655                maybeThrowExceptionForMultiArchCopy(
10656                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10657
10658                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10659                    if (extractLibs) {
10660                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10661                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10662                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10663                                useIsaSpecificSubdirs);
10664                    } else {
10665                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10666                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10667                    }
10668                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10669                }
10670
10671                maybeThrowExceptionForMultiArchCopy(
10672                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10673
10674                if (abi64 >= 0) {
10675                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10676                }
10677
10678                if (abi32 >= 0) {
10679                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
10680                    if (abi64 >= 0) {
10681                        if (pkg.use32bitAbi) {
10682                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
10683                            pkg.applicationInfo.primaryCpuAbi = abi;
10684                        } else {
10685                            pkg.applicationInfo.secondaryCpuAbi = abi;
10686                        }
10687                    } else {
10688                        pkg.applicationInfo.primaryCpuAbi = abi;
10689                    }
10690                }
10691
10692            } else {
10693                String[] abiList = (cpuAbiOverride != null) ?
10694                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
10695
10696                // Enable gross and lame hacks for apps that are built with old
10697                // SDK tools. We must scan their APKs for renderscript bitcode and
10698                // not launch them if it's present. Don't bother checking on devices
10699                // that don't have 64 bit support.
10700                boolean needsRenderScriptOverride = false;
10701                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
10702                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
10703                    abiList = Build.SUPPORTED_32_BIT_ABIS;
10704                    needsRenderScriptOverride = true;
10705                }
10706
10707                final int copyRet;
10708                if (extractLibs) {
10709                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10710                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10711                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
10712                } else {
10713                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10714                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
10715                }
10716                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10717
10718                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
10719                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10720                            "Error unpackaging native libs for app, errorCode=" + copyRet);
10721                }
10722
10723                if (copyRet >= 0) {
10724                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
10725                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
10726                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
10727                } else if (needsRenderScriptOverride) {
10728                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
10729                }
10730            }
10731        } catch (IOException ioe) {
10732            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
10733        } finally {
10734            IoUtils.closeQuietly(handle);
10735        }
10736
10737        // Now that we've calculated the ABIs and determined if it's an internal app,
10738        // we will go ahead and populate the nativeLibraryPath.
10739        setNativeLibraryPaths(pkg, appLib32InstallDir);
10740    }
10741
10742    /**
10743     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
10744     * i.e, so that all packages can be run inside a single process if required.
10745     *
10746     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
10747     * this function will either try and make the ABI for all packages in {@code packagesForUser}
10748     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
10749     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
10750     * updating a package that belongs to a shared user.
10751     *
10752     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
10753     * adds unnecessary complexity.
10754     */
10755    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
10756            PackageParser.Package scannedPackage) {
10757        String requiredInstructionSet = null;
10758        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
10759            requiredInstructionSet = VMRuntime.getInstructionSet(
10760                     scannedPackage.applicationInfo.primaryCpuAbi);
10761        }
10762
10763        PackageSetting requirer = null;
10764        for (PackageSetting ps : packagesForUser) {
10765            // If packagesForUser contains scannedPackage, we skip it. This will happen
10766            // when scannedPackage is an update of an existing package. Without this check,
10767            // we will never be able to change the ABI of any package belonging to a shared
10768            // user, even if it's compatible with other packages.
10769            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10770                if (ps.primaryCpuAbiString == null) {
10771                    continue;
10772                }
10773
10774                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
10775                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
10776                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
10777                    // this but there's not much we can do.
10778                    String errorMessage = "Instruction set mismatch, "
10779                            + ((requirer == null) ? "[caller]" : requirer)
10780                            + " requires " + requiredInstructionSet + " whereas " + ps
10781                            + " requires " + instructionSet;
10782                    Slog.w(TAG, errorMessage);
10783                }
10784
10785                if (requiredInstructionSet == null) {
10786                    requiredInstructionSet = instructionSet;
10787                    requirer = ps;
10788                }
10789            }
10790        }
10791
10792        if (requiredInstructionSet != null) {
10793            String adjustedAbi;
10794            if (requirer != null) {
10795                // requirer != null implies that either scannedPackage was null or that scannedPackage
10796                // did not require an ABI, in which case we have to adjust scannedPackage to match
10797                // the ABI of the set (which is the same as requirer's ABI)
10798                adjustedAbi = requirer.primaryCpuAbiString;
10799                if (scannedPackage != null) {
10800                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
10801                }
10802            } else {
10803                // requirer == null implies that we're updating all ABIs in the set to
10804                // match scannedPackage.
10805                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
10806            }
10807
10808            for (PackageSetting ps : packagesForUser) {
10809                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
10810                    if (ps.primaryCpuAbiString != null) {
10811                        continue;
10812                    }
10813
10814                    ps.primaryCpuAbiString = adjustedAbi;
10815                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
10816                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
10817                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
10818                        Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
10819                                + " (requirer="
10820                                + (requirer != null ? requirer.pkg : "null")
10821                                + ", scannedPackage="
10822                                + (scannedPackage != null ? scannedPackage : "null")
10823                                + ")");
10824                        try {
10825                            mInstaller.rmdex(ps.codePathString,
10826                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
10827                        } catch (InstallerException ignored) {
10828                        }
10829                    }
10830                }
10831            }
10832        }
10833    }
10834
10835    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
10836        synchronized (mPackages) {
10837            mResolverReplaced = true;
10838            // Set up information for custom user intent resolution activity.
10839            mResolveActivity.applicationInfo = pkg.applicationInfo;
10840            mResolveActivity.name = mCustomResolverComponentName.getClassName();
10841            mResolveActivity.packageName = pkg.applicationInfo.packageName;
10842            mResolveActivity.processName = pkg.applicationInfo.packageName;
10843            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10844            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
10845                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10846            mResolveActivity.theme = 0;
10847            mResolveActivity.exported = true;
10848            mResolveActivity.enabled = true;
10849            mResolveInfo.activityInfo = mResolveActivity;
10850            mResolveInfo.priority = 0;
10851            mResolveInfo.preferredOrder = 0;
10852            mResolveInfo.match = 0;
10853            mResolveComponentName = mCustomResolverComponentName;
10854            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
10855                    mResolveComponentName);
10856        }
10857    }
10858
10859    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
10860        if (installerActivity == null) {
10861            if (DEBUG_EPHEMERAL) {
10862                Slog.d(TAG, "Clear ephemeral installer activity");
10863            }
10864            mInstantAppInstallerActivity = null;
10865            return;
10866        }
10867
10868        if (DEBUG_EPHEMERAL) {
10869            Slog.d(TAG, "Set ephemeral installer activity: "
10870                    + installerActivity.getComponentName());
10871        }
10872        // Set up information for ephemeral installer activity
10873        mInstantAppInstallerActivity = installerActivity;
10874        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
10875                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
10876        mInstantAppInstallerActivity.exported = true;
10877        mInstantAppInstallerActivity.enabled = true;
10878        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
10879        mInstantAppInstallerInfo.priority = 0;
10880        mInstantAppInstallerInfo.preferredOrder = 1;
10881        mInstantAppInstallerInfo.isDefault = true;
10882        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
10883                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
10884    }
10885
10886    private static String calculateBundledApkRoot(final String codePathString) {
10887        final File codePath = new File(codePathString);
10888        final File codeRoot;
10889        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
10890            codeRoot = Environment.getRootDirectory();
10891        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
10892            codeRoot = Environment.getOemDirectory();
10893        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
10894            codeRoot = Environment.getVendorDirectory();
10895        } else {
10896            // Unrecognized code path; take its top real segment as the apk root:
10897            // e.g. /something/app/blah.apk => /something
10898            try {
10899                File f = codePath.getCanonicalFile();
10900                File parent = f.getParentFile();    // non-null because codePath is a file
10901                File tmp;
10902                while ((tmp = parent.getParentFile()) != null) {
10903                    f = parent;
10904                    parent = tmp;
10905                }
10906                codeRoot = f;
10907                Slog.w(TAG, "Unrecognized code path "
10908                        + codePath + " - using " + codeRoot);
10909            } catch (IOException e) {
10910                // Can't canonicalize the code path -- shenanigans?
10911                Slog.w(TAG, "Can't canonicalize code path " + codePath);
10912                return Environment.getRootDirectory().getPath();
10913            }
10914        }
10915        return codeRoot.getPath();
10916    }
10917
10918    /**
10919     * Derive and set the location of native libraries for the given package,
10920     * which varies depending on where and how the package was installed.
10921     */
10922    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
10923        final ApplicationInfo info = pkg.applicationInfo;
10924        final String codePath = pkg.codePath;
10925        final File codeFile = new File(codePath);
10926        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
10927        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
10928
10929        info.nativeLibraryRootDir = null;
10930        info.nativeLibraryRootRequiresIsa = false;
10931        info.nativeLibraryDir = null;
10932        info.secondaryNativeLibraryDir = null;
10933
10934        if (isApkFile(codeFile)) {
10935            // Monolithic install
10936            if (bundledApp) {
10937                // If "/system/lib64/apkname" exists, assume that is the per-package
10938                // native library directory to use; otherwise use "/system/lib/apkname".
10939                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
10940                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
10941                        getPrimaryInstructionSet(info));
10942
10943                // This is a bundled system app so choose the path based on the ABI.
10944                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
10945                // is just the default path.
10946                final String apkName = deriveCodePathName(codePath);
10947                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
10948                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
10949                        apkName).getAbsolutePath();
10950
10951                if (info.secondaryCpuAbi != null) {
10952                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
10953                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
10954                            secondaryLibDir, apkName).getAbsolutePath();
10955                }
10956            } else if (asecApp) {
10957                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
10958                        .getAbsolutePath();
10959            } else {
10960                final String apkName = deriveCodePathName(codePath);
10961                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
10962                        .getAbsolutePath();
10963            }
10964
10965            info.nativeLibraryRootRequiresIsa = false;
10966            info.nativeLibraryDir = info.nativeLibraryRootDir;
10967        } else {
10968            // Cluster install
10969            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
10970            info.nativeLibraryRootRequiresIsa = true;
10971
10972            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
10973                    getPrimaryInstructionSet(info)).getAbsolutePath();
10974
10975            if (info.secondaryCpuAbi != null) {
10976                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
10977                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
10978            }
10979        }
10980    }
10981
10982    /**
10983     * Calculate the abis and roots for a bundled app. These can uniquely
10984     * be determined from the contents of the system partition, i.e whether
10985     * it contains 64 or 32 bit shared libraries etc. We do not validate any
10986     * of this information, and instead assume that the system was built
10987     * sensibly.
10988     */
10989    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
10990                                           PackageSetting pkgSetting) {
10991        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
10992
10993        // If "/system/lib64/apkname" exists, assume that is the per-package
10994        // native library directory to use; otherwise use "/system/lib/apkname".
10995        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
10996        setBundledAppAbi(pkg, apkRoot, apkName);
10997        // pkgSetting might be null during rescan following uninstall of updates
10998        // to a bundled app, so accommodate that possibility.  The settings in
10999        // that case will be established later from the parsed package.
11000        //
11001        // If the settings aren't null, sync them up with what we've just derived.
11002        // note that apkRoot isn't stored in the package settings.
11003        if (pkgSetting != null) {
11004            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11005            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11006        }
11007    }
11008
11009    /**
11010     * Deduces the ABI of a bundled app and sets the relevant fields on the
11011     * parsed pkg object.
11012     *
11013     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11014     *        under which system libraries are installed.
11015     * @param apkName the name of the installed package.
11016     */
11017    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11018        final File codeFile = new File(pkg.codePath);
11019
11020        final boolean has64BitLibs;
11021        final boolean has32BitLibs;
11022        if (isApkFile(codeFile)) {
11023            // Monolithic install
11024            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11025            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11026        } else {
11027            // Cluster install
11028            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11029            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11030                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11031                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11032                has64BitLibs = (new File(rootDir, isa)).exists();
11033            } else {
11034                has64BitLibs = false;
11035            }
11036            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11037                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11038                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11039                has32BitLibs = (new File(rootDir, isa)).exists();
11040            } else {
11041                has32BitLibs = false;
11042            }
11043        }
11044
11045        if (has64BitLibs && !has32BitLibs) {
11046            // The package has 64 bit libs, but not 32 bit libs. Its primary
11047            // ABI should be 64 bit. We can safely assume here that the bundled
11048            // native libraries correspond to the most preferred ABI in the list.
11049
11050            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11051            pkg.applicationInfo.secondaryCpuAbi = null;
11052        } else if (has32BitLibs && !has64BitLibs) {
11053            // The package has 32 bit libs but not 64 bit libs. Its primary
11054            // ABI should be 32 bit.
11055
11056            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11057            pkg.applicationInfo.secondaryCpuAbi = null;
11058        } else if (has32BitLibs && has64BitLibs) {
11059            // The application has both 64 and 32 bit bundled libraries. We check
11060            // here that the app declares multiArch support, and warn if it doesn't.
11061            //
11062            // We will be lenient here and record both ABIs. The primary will be the
11063            // ABI that's higher on the list, i.e, a device that's configured to prefer
11064            // 64 bit apps will see a 64 bit primary ABI,
11065
11066            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11067                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11068            }
11069
11070            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11071                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11072                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11073            } else {
11074                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11075                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11076            }
11077        } else {
11078            pkg.applicationInfo.primaryCpuAbi = null;
11079            pkg.applicationInfo.secondaryCpuAbi = null;
11080        }
11081    }
11082
11083    private void killApplication(String pkgName, int appId, String reason) {
11084        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11085    }
11086
11087    private void killApplication(String pkgName, int appId, int userId, String reason) {
11088        // Request the ActivityManager to kill the process(only for existing packages)
11089        // so that we do not end up in a confused state while the user is still using the older
11090        // version of the application while the new one gets installed.
11091        final long token = Binder.clearCallingIdentity();
11092        try {
11093            IActivityManager am = ActivityManager.getService();
11094            if (am != null) {
11095                try {
11096                    am.killApplication(pkgName, appId, userId, reason);
11097                } catch (RemoteException e) {
11098                }
11099            }
11100        } finally {
11101            Binder.restoreCallingIdentity(token);
11102        }
11103    }
11104
11105    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11106        // Remove the parent package setting
11107        PackageSetting ps = (PackageSetting) pkg.mExtras;
11108        if (ps != null) {
11109            removePackageLI(ps, chatty);
11110        }
11111        // Remove the child package setting
11112        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11113        for (int i = 0; i < childCount; i++) {
11114            PackageParser.Package childPkg = pkg.childPackages.get(i);
11115            ps = (PackageSetting) childPkg.mExtras;
11116            if (ps != null) {
11117                removePackageLI(ps, chatty);
11118            }
11119        }
11120    }
11121
11122    void removePackageLI(PackageSetting ps, boolean chatty) {
11123        if (DEBUG_INSTALL) {
11124            if (chatty)
11125                Log.d(TAG, "Removing package " + ps.name);
11126        }
11127
11128        // writer
11129        synchronized (mPackages) {
11130            mPackages.remove(ps.name);
11131            final PackageParser.Package pkg = ps.pkg;
11132            if (pkg != null) {
11133                cleanPackageDataStructuresLILPw(pkg, chatty);
11134            }
11135        }
11136    }
11137
11138    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11139        if (DEBUG_INSTALL) {
11140            if (chatty)
11141                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11142        }
11143
11144        // writer
11145        synchronized (mPackages) {
11146            // Remove the parent package
11147            mPackages.remove(pkg.applicationInfo.packageName);
11148            cleanPackageDataStructuresLILPw(pkg, chatty);
11149
11150            // Remove the child packages
11151            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11152            for (int i = 0; i < childCount; i++) {
11153                PackageParser.Package childPkg = pkg.childPackages.get(i);
11154                mPackages.remove(childPkg.applicationInfo.packageName);
11155                cleanPackageDataStructuresLILPw(childPkg, chatty);
11156            }
11157        }
11158    }
11159
11160    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11161        int N = pkg.providers.size();
11162        StringBuilder r = null;
11163        int i;
11164        for (i=0; i<N; i++) {
11165            PackageParser.Provider p = pkg.providers.get(i);
11166            mProviders.removeProvider(p);
11167            if (p.info.authority == null) {
11168
11169                /* There was another ContentProvider with this authority when
11170                 * this app was installed so this authority is null,
11171                 * Ignore it as we don't have to unregister the provider.
11172                 */
11173                continue;
11174            }
11175            String names[] = p.info.authority.split(";");
11176            for (int j = 0; j < names.length; j++) {
11177                if (mProvidersByAuthority.get(names[j]) == p) {
11178                    mProvidersByAuthority.remove(names[j]);
11179                    if (DEBUG_REMOVE) {
11180                        if (chatty)
11181                            Log.d(TAG, "Unregistered content provider: " + names[j]
11182                                    + ", className = " + p.info.name + ", isSyncable = "
11183                                    + p.info.isSyncable);
11184                    }
11185                }
11186            }
11187            if (DEBUG_REMOVE && chatty) {
11188                if (r == null) {
11189                    r = new StringBuilder(256);
11190                } else {
11191                    r.append(' ');
11192                }
11193                r.append(p.info.name);
11194            }
11195        }
11196        if (r != null) {
11197            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11198        }
11199
11200        N = pkg.services.size();
11201        r = null;
11202        for (i=0; i<N; i++) {
11203            PackageParser.Service s = pkg.services.get(i);
11204            mServices.removeService(s);
11205            if (chatty) {
11206                if (r == null) {
11207                    r = new StringBuilder(256);
11208                } else {
11209                    r.append(' ');
11210                }
11211                r.append(s.info.name);
11212            }
11213        }
11214        if (r != null) {
11215            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11216        }
11217
11218        N = pkg.receivers.size();
11219        r = null;
11220        for (i=0; i<N; i++) {
11221            PackageParser.Activity a = pkg.receivers.get(i);
11222            mReceivers.removeActivity(a, "receiver");
11223            if (DEBUG_REMOVE && chatty) {
11224                if (r == null) {
11225                    r = new StringBuilder(256);
11226                } else {
11227                    r.append(' ');
11228                }
11229                r.append(a.info.name);
11230            }
11231        }
11232        if (r != null) {
11233            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11234        }
11235
11236        N = pkg.activities.size();
11237        r = null;
11238        for (i=0; i<N; i++) {
11239            PackageParser.Activity a = pkg.activities.get(i);
11240            mActivities.removeActivity(a, "activity");
11241            if (DEBUG_REMOVE && chatty) {
11242                if (r == null) {
11243                    r = new StringBuilder(256);
11244                } else {
11245                    r.append(' ');
11246                }
11247                r.append(a.info.name);
11248            }
11249        }
11250        if (r != null) {
11251            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11252        }
11253
11254        N = pkg.permissions.size();
11255        r = null;
11256        for (i=0; i<N; i++) {
11257            PackageParser.Permission p = pkg.permissions.get(i);
11258            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11259            if (bp == null) {
11260                bp = mSettings.mPermissionTrees.get(p.info.name);
11261            }
11262            if (bp != null && bp.perm == p) {
11263                bp.perm = null;
11264                if (DEBUG_REMOVE && chatty) {
11265                    if (r == null) {
11266                        r = new StringBuilder(256);
11267                    } else {
11268                        r.append(' ');
11269                    }
11270                    r.append(p.info.name);
11271                }
11272            }
11273            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11274                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11275                if (appOpPkgs != null) {
11276                    appOpPkgs.remove(pkg.packageName);
11277                }
11278            }
11279        }
11280        if (r != null) {
11281            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11282        }
11283
11284        N = pkg.requestedPermissions.size();
11285        r = null;
11286        for (i=0; i<N; i++) {
11287            String perm = pkg.requestedPermissions.get(i);
11288            BasePermission bp = mSettings.mPermissions.get(perm);
11289            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11290                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11291                if (appOpPkgs != null) {
11292                    appOpPkgs.remove(pkg.packageName);
11293                    if (appOpPkgs.isEmpty()) {
11294                        mAppOpPermissionPackages.remove(perm);
11295                    }
11296                }
11297            }
11298        }
11299        if (r != null) {
11300            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11301        }
11302
11303        N = pkg.instrumentation.size();
11304        r = null;
11305        for (i=0; i<N; i++) {
11306            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11307            mInstrumentation.remove(a.getComponentName());
11308            if (DEBUG_REMOVE && chatty) {
11309                if (r == null) {
11310                    r = new StringBuilder(256);
11311                } else {
11312                    r.append(' ');
11313                }
11314                r.append(a.info.name);
11315            }
11316        }
11317        if (r != null) {
11318            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11319        }
11320
11321        r = null;
11322        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11323            // Only system apps can hold shared libraries.
11324            if (pkg.libraryNames != null) {
11325                for (i = 0; i < pkg.libraryNames.size(); i++) {
11326                    String name = pkg.libraryNames.get(i);
11327                    if (removeSharedLibraryLPw(name, 0)) {
11328                        if (DEBUG_REMOVE && chatty) {
11329                            if (r == null) {
11330                                r = new StringBuilder(256);
11331                            } else {
11332                                r.append(' ');
11333                            }
11334                            r.append(name);
11335                        }
11336                    }
11337                }
11338            }
11339        }
11340
11341        r = null;
11342
11343        // Any package can hold static shared libraries.
11344        if (pkg.staticSharedLibName != null) {
11345            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11346                if (DEBUG_REMOVE && chatty) {
11347                    if (r == null) {
11348                        r = new StringBuilder(256);
11349                    } else {
11350                        r.append(' ');
11351                    }
11352                    r.append(pkg.staticSharedLibName);
11353                }
11354            }
11355        }
11356
11357        if (r != null) {
11358            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11359        }
11360    }
11361
11362    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11363        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11364            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11365                return true;
11366            }
11367        }
11368        return false;
11369    }
11370
11371    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11372    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11373    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11374
11375    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11376        // Update the parent permissions
11377        updatePermissionsLPw(pkg.packageName, pkg, flags);
11378        // Update the child permissions
11379        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11380        for (int i = 0; i < childCount; i++) {
11381            PackageParser.Package childPkg = pkg.childPackages.get(i);
11382            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11383        }
11384    }
11385
11386    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11387            int flags) {
11388        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11389        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11390    }
11391
11392    private void updatePermissionsLPw(String changingPkg,
11393            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11394        // Make sure there are no dangling permission trees.
11395        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11396        while (it.hasNext()) {
11397            final BasePermission bp = it.next();
11398            if (bp.packageSetting == null) {
11399                // We may not yet have parsed the package, so just see if
11400                // we still know about its settings.
11401                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11402            }
11403            if (bp.packageSetting == null) {
11404                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11405                        + " from package " + bp.sourcePackage);
11406                it.remove();
11407            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11408                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11409                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11410                            + " from package " + bp.sourcePackage);
11411                    flags |= UPDATE_PERMISSIONS_ALL;
11412                    it.remove();
11413                }
11414            }
11415        }
11416
11417        // Make sure all dynamic permissions have been assigned to a package,
11418        // and make sure there are no dangling permissions.
11419        it = mSettings.mPermissions.values().iterator();
11420        while (it.hasNext()) {
11421            final BasePermission bp = it.next();
11422            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11423                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11424                        + bp.name + " pkg=" + bp.sourcePackage
11425                        + " info=" + bp.pendingInfo);
11426                if (bp.packageSetting == null && bp.pendingInfo != null) {
11427                    final BasePermission tree = findPermissionTreeLP(bp.name);
11428                    if (tree != null && tree.perm != null) {
11429                        bp.packageSetting = tree.packageSetting;
11430                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11431                                new PermissionInfo(bp.pendingInfo));
11432                        bp.perm.info.packageName = tree.perm.info.packageName;
11433                        bp.perm.info.name = bp.name;
11434                        bp.uid = tree.uid;
11435                    }
11436                }
11437            }
11438            if (bp.packageSetting == null) {
11439                // We may not yet have parsed the package, so just see if
11440                // we still know about its settings.
11441                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11442            }
11443            if (bp.packageSetting == null) {
11444                Slog.w(TAG, "Removing dangling permission: " + bp.name
11445                        + " from package " + bp.sourcePackage);
11446                it.remove();
11447            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11448                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11449                    Slog.i(TAG, "Removing old permission: " + bp.name
11450                            + " from package " + bp.sourcePackage);
11451                    flags |= UPDATE_PERMISSIONS_ALL;
11452                    it.remove();
11453                }
11454            }
11455        }
11456
11457        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11458        // Now update the permissions for all packages, in particular
11459        // replace the granted permissions of the system packages.
11460        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11461            for (PackageParser.Package pkg : mPackages.values()) {
11462                if (pkg != pkgInfo) {
11463                    // Only replace for packages on requested volume
11464                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11465                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11466                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11467                    grantPermissionsLPw(pkg, replace, changingPkg);
11468                }
11469            }
11470        }
11471
11472        if (pkgInfo != null) {
11473            // Only replace for packages on requested volume
11474            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11475            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11476                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11477            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11478        }
11479        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11480    }
11481
11482    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11483            String packageOfInterest) {
11484        // IMPORTANT: There are two types of permissions: install and runtime.
11485        // Install time permissions are granted when the app is installed to
11486        // all device users and users added in the future. Runtime permissions
11487        // are granted at runtime explicitly to specific users. Normal and signature
11488        // protected permissions are install time permissions. Dangerous permissions
11489        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11490        // otherwise they are runtime permissions. This function does not manage
11491        // runtime permissions except for the case an app targeting Lollipop MR1
11492        // being upgraded to target a newer SDK, in which case dangerous permissions
11493        // are transformed from install time to runtime ones.
11494
11495        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11496        if (ps == null) {
11497            return;
11498        }
11499
11500        PermissionsState permissionsState = ps.getPermissionsState();
11501        PermissionsState origPermissions = permissionsState;
11502
11503        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11504
11505        boolean runtimePermissionsRevoked = false;
11506        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11507
11508        boolean changedInstallPermission = false;
11509
11510        if (replace) {
11511            ps.installPermissionsFixed = false;
11512            if (!ps.isSharedUser()) {
11513                origPermissions = new PermissionsState(permissionsState);
11514                permissionsState.reset();
11515            } else {
11516                // We need to know only about runtime permission changes since the
11517                // calling code always writes the install permissions state but
11518                // the runtime ones are written only if changed. The only cases of
11519                // changed runtime permissions here are promotion of an install to
11520                // runtime and revocation of a runtime from a shared user.
11521                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11522                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11523                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11524                    runtimePermissionsRevoked = true;
11525                }
11526            }
11527        }
11528
11529        permissionsState.setGlobalGids(mGlobalGids);
11530
11531        final int N = pkg.requestedPermissions.size();
11532        for (int i=0; i<N; i++) {
11533            final String name = pkg.requestedPermissions.get(i);
11534            final BasePermission bp = mSettings.mPermissions.get(name);
11535            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11536                    >= Build.VERSION_CODES.M;
11537
11538            if (DEBUG_INSTALL) {
11539                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11540            }
11541
11542            if (bp == null || bp.packageSetting == null) {
11543                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11544                    Slog.w(TAG, "Unknown permission " + name
11545                            + " in package " + pkg.packageName);
11546                }
11547                continue;
11548            }
11549
11550
11551            // Limit ephemeral apps to ephemeral allowed permissions.
11552            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11553                Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11554                        + pkg.packageName);
11555                continue;
11556            }
11557
11558            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11559                Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11560                        + pkg.packageName);
11561                continue;
11562            }
11563
11564            final String perm = bp.name;
11565            boolean allowedSig = false;
11566            int grant = GRANT_DENIED;
11567
11568            // Keep track of app op permissions.
11569            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11570                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11571                if (pkgs == null) {
11572                    pkgs = new ArraySet<>();
11573                    mAppOpPermissionPackages.put(bp.name, pkgs);
11574                }
11575                pkgs.add(pkg.packageName);
11576            }
11577
11578            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11579            switch (level) {
11580                case PermissionInfo.PROTECTION_NORMAL: {
11581                    // For all apps normal permissions are install time ones.
11582                    grant = GRANT_INSTALL;
11583                } break;
11584
11585                case PermissionInfo.PROTECTION_DANGEROUS: {
11586                    // If a permission review is required for legacy apps we represent
11587                    // their permissions as always granted runtime ones since we need
11588                    // to keep the review required permission flag per user while an
11589                    // install permission's state is shared across all users.
11590                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11591                        // For legacy apps dangerous permissions are install time ones.
11592                        grant = GRANT_INSTALL;
11593                    } else if (origPermissions.hasInstallPermission(bp.name)) {
11594                        // For legacy apps that became modern, install becomes runtime.
11595                        grant = GRANT_UPGRADE;
11596                    } else if (mPromoteSystemApps
11597                            && isSystemApp(ps)
11598                            && mExistingSystemPackages.contains(ps.name)) {
11599                        // For legacy system apps, install becomes runtime.
11600                        // We cannot check hasInstallPermission() for system apps since those
11601                        // permissions were granted implicitly and not persisted pre-M.
11602                        grant = GRANT_UPGRADE;
11603                    } else {
11604                        // For modern apps keep runtime permissions unchanged.
11605                        grant = GRANT_RUNTIME;
11606                    }
11607                } break;
11608
11609                case PermissionInfo.PROTECTION_SIGNATURE: {
11610                    // For all apps signature permissions are install time ones.
11611                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11612                    if (allowedSig) {
11613                        grant = GRANT_INSTALL;
11614                    }
11615                } break;
11616            }
11617
11618            if (DEBUG_INSTALL) {
11619                Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
11620            }
11621
11622            if (grant != GRANT_DENIED) {
11623                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11624                    // If this is an existing, non-system package, then
11625                    // we can't add any new permissions to it.
11626                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11627                        // Except...  if this is a permission that was added
11628                        // to the platform (note: need to only do this when
11629                        // updating the platform).
11630                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11631                            grant = GRANT_DENIED;
11632                        }
11633                    }
11634                }
11635
11636                switch (grant) {
11637                    case GRANT_INSTALL: {
11638                        // Revoke this as runtime permission to handle the case of
11639                        // a runtime permission being downgraded to an install one.
11640                        // Also in permission review mode we keep dangerous permissions
11641                        // for legacy apps
11642                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11643                            if (origPermissions.getRuntimePermissionState(
11644                                    bp.name, userId) != null) {
11645                                // Revoke the runtime permission and clear the flags.
11646                                origPermissions.revokeRuntimePermission(bp, userId);
11647                                origPermissions.updatePermissionFlags(bp, userId,
11648                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
11649                                // If we revoked a permission permission, we have to write.
11650                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11651                                        changedRuntimePermissionUserIds, userId);
11652                            }
11653                        }
11654                        // Grant an install permission.
11655                        if (permissionsState.grantInstallPermission(bp) !=
11656                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
11657                            changedInstallPermission = true;
11658                        }
11659                    } break;
11660
11661                    case GRANT_RUNTIME: {
11662                        // Grant previously granted runtime permissions.
11663                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11664                            PermissionState permissionState = origPermissions
11665                                    .getRuntimePermissionState(bp.name, userId);
11666                            int flags = permissionState != null
11667                                    ? permissionState.getFlags() : 0;
11668                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
11669                                // Don't propagate the permission in a permission review mode if
11670                                // the former was revoked, i.e. marked to not propagate on upgrade.
11671                                // Note that in a permission review mode install permissions are
11672                                // represented as constantly granted runtime ones since we need to
11673                                // keep a per user state associated with the permission. Also the
11674                                // revoke on upgrade flag is no longer applicable and is reset.
11675                                final boolean revokeOnUpgrade = (flags & PackageManager
11676                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
11677                                if (revokeOnUpgrade) {
11678                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
11679                                    // Since we changed the flags, we have to write.
11680                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11681                                            changedRuntimePermissionUserIds, userId);
11682                                }
11683                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
11684                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
11685                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
11686                                        // If we cannot put the permission as it was,
11687                                        // we have to write.
11688                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11689                                                changedRuntimePermissionUserIds, userId);
11690                                    }
11691                                }
11692
11693                                // If the app supports runtime permissions no need for a review.
11694                                if (mPermissionReviewRequired
11695                                        && appSupportsRuntimePermissions
11696                                        && (flags & PackageManager
11697                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
11698                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
11699                                    // Since we changed the flags, we have to write.
11700                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11701                                            changedRuntimePermissionUserIds, userId);
11702                                }
11703                            } else if (mPermissionReviewRequired
11704                                    && !appSupportsRuntimePermissions) {
11705                                // For legacy apps that need a permission review, every new
11706                                // runtime permission is granted but it is pending a review.
11707                                // We also need to review only platform defined runtime
11708                                // permissions as these are the only ones the platform knows
11709                                // how to disable the API to simulate revocation as legacy
11710                                // apps don't expect to run with revoked permissions.
11711                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
11712                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
11713                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
11714                                        // We changed the flags, hence have to write.
11715                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11716                                                changedRuntimePermissionUserIds, userId);
11717                                    }
11718                                }
11719                                if (permissionsState.grantRuntimePermission(bp, userId)
11720                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11721                                    // We changed the permission, hence have to write.
11722                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11723                                            changedRuntimePermissionUserIds, userId);
11724                                }
11725                            }
11726                            // Propagate the permission flags.
11727                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
11728                        }
11729                    } break;
11730
11731                    case GRANT_UPGRADE: {
11732                        // Grant runtime permissions for a previously held install permission.
11733                        PermissionState permissionState = origPermissions
11734                                .getInstallPermissionState(bp.name);
11735                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
11736
11737                        if (origPermissions.revokeInstallPermission(bp)
11738                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
11739                            // We will be transferring the permission flags, so clear them.
11740                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
11741                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
11742                            changedInstallPermission = true;
11743                        }
11744
11745                        // If the permission is not to be promoted to runtime we ignore it and
11746                        // also its other flags as they are not applicable to install permissions.
11747                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
11748                            for (int userId : currentUserIds) {
11749                                if (permissionsState.grantRuntimePermission(bp, userId) !=
11750                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11751                                    // Transfer the permission flags.
11752                                    permissionsState.updatePermissionFlags(bp, userId,
11753                                            flags, flags);
11754                                    // If we granted the permission, we have to write.
11755                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11756                                            changedRuntimePermissionUserIds, userId);
11757                                }
11758                            }
11759                        }
11760                    } break;
11761
11762                    default: {
11763                        if (packageOfInterest == null
11764                                || packageOfInterest.equals(pkg.packageName)) {
11765                            Slog.w(TAG, "Not granting permission " + perm
11766                                    + " to package " + pkg.packageName
11767                                    + " because it was previously installed without");
11768                        }
11769                    } break;
11770                }
11771            } else {
11772                if (permissionsState.revokeInstallPermission(bp) !=
11773                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
11774                    // Also drop the permission flags.
11775                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
11776                            PackageManager.MASK_PERMISSION_FLAGS, 0);
11777                    changedInstallPermission = true;
11778                    Slog.i(TAG, "Un-granting permission " + perm
11779                            + " from package " + pkg.packageName
11780                            + " (protectionLevel=" + bp.protectionLevel
11781                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11782                            + ")");
11783                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
11784                    // Don't print warning for app op permissions, since it is fine for them
11785                    // not to be granted, there is a UI for the user to decide.
11786                    if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11787                        Slog.w(TAG, "Not granting permission " + perm
11788                                + " to package " + pkg.packageName
11789                                + " (protectionLevel=" + bp.protectionLevel
11790                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
11791                                + ")");
11792                    }
11793                }
11794            }
11795        }
11796
11797        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
11798                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
11799            // This is the first that we have heard about this package, so the
11800            // permissions we have now selected are fixed until explicitly
11801            // changed.
11802            ps.installPermissionsFixed = true;
11803        }
11804
11805        // Persist the runtime permissions state for users with changes. If permissions
11806        // were revoked because no app in the shared user declares them we have to
11807        // write synchronously to avoid losing runtime permissions state.
11808        for (int userId : changedRuntimePermissionUserIds) {
11809            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
11810        }
11811    }
11812
11813    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
11814        boolean allowed = false;
11815        final int NP = PackageParser.NEW_PERMISSIONS.length;
11816        for (int ip=0; ip<NP; ip++) {
11817            final PackageParser.NewPermissionInfo npi
11818                    = PackageParser.NEW_PERMISSIONS[ip];
11819            if (npi.name.equals(perm)
11820                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
11821                allowed = true;
11822                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
11823                        + pkg.packageName);
11824                break;
11825            }
11826        }
11827        return allowed;
11828    }
11829
11830    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
11831            BasePermission bp, PermissionsState origPermissions) {
11832        boolean privilegedPermission = (bp.protectionLevel
11833                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
11834        boolean privappPermissionsDisable =
11835                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
11836        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
11837        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
11838        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
11839                && !platformPackage && platformPermission) {
11840            ArraySet<String> wlPermissions = SystemConfig.getInstance()
11841                    .getPrivAppPermissions(pkg.packageName);
11842            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
11843            if (!whitelisted) {
11844                Slog.w(TAG, "Privileged permission " + perm + " for package "
11845                        + pkg.packageName + " - not in privapp-permissions whitelist");
11846                // Only report violations for apps on system image
11847                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
11848                    if (mPrivappPermissionsViolations == null) {
11849                        mPrivappPermissionsViolations = new ArraySet<>();
11850                    }
11851                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
11852                }
11853                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
11854                    return false;
11855                }
11856            }
11857        }
11858        boolean allowed = (compareSignatures(
11859                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
11860                        == PackageManager.SIGNATURE_MATCH)
11861                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
11862                        == PackageManager.SIGNATURE_MATCH);
11863        if (!allowed && privilegedPermission) {
11864            if (isSystemApp(pkg)) {
11865                // For updated system applications, a system permission
11866                // is granted only if it had been defined by the original application.
11867                if (pkg.isUpdatedSystemApp()) {
11868                    final PackageSetting sysPs = mSettings
11869                            .getDisabledSystemPkgLPr(pkg.packageName);
11870                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
11871                        // If the original was granted this permission, we take
11872                        // that grant decision as read and propagate it to the
11873                        // update.
11874                        if (sysPs.isPrivileged()) {
11875                            allowed = true;
11876                        }
11877                    } else {
11878                        // The system apk may have been updated with an older
11879                        // version of the one on the data partition, but which
11880                        // granted a new system permission that it didn't have
11881                        // before.  In this case we do want to allow the app to
11882                        // now get the new permission if the ancestral apk is
11883                        // privileged to get it.
11884                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
11885                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
11886                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
11887                                    allowed = true;
11888                                    break;
11889                                }
11890                            }
11891                        }
11892                        // Also if a privileged parent package on the system image or any of
11893                        // its children requested a privileged permission, the updated child
11894                        // packages can also get the permission.
11895                        if (pkg.parentPackage != null) {
11896                            final PackageSetting disabledSysParentPs = mSettings
11897                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
11898                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
11899                                    && disabledSysParentPs.isPrivileged()) {
11900                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
11901                                    allowed = true;
11902                                } else if (disabledSysParentPs.pkg.childPackages != null) {
11903                                    final int count = disabledSysParentPs.pkg.childPackages.size();
11904                                    for (int i = 0; i < count; i++) {
11905                                        PackageParser.Package disabledSysChildPkg =
11906                                                disabledSysParentPs.pkg.childPackages.get(i);
11907                                        if (isPackageRequestingPermission(disabledSysChildPkg,
11908                                                perm)) {
11909                                            allowed = true;
11910                                            break;
11911                                        }
11912                                    }
11913                                }
11914                            }
11915                        }
11916                    }
11917                } else {
11918                    allowed = isPrivilegedApp(pkg);
11919                }
11920            }
11921        }
11922        if (!allowed) {
11923            if (!allowed && (bp.protectionLevel
11924                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
11925                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
11926                // If this was a previously normal/dangerous permission that got moved
11927                // to a system permission as part of the runtime permission redesign, then
11928                // we still want to blindly grant it to old apps.
11929                allowed = true;
11930            }
11931            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
11932                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
11933                // If this permission is to be granted to the system installer and
11934                // this app is an installer, then it gets the permission.
11935                allowed = true;
11936            }
11937            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
11938                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
11939                // If this permission is to be granted to the system verifier and
11940                // this app is a verifier, then it gets the permission.
11941                allowed = true;
11942            }
11943            if (!allowed && (bp.protectionLevel
11944                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
11945                    && isSystemApp(pkg)) {
11946                // Any pre-installed system app is allowed to get this permission.
11947                allowed = true;
11948            }
11949            if (!allowed && (bp.protectionLevel
11950                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
11951                // For development permissions, a development permission
11952                // is granted only if it was already granted.
11953                allowed = origPermissions.hasInstallPermission(perm);
11954            }
11955            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
11956                    && pkg.packageName.equals(mSetupWizardPackage)) {
11957                // If this permission is to be granted to the system setup wizard and
11958                // this app is a setup wizard, then it gets the permission.
11959                allowed = true;
11960            }
11961        }
11962        return allowed;
11963    }
11964
11965    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
11966        final int permCount = pkg.requestedPermissions.size();
11967        for (int j = 0; j < permCount; j++) {
11968            String requestedPermission = pkg.requestedPermissions.get(j);
11969            if (permission.equals(requestedPermission)) {
11970                return true;
11971            }
11972        }
11973        return false;
11974    }
11975
11976    final class ActivityIntentResolver
11977            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11978        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11979                boolean defaultOnly, int userId) {
11980            if (!sUserManager.exists(userId)) return null;
11981            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11982            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11983        }
11984
11985        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11986                int userId) {
11987            if (!sUserManager.exists(userId)) return null;
11988            mFlags = flags;
11989            return super.queryIntent(intent, resolvedType,
11990                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11991                    userId);
11992        }
11993
11994        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11995                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11996            if (!sUserManager.exists(userId)) return null;
11997            if (packageActivities == null) {
11998                return null;
11999            }
12000            mFlags = flags;
12001            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12002            final int N = packageActivities.size();
12003            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12004                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12005
12006            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12007            for (int i = 0; i < N; ++i) {
12008                intentFilters = packageActivities.get(i).intents;
12009                if (intentFilters != null && intentFilters.size() > 0) {
12010                    PackageParser.ActivityIntentInfo[] array =
12011                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12012                    intentFilters.toArray(array);
12013                    listCut.add(array);
12014                }
12015            }
12016            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12017        }
12018
12019        /**
12020         * Finds a privileged activity that matches the specified activity names.
12021         */
12022        private PackageParser.Activity findMatchingActivity(
12023                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12024            for (PackageParser.Activity sysActivity : activityList) {
12025                if (sysActivity.info.name.equals(activityInfo.name)) {
12026                    return sysActivity;
12027                }
12028                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12029                    return sysActivity;
12030                }
12031                if (sysActivity.info.targetActivity != null) {
12032                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12033                        return sysActivity;
12034                    }
12035                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12036                        return sysActivity;
12037                    }
12038                }
12039            }
12040            return null;
12041        }
12042
12043        public class IterGenerator<E> {
12044            public Iterator<E> generate(ActivityIntentInfo info) {
12045                return null;
12046            }
12047        }
12048
12049        public class ActionIterGenerator extends IterGenerator<String> {
12050            @Override
12051            public Iterator<String> generate(ActivityIntentInfo info) {
12052                return info.actionsIterator();
12053            }
12054        }
12055
12056        public class CategoriesIterGenerator extends IterGenerator<String> {
12057            @Override
12058            public Iterator<String> generate(ActivityIntentInfo info) {
12059                return info.categoriesIterator();
12060            }
12061        }
12062
12063        public class SchemesIterGenerator extends IterGenerator<String> {
12064            @Override
12065            public Iterator<String> generate(ActivityIntentInfo info) {
12066                return info.schemesIterator();
12067            }
12068        }
12069
12070        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12071            @Override
12072            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12073                return info.authoritiesIterator();
12074            }
12075        }
12076
12077        /**
12078         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12079         * MODIFIED. Do not pass in a list that should not be changed.
12080         */
12081        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12082                IterGenerator<T> generator, Iterator<T> searchIterator) {
12083            // loop through the set of actions; every one must be found in the intent filter
12084            while (searchIterator.hasNext()) {
12085                // we must have at least one filter in the list to consider a match
12086                if (intentList.size() == 0) {
12087                    break;
12088                }
12089
12090                final T searchAction = searchIterator.next();
12091
12092                // loop through the set of intent filters
12093                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12094                while (intentIter.hasNext()) {
12095                    final ActivityIntentInfo intentInfo = intentIter.next();
12096                    boolean selectionFound = false;
12097
12098                    // loop through the intent filter's selection criteria; at least one
12099                    // of them must match the searched criteria
12100                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12101                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12102                        final T intentSelection = intentSelectionIter.next();
12103                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12104                            selectionFound = true;
12105                            break;
12106                        }
12107                    }
12108
12109                    // the selection criteria wasn't found in this filter's set; this filter
12110                    // is not a potential match
12111                    if (!selectionFound) {
12112                        intentIter.remove();
12113                    }
12114                }
12115            }
12116        }
12117
12118        private boolean isProtectedAction(ActivityIntentInfo filter) {
12119            final Iterator<String> actionsIter = filter.actionsIterator();
12120            while (actionsIter != null && actionsIter.hasNext()) {
12121                final String filterAction = actionsIter.next();
12122                if (PROTECTED_ACTIONS.contains(filterAction)) {
12123                    return true;
12124                }
12125            }
12126            return false;
12127        }
12128
12129        /**
12130         * Adjusts the priority of the given intent filter according to policy.
12131         * <p>
12132         * <ul>
12133         * <li>The priority for non privileged applications is capped to '0'</li>
12134         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12135         * <li>The priority for unbundled updates to privileged applications is capped to the
12136         *      priority defined on the system partition</li>
12137         * </ul>
12138         * <p>
12139         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12140         * allowed to obtain any priority on any action.
12141         */
12142        private void adjustPriority(
12143                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12144            // nothing to do; priority is fine as-is
12145            if (intent.getPriority() <= 0) {
12146                return;
12147            }
12148
12149            final ActivityInfo activityInfo = intent.activity.info;
12150            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12151
12152            final boolean privilegedApp =
12153                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12154            if (!privilegedApp) {
12155                // non-privileged applications can never define a priority >0
12156                Slog.w(TAG, "Non-privileged app; cap priority to 0;"
12157                        + " package: " + applicationInfo.packageName
12158                        + " activity: " + intent.activity.className
12159                        + " origPrio: " + intent.getPriority());
12160                intent.setPriority(0);
12161                return;
12162            }
12163
12164            if (systemActivities == null) {
12165                // the system package is not disabled; we're parsing the system partition
12166                if (isProtectedAction(intent)) {
12167                    if (mDeferProtectedFilters) {
12168                        // We can't deal with these just yet. No component should ever obtain a
12169                        // >0 priority for a protected actions, with ONE exception -- the setup
12170                        // wizard. The setup wizard, however, cannot be known until we're able to
12171                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12172                        // until all intent filters have been processed. Chicken, meet egg.
12173                        // Let the filter temporarily have a high priority and rectify the
12174                        // priorities after all system packages have been scanned.
12175                        mProtectedFilters.add(intent);
12176                        if (DEBUG_FILTERS) {
12177                            Slog.i(TAG, "Protected action; save for later;"
12178                                    + " package: " + applicationInfo.packageName
12179                                    + " activity: " + intent.activity.className
12180                                    + " origPrio: " + intent.getPriority());
12181                        }
12182                        return;
12183                    } else {
12184                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12185                            Slog.i(TAG, "No setup wizard;"
12186                                + " All protected intents capped to priority 0");
12187                        }
12188                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12189                            if (DEBUG_FILTERS) {
12190                                Slog.i(TAG, "Found setup wizard;"
12191                                    + " allow priority " + intent.getPriority() + ";"
12192                                    + " package: " + intent.activity.info.packageName
12193                                    + " activity: " + intent.activity.className
12194                                    + " priority: " + intent.getPriority());
12195                            }
12196                            // setup wizard gets whatever it wants
12197                            return;
12198                        }
12199                        Slog.w(TAG, "Protected action; cap priority to 0;"
12200                                + " package: " + intent.activity.info.packageName
12201                                + " activity: " + intent.activity.className
12202                                + " origPrio: " + intent.getPriority());
12203                        intent.setPriority(0);
12204                        return;
12205                    }
12206                }
12207                // privileged apps on the system image get whatever priority they request
12208                return;
12209            }
12210
12211            // privileged app unbundled update ... try to find the same activity
12212            final PackageParser.Activity foundActivity =
12213                    findMatchingActivity(systemActivities, activityInfo);
12214            if (foundActivity == null) {
12215                // this is a new activity; it cannot obtain >0 priority
12216                if (DEBUG_FILTERS) {
12217                    Slog.i(TAG, "New activity; cap priority to 0;"
12218                            + " package: " + applicationInfo.packageName
12219                            + " activity: " + intent.activity.className
12220                            + " origPrio: " + intent.getPriority());
12221                }
12222                intent.setPriority(0);
12223                return;
12224            }
12225
12226            // found activity, now check for filter equivalence
12227
12228            // a shallow copy is enough; we modify the list, not its contents
12229            final List<ActivityIntentInfo> intentListCopy =
12230                    new ArrayList<>(foundActivity.intents);
12231            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12232
12233            // find matching action subsets
12234            final Iterator<String> actionsIterator = intent.actionsIterator();
12235            if (actionsIterator != null) {
12236                getIntentListSubset(
12237                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12238                if (intentListCopy.size() == 0) {
12239                    // no more intents to match; we're not equivalent
12240                    if (DEBUG_FILTERS) {
12241                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12242                                + " package: " + applicationInfo.packageName
12243                                + " activity: " + intent.activity.className
12244                                + " origPrio: " + intent.getPriority());
12245                    }
12246                    intent.setPriority(0);
12247                    return;
12248                }
12249            }
12250
12251            // find matching category subsets
12252            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12253            if (categoriesIterator != null) {
12254                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12255                        categoriesIterator);
12256                if (intentListCopy.size() == 0) {
12257                    // no more intents to match; we're not equivalent
12258                    if (DEBUG_FILTERS) {
12259                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12260                                + " package: " + applicationInfo.packageName
12261                                + " activity: " + intent.activity.className
12262                                + " origPrio: " + intent.getPriority());
12263                    }
12264                    intent.setPriority(0);
12265                    return;
12266                }
12267            }
12268
12269            // find matching schemes subsets
12270            final Iterator<String> schemesIterator = intent.schemesIterator();
12271            if (schemesIterator != null) {
12272                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12273                        schemesIterator);
12274                if (intentListCopy.size() == 0) {
12275                    // no more intents to match; we're not equivalent
12276                    if (DEBUG_FILTERS) {
12277                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12278                                + " package: " + applicationInfo.packageName
12279                                + " activity: " + intent.activity.className
12280                                + " origPrio: " + intent.getPriority());
12281                    }
12282                    intent.setPriority(0);
12283                    return;
12284                }
12285            }
12286
12287            // find matching authorities subsets
12288            final Iterator<IntentFilter.AuthorityEntry>
12289                    authoritiesIterator = intent.authoritiesIterator();
12290            if (authoritiesIterator != null) {
12291                getIntentListSubset(intentListCopy,
12292                        new AuthoritiesIterGenerator(),
12293                        authoritiesIterator);
12294                if (intentListCopy.size() == 0) {
12295                    // no more intents to match; we're not equivalent
12296                    if (DEBUG_FILTERS) {
12297                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12298                                + " package: " + applicationInfo.packageName
12299                                + " activity: " + intent.activity.className
12300                                + " origPrio: " + intent.getPriority());
12301                    }
12302                    intent.setPriority(0);
12303                    return;
12304                }
12305            }
12306
12307            // we found matching filter(s); app gets the max priority of all intents
12308            int cappedPriority = 0;
12309            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12310                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12311            }
12312            if (intent.getPriority() > cappedPriority) {
12313                if (DEBUG_FILTERS) {
12314                    Slog.i(TAG, "Found matching filter(s);"
12315                            + " cap priority to " + cappedPriority + ";"
12316                            + " package: " + applicationInfo.packageName
12317                            + " activity: " + intent.activity.className
12318                            + " origPrio: " + intent.getPriority());
12319                }
12320                intent.setPriority(cappedPriority);
12321                return;
12322            }
12323            // all this for nothing; the requested priority was <= what was on the system
12324        }
12325
12326        public final void addActivity(PackageParser.Activity a, String type) {
12327            mActivities.put(a.getComponentName(), a);
12328            if (DEBUG_SHOW_INFO)
12329                Log.v(
12330                TAG, "  " + type + " " +
12331                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12332            if (DEBUG_SHOW_INFO)
12333                Log.v(TAG, "    Class=" + a.info.name);
12334            final int NI = a.intents.size();
12335            for (int j=0; j<NI; j++) {
12336                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12337                if ("activity".equals(type)) {
12338                    final PackageSetting ps =
12339                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12340                    final List<PackageParser.Activity> systemActivities =
12341                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12342                    adjustPriority(systemActivities, intent);
12343                }
12344                if (DEBUG_SHOW_INFO) {
12345                    Log.v(TAG, "    IntentFilter:");
12346                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12347                }
12348                if (!intent.debugCheck()) {
12349                    Log.w(TAG, "==> For Activity " + a.info.name);
12350                }
12351                addFilter(intent);
12352            }
12353        }
12354
12355        public final void removeActivity(PackageParser.Activity a, String type) {
12356            mActivities.remove(a.getComponentName());
12357            if (DEBUG_SHOW_INFO) {
12358                Log.v(TAG, "  " + type + " "
12359                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12360                                : a.info.name) + ":");
12361                Log.v(TAG, "    Class=" + a.info.name);
12362            }
12363            final int NI = a.intents.size();
12364            for (int j=0; j<NI; j++) {
12365                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12366                if (DEBUG_SHOW_INFO) {
12367                    Log.v(TAG, "    IntentFilter:");
12368                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12369                }
12370                removeFilter(intent);
12371            }
12372        }
12373
12374        @Override
12375        protected boolean allowFilterResult(
12376                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12377            ActivityInfo filterAi = filter.activity.info;
12378            for (int i=dest.size()-1; i>=0; i--) {
12379                ActivityInfo destAi = dest.get(i).activityInfo;
12380                if (destAi.name == filterAi.name
12381                        && destAi.packageName == filterAi.packageName) {
12382                    return false;
12383                }
12384            }
12385            return true;
12386        }
12387
12388        @Override
12389        protected ActivityIntentInfo[] newArray(int size) {
12390            return new ActivityIntentInfo[size];
12391        }
12392
12393        @Override
12394        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12395            if (!sUserManager.exists(userId)) return true;
12396            PackageParser.Package p = filter.activity.owner;
12397            if (p != null) {
12398                PackageSetting ps = (PackageSetting)p.mExtras;
12399                if (ps != null) {
12400                    // System apps are never considered stopped for purposes of
12401                    // filtering, because there may be no way for the user to
12402                    // actually re-launch them.
12403                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12404                            && ps.getStopped(userId);
12405                }
12406            }
12407            return false;
12408        }
12409
12410        @Override
12411        protected boolean isPackageForFilter(String packageName,
12412                PackageParser.ActivityIntentInfo info) {
12413            return packageName.equals(info.activity.owner.packageName);
12414        }
12415
12416        @Override
12417        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12418                int match, int userId) {
12419            if (!sUserManager.exists(userId)) return null;
12420            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12421                return null;
12422            }
12423            final PackageParser.Activity activity = info.activity;
12424            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12425            if (ps == null) {
12426                return null;
12427            }
12428            final PackageUserState userState = ps.readUserState(userId);
12429            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12430            if (ai == null) {
12431                return null;
12432            }
12433            final boolean matchVisibleToInstantApp =
12434                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12435            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12436            // throw out filters that aren't visible to ephemeral apps
12437            if (matchVisibleToInstantApp
12438                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12439                return null;
12440            }
12441            // throw out ephemeral filters if we're not explicitly requesting them
12442            if (!isInstantApp && userState.instantApp) {
12443                return null;
12444            }
12445            // throw out instant app filters if updates are available; will trigger
12446            // instant app resolution
12447            if (userState.instantApp && ps.isUpdateAvailable()) {
12448                return null;
12449            }
12450            final ResolveInfo res = new ResolveInfo();
12451            res.activityInfo = ai;
12452            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12453                res.filter = info;
12454            }
12455            if (info != null) {
12456                res.handleAllWebDataURI = info.handleAllWebDataURI();
12457            }
12458            res.priority = info.getPriority();
12459            res.preferredOrder = activity.owner.mPreferredOrder;
12460            //System.out.println("Result: " + res.activityInfo.className +
12461            //                   " = " + res.priority);
12462            res.match = match;
12463            res.isDefault = info.hasDefault;
12464            res.labelRes = info.labelRes;
12465            res.nonLocalizedLabel = info.nonLocalizedLabel;
12466            if (userNeedsBadging(userId)) {
12467                res.noResourceId = true;
12468            } else {
12469                res.icon = info.icon;
12470            }
12471            res.iconResourceId = info.icon;
12472            res.system = res.activityInfo.applicationInfo.isSystemApp();
12473            res.instantAppAvailable = userState.instantApp;
12474            return res;
12475        }
12476
12477        @Override
12478        protected void sortResults(List<ResolveInfo> results) {
12479            Collections.sort(results, mResolvePrioritySorter);
12480        }
12481
12482        @Override
12483        protected void dumpFilter(PrintWriter out, String prefix,
12484                PackageParser.ActivityIntentInfo filter) {
12485            out.print(prefix); out.print(
12486                    Integer.toHexString(System.identityHashCode(filter.activity)));
12487                    out.print(' ');
12488                    filter.activity.printComponentShortName(out);
12489                    out.print(" filter ");
12490                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12491        }
12492
12493        @Override
12494        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12495            return filter.activity;
12496        }
12497
12498        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12499            PackageParser.Activity activity = (PackageParser.Activity)label;
12500            out.print(prefix); out.print(
12501                    Integer.toHexString(System.identityHashCode(activity)));
12502                    out.print(' ');
12503                    activity.printComponentShortName(out);
12504            if (count > 1) {
12505                out.print(" ("); out.print(count); out.print(" filters)");
12506            }
12507            out.println();
12508        }
12509
12510        // Keys are String (activity class name), values are Activity.
12511        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12512                = new ArrayMap<ComponentName, PackageParser.Activity>();
12513        private int mFlags;
12514    }
12515
12516    private final class ServiceIntentResolver
12517            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12518        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12519                boolean defaultOnly, int userId) {
12520            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12521            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12522        }
12523
12524        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12525                int userId) {
12526            if (!sUserManager.exists(userId)) return null;
12527            mFlags = flags;
12528            return super.queryIntent(intent, resolvedType,
12529                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12530                    userId);
12531        }
12532
12533        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12534                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12535            if (!sUserManager.exists(userId)) return null;
12536            if (packageServices == null) {
12537                return null;
12538            }
12539            mFlags = flags;
12540            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12541            final int N = packageServices.size();
12542            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12543                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12544
12545            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12546            for (int i = 0; i < N; ++i) {
12547                intentFilters = packageServices.get(i).intents;
12548                if (intentFilters != null && intentFilters.size() > 0) {
12549                    PackageParser.ServiceIntentInfo[] array =
12550                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12551                    intentFilters.toArray(array);
12552                    listCut.add(array);
12553                }
12554            }
12555            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12556        }
12557
12558        public final void addService(PackageParser.Service s) {
12559            mServices.put(s.getComponentName(), s);
12560            if (DEBUG_SHOW_INFO) {
12561                Log.v(TAG, "  "
12562                        + (s.info.nonLocalizedLabel != null
12563                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12564                Log.v(TAG, "    Class=" + s.info.name);
12565            }
12566            final int NI = s.intents.size();
12567            int j;
12568            for (j=0; j<NI; j++) {
12569                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12570                if (DEBUG_SHOW_INFO) {
12571                    Log.v(TAG, "    IntentFilter:");
12572                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12573                }
12574                if (!intent.debugCheck()) {
12575                    Log.w(TAG, "==> For Service " + s.info.name);
12576                }
12577                addFilter(intent);
12578            }
12579        }
12580
12581        public final void removeService(PackageParser.Service s) {
12582            mServices.remove(s.getComponentName());
12583            if (DEBUG_SHOW_INFO) {
12584                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12585                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12586                Log.v(TAG, "    Class=" + s.info.name);
12587            }
12588            final int NI = s.intents.size();
12589            int j;
12590            for (j=0; j<NI; j++) {
12591                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12592                if (DEBUG_SHOW_INFO) {
12593                    Log.v(TAG, "    IntentFilter:");
12594                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12595                }
12596                removeFilter(intent);
12597            }
12598        }
12599
12600        @Override
12601        protected boolean allowFilterResult(
12602                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12603            ServiceInfo filterSi = filter.service.info;
12604            for (int i=dest.size()-1; i>=0; i--) {
12605                ServiceInfo destAi = dest.get(i).serviceInfo;
12606                if (destAi.name == filterSi.name
12607                        && destAi.packageName == filterSi.packageName) {
12608                    return false;
12609                }
12610            }
12611            return true;
12612        }
12613
12614        @Override
12615        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12616            return new PackageParser.ServiceIntentInfo[size];
12617        }
12618
12619        @Override
12620        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12621            if (!sUserManager.exists(userId)) return true;
12622            PackageParser.Package p = filter.service.owner;
12623            if (p != null) {
12624                PackageSetting ps = (PackageSetting)p.mExtras;
12625                if (ps != null) {
12626                    // System apps are never considered stopped for purposes of
12627                    // filtering, because there may be no way for the user to
12628                    // actually re-launch them.
12629                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12630                            && ps.getStopped(userId);
12631                }
12632            }
12633            return false;
12634        }
12635
12636        @Override
12637        protected boolean isPackageForFilter(String packageName,
12638                PackageParser.ServiceIntentInfo info) {
12639            return packageName.equals(info.service.owner.packageName);
12640        }
12641
12642        @Override
12643        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12644                int match, int userId) {
12645            if (!sUserManager.exists(userId)) return null;
12646            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12647            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12648                return null;
12649            }
12650            final PackageParser.Service service = info.service;
12651            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12652            if (ps == null) {
12653                return null;
12654            }
12655            final PackageUserState userState = ps.readUserState(userId);
12656            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12657                    userState, userId);
12658            if (si == null) {
12659                return null;
12660            }
12661            final boolean matchVisibleToInstantApp =
12662                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12663            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12664            // throw out filters that aren't visible to ephemeral apps
12665            if (matchVisibleToInstantApp
12666                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12667                return null;
12668            }
12669            // throw out ephemeral filters if we're not explicitly requesting them
12670            if (!isInstantApp && userState.instantApp) {
12671                return null;
12672            }
12673            // throw out instant app filters if updates are available; will trigger
12674            // instant app resolution
12675            if (userState.instantApp && ps.isUpdateAvailable()) {
12676                return null;
12677            }
12678            final ResolveInfo res = new ResolveInfo();
12679            res.serviceInfo = si;
12680            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12681                res.filter = filter;
12682            }
12683            res.priority = info.getPriority();
12684            res.preferredOrder = service.owner.mPreferredOrder;
12685            res.match = match;
12686            res.isDefault = info.hasDefault;
12687            res.labelRes = info.labelRes;
12688            res.nonLocalizedLabel = info.nonLocalizedLabel;
12689            res.icon = info.icon;
12690            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12691            return res;
12692        }
12693
12694        @Override
12695        protected void sortResults(List<ResolveInfo> results) {
12696            Collections.sort(results, mResolvePrioritySorter);
12697        }
12698
12699        @Override
12700        protected void dumpFilter(PrintWriter out, String prefix,
12701                PackageParser.ServiceIntentInfo filter) {
12702            out.print(prefix); out.print(
12703                    Integer.toHexString(System.identityHashCode(filter.service)));
12704                    out.print(' ');
12705                    filter.service.printComponentShortName(out);
12706                    out.print(" filter ");
12707                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12708        }
12709
12710        @Override
12711        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12712            return filter.service;
12713        }
12714
12715        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12716            PackageParser.Service service = (PackageParser.Service)label;
12717            out.print(prefix); out.print(
12718                    Integer.toHexString(System.identityHashCode(service)));
12719                    out.print(' ');
12720                    service.printComponentShortName(out);
12721            if (count > 1) {
12722                out.print(" ("); out.print(count); out.print(" filters)");
12723            }
12724            out.println();
12725        }
12726
12727//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12728//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12729//            final List<ResolveInfo> retList = Lists.newArrayList();
12730//            while (i.hasNext()) {
12731//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12732//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12733//                    retList.add(resolveInfo);
12734//                }
12735//            }
12736//            return retList;
12737//        }
12738
12739        // Keys are String (activity class name), values are Activity.
12740        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12741                = new ArrayMap<ComponentName, PackageParser.Service>();
12742        private int mFlags;
12743    }
12744
12745    private final class ProviderIntentResolver
12746            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12747        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12748                boolean defaultOnly, int userId) {
12749            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12750            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12751        }
12752
12753        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12754                int userId) {
12755            if (!sUserManager.exists(userId))
12756                return null;
12757            mFlags = flags;
12758            return super.queryIntent(intent, resolvedType,
12759                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12760                    userId);
12761        }
12762
12763        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12764                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12765            if (!sUserManager.exists(userId))
12766                return null;
12767            if (packageProviders == null) {
12768                return null;
12769            }
12770            mFlags = flags;
12771            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12772            final int N = packageProviders.size();
12773            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12774                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12775
12776            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12777            for (int i = 0; i < N; ++i) {
12778                intentFilters = packageProviders.get(i).intents;
12779                if (intentFilters != null && intentFilters.size() > 0) {
12780                    PackageParser.ProviderIntentInfo[] array =
12781                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12782                    intentFilters.toArray(array);
12783                    listCut.add(array);
12784                }
12785            }
12786            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12787        }
12788
12789        public final void addProvider(PackageParser.Provider p) {
12790            if (mProviders.containsKey(p.getComponentName())) {
12791                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12792                return;
12793            }
12794
12795            mProviders.put(p.getComponentName(), p);
12796            if (DEBUG_SHOW_INFO) {
12797                Log.v(TAG, "  "
12798                        + (p.info.nonLocalizedLabel != null
12799                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12800                Log.v(TAG, "    Class=" + p.info.name);
12801            }
12802            final int NI = p.intents.size();
12803            int j;
12804            for (j = 0; j < NI; j++) {
12805                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12806                if (DEBUG_SHOW_INFO) {
12807                    Log.v(TAG, "    IntentFilter:");
12808                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12809                }
12810                if (!intent.debugCheck()) {
12811                    Log.w(TAG, "==> For Provider " + p.info.name);
12812                }
12813                addFilter(intent);
12814            }
12815        }
12816
12817        public final void removeProvider(PackageParser.Provider p) {
12818            mProviders.remove(p.getComponentName());
12819            if (DEBUG_SHOW_INFO) {
12820                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12821                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12822                Log.v(TAG, "    Class=" + p.info.name);
12823            }
12824            final int NI = p.intents.size();
12825            int j;
12826            for (j = 0; j < NI; j++) {
12827                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12828                if (DEBUG_SHOW_INFO) {
12829                    Log.v(TAG, "    IntentFilter:");
12830                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12831                }
12832                removeFilter(intent);
12833            }
12834        }
12835
12836        @Override
12837        protected boolean allowFilterResult(
12838                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12839            ProviderInfo filterPi = filter.provider.info;
12840            for (int i = dest.size() - 1; i >= 0; i--) {
12841                ProviderInfo destPi = dest.get(i).providerInfo;
12842                if (destPi.name == filterPi.name
12843                        && destPi.packageName == filterPi.packageName) {
12844                    return false;
12845                }
12846            }
12847            return true;
12848        }
12849
12850        @Override
12851        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12852            return new PackageParser.ProviderIntentInfo[size];
12853        }
12854
12855        @Override
12856        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12857            if (!sUserManager.exists(userId))
12858                return true;
12859            PackageParser.Package p = filter.provider.owner;
12860            if (p != null) {
12861                PackageSetting ps = (PackageSetting) p.mExtras;
12862                if (ps != null) {
12863                    // System apps are never considered stopped for purposes of
12864                    // filtering, because there may be no way for the user to
12865                    // actually re-launch them.
12866                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12867                            && ps.getStopped(userId);
12868                }
12869            }
12870            return false;
12871        }
12872
12873        @Override
12874        protected boolean isPackageForFilter(String packageName,
12875                PackageParser.ProviderIntentInfo info) {
12876            return packageName.equals(info.provider.owner.packageName);
12877        }
12878
12879        @Override
12880        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12881                int match, int userId) {
12882            if (!sUserManager.exists(userId))
12883                return null;
12884            final PackageParser.ProviderIntentInfo info = filter;
12885            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12886                return null;
12887            }
12888            final PackageParser.Provider provider = info.provider;
12889            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12890            if (ps == null) {
12891                return null;
12892            }
12893            final PackageUserState userState = ps.readUserState(userId);
12894            final boolean matchVisibleToInstantApp =
12895                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12896            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12897            // throw out filters that aren't visible to instant applications
12898            if (matchVisibleToInstantApp
12899                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12900                return null;
12901            }
12902            // throw out instant application filters if we're not explicitly requesting them
12903            if (!isInstantApp && userState.instantApp) {
12904                return null;
12905            }
12906            // throw out instant application filters if updates are available; will trigger
12907            // instant application resolution
12908            if (userState.instantApp && ps.isUpdateAvailable()) {
12909                return null;
12910            }
12911            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12912                    userState, userId);
12913            if (pi == null) {
12914                return null;
12915            }
12916            final ResolveInfo res = new ResolveInfo();
12917            res.providerInfo = pi;
12918            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12919                res.filter = filter;
12920            }
12921            res.priority = info.getPriority();
12922            res.preferredOrder = provider.owner.mPreferredOrder;
12923            res.match = match;
12924            res.isDefault = info.hasDefault;
12925            res.labelRes = info.labelRes;
12926            res.nonLocalizedLabel = info.nonLocalizedLabel;
12927            res.icon = info.icon;
12928            res.system = res.providerInfo.applicationInfo.isSystemApp();
12929            return res;
12930        }
12931
12932        @Override
12933        protected void sortResults(List<ResolveInfo> results) {
12934            Collections.sort(results, mResolvePrioritySorter);
12935        }
12936
12937        @Override
12938        protected void dumpFilter(PrintWriter out, String prefix,
12939                PackageParser.ProviderIntentInfo filter) {
12940            out.print(prefix);
12941            out.print(
12942                    Integer.toHexString(System.identityHashCode(filter.provider)));
12943            out.print(' ');
12944            filter.provider.printComponentShortName(out);
12945            out.print(" filter ");
12946            out.println(Integer.toHexString(System.identityHashCode(filter)));
12947        }
12948
12949        @Override
12950        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12951            return filter.provider;
12952        }
12953
12954        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12955            PackageParser.Provider provider = (PackageParser.Provider)label;
12956            out.print(prefix); out.print(
12957                    Integer.toHexString(System.identityHashCode(provider)));
12958                    out.print(' ');
12959                    provider.printComponentShortName(out);
12960            if (count > 1) {
12961                out.print(" ("); out.print(count); out.print(" filters)");
12962            }
12963            out.println();
12964        }
12965
12966        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12967                = new ArrayMap<ComponentName, PackageParser.Provider>();
12968        private int mFlags;
12969    }
12970
12971    static final class EphemeralIntentResolver
12972            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12973        /**
12974         * The result that has the highest defined order. Ordering applies on a
12975         * per-package basis. Mapping is from package name to Pair of order and
12976         * EphemeralResolveInfo.
12977         * <p>
12978         * NOTE: This is implemented as a field variable for convenience and efficiency.
12979         * By having a field variable, we're able to track filter ordering as soon as
12980         * a non-zero order is defined. Otherwise, multiple loops across the result set
12981         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12982         * this needs to be contained entirely within {@link #filterResults}.
12983         */
12984        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12985
12986        @Override
12987        protected AuxiliaryResolveInfo[] newArray(int size) {
12988            return new AuxiliaryResolveInfo[size];
12989        }
12990
12991        @Override
12992        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12993            return true;
12994        }
12995
12996        @Override
12997        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12998                int userId) {
12999            if (!sUserManager.exists(userId)) {
13000                return null;
13001            }
13002            final String packageName = responseObj.resolveInfo.getPackageName();
13003            final Integer order = responseObj.getOrder();
13004            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13005                    mOrderResult.get(packageName);
13006            // ordering is enabled and this item's order isn't high enough
13007            if (lastOrderResult != null && lastOrderResult.first >= order) {
13008                return null;
13009            }
13010            final InstantAppResolveInfo res = responseObj.resolveInfo;
13011            if (order > 0) {
13012                // non-zero order, enable ordering
13013                mOrderResult.put(packageName, new Pair<>(order, res));
13014            }
13015            return responseObj;
13016        }
13017
13018        @Override
13019        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13020            // only do work if ordering is enabled [most of the time it won't be]
13021            if (mOrderResult.size() == 0) {
13022                return;
13023            }
13024            int resultSize = results.size();
13025            for (int i = 0; i < resultSize; i++) {
13026                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13027                final String packageName = info.getPackageName();
13028                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13029                if (savedInfo == null) {
13030                    // package doesn't having ordering
13031                    continue;
13032                }
13033                if (savedInfo.second == info) {
13034                    // circled back to the highest ordered item; remove from order list
13035                    mOrderResult.remove(savedInfo);
13036                    if (mOrderResult.size() == 0) {
13037                        // no more ordered items
13038                        break;
13039                    }
13040                    continue;
13041                }
13042                // item has a worse order, remove it from the result list
13043                results.remove(i);
13044                resultSize--;
13045                i--;
13046            }
13047        }
13048    }
13049
13050    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13051            new Comparator<ResolveInfo>() {
13052        public int compare(ResolveInfo r1, ResolveInfo r2) {
13053            int v1 = r1.priority;
13054            int v2 = r2.priority;
13055            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13056            if (v1 != v2) {
13057                return (v1 > v2) ? -1 : 1;
13058            }
13059            v1 = r1.preferredOrder;
13060            v2 = r2.preferredOrder;
13061            if (v1 != v2) {
13062                return (v1 > v2) ? -1 : 1;
13063            }
13064            if (r1.isDefault != r2.isDefault) {
13065                return r1.isDefault ? -1 : 1;
13066            }
13067            v1 = r1.match;
13068            v2 = r2.match;
13069            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13070            if (v1 != v2) {
13071                return (v1 > v2) ? -1 : 1;
13072            }
13073            if (r1.system != r2.system) {
13074                return r1.system ? -1 : 1;
13075            }
13076            if (r1.activityInfo != null) {
13077                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13078            }
13079            if (r1.serviceInfo != null) {
13080                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13081            }
13082            if (r1.providerInfo != null) {
13083                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13084            }
13085            return 0;
13086        }
13087    };
13088
13089    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13090            new Comparator<ProviderInfo>() {
13091        public int compare(ProviderInfo p1, ProviderInfo p2) {
13092            final int v1 = p1.initOrder;
13093            final int v2 = p2.initOrder;
13094            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13095        }
13096    };
13097
13098    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13099            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13100            final int[] userIds) {
13101        mHandler.post(new Runnable() {
13102            @Override
13103            public void run() {
13104                try {
13105                    final IActivityManager am = ActivityManager.getService();
13106                    if (am == null) return;
13107                    final int[] resolvedUserIds;
13108                    if (userIds == null) {
13109                        resolvedUserIds = am.getRunningUserIds();
13110                    } else {
13111                        resolvedUserIds = userIds;
13112                    }
13113                    for (int id : resolvedUserIds) {
13114                        final Intent intent = new Intent(action,
13115                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13116                        if (extras != null) {
13117                            intent.putExtras(extras);
13118                        }
13119                        if (targetPkg != null) {
13120                            intent.setPackage(targetPkg);
13121                        }
13122                        // Modify the UID when posting to other users
13123                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13124                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13125                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13126                            intent.putExtra(Intent.EXTRA_UID, uid);
13127                        }
13128                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13129                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13130                        if (DEBUG_BROADCASTS) {
13131                            RuntimeException here = new RuntimeException("here");
13132                            here.fillInStackTrace();
13133                            Slog.d(TAG, "Sending to user " + id + ": "
13134                                    + intent.toShortString(false, true, false, false)
13135                                    + " " + intent.getExtras(), here);
13136                        }
13137                        am.broadcastIntent(null, intent, null, finishedReceiver,
13138                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13139                                null, finishedReceiver != null, false, id);
13140                    }
13141                } catch (RemoteException ex) {
13142                }
13143            }
13144        });
13145    }
13146
13147    /**
13148     * Check if the external storage media is available. This is true if there
13149     * is a mounted external storage medium or if the external storage is
13150     * emulated.
13151     */
13152    private boolean isExternalMediaAvailable() {
13153        return mMediaMounted || Environment.isExternalStorageEmulated();
13154    }
13155
13156    @Override
13157    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13158        // writer
13159        synchronized (mPackages) {
13160            if (!isExternalMediaAvailable()) {
13161                // If the external storage is no longer mounted at this point,
13162                // the caller may not have been able to delete all of this
13163                // packages files and can not delete any more.  Bail.
13164                return null;
13165            }
13166            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13167            if (lastPackage != null) {
13168                pkgs.remove(lastPackage);
13169            }
13170            if (pkgs.size() > 0) {
13171                return pkgs.get(0);
13172            }
13173        }
13174        return null;
13175    }
13176
13177    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13178        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13179                userId, andCode ? 1 : 0, packageName);
13180        if (mSystemReady) {
13181            msg.sendToTarget();
13182        } else {
13183            if (mPostSystemReadyMessages == null) {
13184                mPostSystemReadyMessages = new ArrayList<>();
13185            }
13186            mPostSystemReadyMessages.add(msg);
13187        }
13188    }
13189
13190    void startCleaningPackages() {
13191        // reader
13192        if (!isExternalMediaAvailable()) {
13193            return;
13194        }
13195        synchronized (mPackages) {
13196            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13197                return;
13198            }
13199        }
13200        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13201        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13202        IActivityManager am = ActivityManager.getService();
13203        if (am != null) {
13204            int dcsUid = -1;
13205            synchronized (mPackages) {
13206                if (!mDefaultContainerWhitelisted) {
13207                    mDefaultContainerWhitelisted = true;
13208                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13209                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13210                }
13211            }
13212            try {
13213                if (dcsUid > 0) {
13214                    am.backgroundWhitelistUid(dcsUid);
13215                }
13216                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13217                        UserHandle.USER_SYSTEM);
13218            } catch (RemoteException e) {
13219            }
13220        }
13221    }
13222
13223    @Override
13224    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13225            int installFlags, String installerPackageName, int userId) {
13226        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13227
13228        final int callingUid = Binder.getCallingUid();
13229        enforceCrossUserPermission(callingUid, userId,
13230                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13231
13232        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13233            try {
13234                if (observer != null) {
13235                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13236                }
13237            } catch (RemoteException re) {
13238            }
13239            return;
13240        }
13241
13242        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13243            installFlags |= PackageManager.INSTALL_FROM_ADB;
13244
13245        } else {
13246            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13247            // about installerPackageName.
13248
13249            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13250            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13251        }
13252
13253        UserHandle user;
13254        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13255            user = UserHandle.ALL;
13256        } else {
13257            user = new UserHandle(userId);
13258        }
13259
13260        // Only system components can circumvent runtime permissions when installing.
13261        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13262                && mContext.checkCallingOrSelfPermission(Manifest.permission
13263                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13264            throw new SecurityException("You need the "
13265                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13266                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13267        }
13268
13269        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13270                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13271            throw new IllegalArgumentException(
13272                    "New installs into ASEC containers no longer supported");
13273        }
13274
13275        final File originFile = new File(originPath);
13276        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13277
13278        final Message msg = mHandler.obtainMessage(INIT_COPY);
13279        final VerificationInfo verificationInfo = new VerificationInfo(
13280                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13281        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13282                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13283                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13284                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13285        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13286        msg.obj = params;
13287
13288        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13289                System.identityHashCode(msg.obj));
13290        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13291                System.identityHashCode(msg.obj));
13292
13293        mHandler.sendMessage(msg);
13294    }
13295
13296
13297    /**
13298     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13299     * it is acting on behalf on an enterprise or the user).
13300     *
13301     * Note that the ordering of the conditionals in this method is important. The checks we perform
13302     * are as follows, in this order:
13303     *
13304     * 1) If the install is being performed by a system app, we can trust the app to have set the
13305     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13306     *    what it is.
13307     * 2) If the install is being performed by a device or profile owner app, the install reason
13308     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13309     *    set the install reason correctly. If the app targets an older SDK version where install
13310     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13311     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13312     * 3) In all other cases, the install is being performed by a regular app that is neither part
13313     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13314     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13315     *    set to enterprise policy and if so, change it to unknown instead.
13316     */
13317    private int fixUpInstallReason(String installerPackageName, int installerUid,
13318            int installReason) {
13319        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13320                == PERMISSION_GRANTED) {
13321            // If the install is being performed by a system app, we trust that app to have set the
13322            // install reason correctly.
13323            return installReason;
13324        }
13325
13326        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13327            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13328        if (dpm != null) {
13329            ComponentName owner = null;
13330            try {
13331                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13332                if (owner == null) {
13333                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13334                }
13335            } catch (RemoteException e) {
13336            }
13337            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13338                // If the install is being performed by a device or profile owner, the install
13339                // reason should be enterprise policy.
13340                return PackageManager.INSTALL_REASON_POLICY;
13341            }
13342        }
13343
13344        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13345            // If the install is being performed by a regular app (i.e. neither system app nor
13346            // device or profile owner), we have no reason to believe that the app is acting on
13347            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13348            // change it to unknown instead.
13349            return PackageManager.INSTALL_REASON_UNKNOWN;
13350        }
13351
13352        // If the install is being performed by a regular app and the install reason was set to any
13353        // value but enterprise policy, leave the install reason unchanged.
13354        return installReason;
13355    }
13356
13357    void installStage(String packageName, File stagedDir, String stagedCid,
13358            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13359            String installerPackageName, int installerUid, UserHandle user,
13360            Certificate[][] certificates) {
13361        if (DEBUG_EPHEMERAL) {
13362            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13363                Slog.d(TAG, "Ephemeral install of " + packageName);
13364            }
13365        }
13366        final VerificationInfo verificationInfo = new VerificationInfo(
13367                sessionParams.originatingUri, sessionParams.referrerUri,
13368                sessionParams.originatingUid, installerUid);
13369
13370        final OriginInfo origin;
13371        if (stagedDir != null) {
13372            origin = OriginInfo.fromStagedFile(stagedDir);
13373        } else {
13374            origin = OriginInfo.fromStagedContainer(stagedCid);
13375        }
13376
13377        final Message msg = mHandler.obtainMessage(INIT_COPY);
13378        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13379                sessionParams.installReason);
13380        final InstallParams params = new InstallParams(origin, null, observer,
13381                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13382                verificationInfo, user, sessionParams.abiOverride,
13383                sessionParams.grantedRuntimePermissions, certificates, installReason);
13384        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13385        msg.obj = params;
13386
13387        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13388                System.identityHashCode(msg.obj));
13389        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13390                System.identityHashCode(msg.obj));
13391
13392        mHandler.sendMessage(msg);
13393    }
13394
13395    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13396            int userId) {
13397        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13398        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13399    }
13400
13401    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13402        if (ArrayUtils.isEmpty(userIds)) {
13403            return;
13404        }
13405        Bundle extras = new Bundle(1);
13406        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13407        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13408
13409        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13410                packageName, extras, 0, null, null, userIds);
13411        if (isSystem) {
13412            mHandler.post(() -> {
13413                        for (int userId : userIds) {
13414                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13415                        }
13416                    }
13417            );
13418        }
13419    }
13420
13421    /**
13422     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13423     * automatically without needing an explicit launch.
13424     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13425     */
13426    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13427        // If user is not running, the app didn't miss any broadcast
13428        if (!mUserManagerInternal.isUserRunning(userId)) {
13429            return;
13430        }
13431        final IActivityManager am = ActivityManager.getService();
13432        try {
13433            // Deliver LOCKED_BOOT_COMPLETED first
13434            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13435                    .setPackage(packageName);
13436            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13437            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13438                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13439
13440            // Deliver BOOT_COMPLETED only if user is unlocked
13441            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13442                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13443                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13444                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13445            }
13446        } catch (RemoteException e) {
13447            throw e.rethrowFromSystemServer();
13448        }
13449    }
13450
13451    @Override
13452    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13453            int userId) {
13454        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13455        PackageSetting pkgSetting;
13456        final int uid = Binder.getCallingUid();
13457        enforceCrossUserPermission(uid, userId,
13458                true /* requireFullPermission */, true /* checkShell */,
13459                "setApplicationHiddenSetting for user " + userId);
13460
13461        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13462            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13463            return false;
13464        }
13465
13466        long callingId = Binder.clearCallingIdentity();
13467        try {
13468            boolean sendAdded = false;
13469            boolean sendRemoved = false;
13470            // writer
13471            synchronized (mPackages) {
13472                pkgSetting = mSettings.mPackages.get(packageName);
13473                if (pkgSetting == null) {
13474                    return false;
13475                }
13476                // Do not allow "android" is being disabled
13477                if ("android".equals(packageName)) {
13478                    Slog.w(TAG, "Cannot hide package: android");
13479                    return false;
13480                }
13481                // Cannot hide static shared libs as they are considered
13482                // a part of the using app (emulating static linking). Also
13483                // static libs are installed always on internal storage.
13484                PackageParser.Package pkg = mPackages.get(packageName);
13485                if (pkg != null && pkg.staticSharedLibName != null) {
13486                    Slog.w(TAG, "Cannot hide package: " + packageName
13487                            + " providing static shared library: "
13488                            + pkg.staticSharedLibName);
13489                    return false;
13490                }
13491                // Only allow protected packages to hide themselves.
13492                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13493                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13494                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13495                    return false;
13496                }
13497
13498                if (pkgSetting.getHidden(userId) != hidden) {
13499                    pkgSetting.setHidden(hidden, userId);
13500                    mSettings.writePackageRestrictionsLPr(userId);
13501                    if (hidden) {
13502                        sendRemoved = true;
13503                    } else {
13504                        sendAdded = true;
13505                    }
13506                }
13507            }
13508            if (sendAdded) {
13509                sendPackageAddedForUser(packageName, pkgSetting, userId);
13510                return true;
13511            }
13512            if (sendRemoved) {
13513                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13514                        "hiding pkg");
13515                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13516                return true;
13517            }
13518        } finally {
13519            Binder.restoreCallingIdentity(callingId);
13520        }
13521        return false;
13522    }
13523
13524    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13525            int userId) {
13526        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13527        info.removedPackage = packageName;
13528        info.installerPackageName = pkgSetting.installerPackageName;
13529        info.removedUsers = new int[] {userId};
13530        info.broadcastUsers = new int[] {userId};
13531        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13532        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13533    }
13534
13535    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13536        if (pkgList.length > 0) {
13537            Bundle extras = new Bundle(1);
13538            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13539
13540            sendPackageBroadcast(
13541                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13542                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13543                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13544                    new int[] {userId});
13545        }
13546    }
13547
13548    /**
13549     * Returns true if application is not found or there was an error. Otherwise it returns
13550     * the hidden state of the package for the given user.
13551     */
13552    @Override
13553    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13554        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13555        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13556                true /* requireFullPermission */, false /* checkShell */,
13557                "getApplicationHidden for user " + userId);
13558        PackageSetting pkgSetting;
13559        long callingId = Binder.clearCallingIdentity();
13560        try {
13561            // writer
13562            synchronized (mPackages) {
13563                pkgSetting = mSettings.mPackages.get(packageName);
13564                if (pkgSetting == null) {
13565                    return true;
13566                }
13567                return pkgSetting.getHidden(userId);
13568            }
13569        } finally {
13570            Binder.restoreCallingIdentity(callingId);
13571        }
13572    }
13573
13574    /**
13575     * @hide
13576     */
13577    @Override
13578    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13579            int installReason) {
13580        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13581                null);
13582        PackageSetting pkgSetting;
13583        final int uid = Binder.getCallingUid();
13584        enforceCrossUserPermission(uid, userId,
13585                true /* requireFullPermission */, true /* checkShell */,
13586                "installExistingPackage for user " + userId);
13587        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13588            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13589        }
13590
13591        long callingId = Binder.clearCallingIdentity();
13592        try {
13593            boolean installed = false;
13594            final boolean instantApp =
13595                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13596            final boolean fullApp =
13597                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13598
13599            // writer
13600            synchronized (mPackages) {
13601                pkgSetting = mSettings.mPackages.get(packageName);
13602                if (pkgSetting == null) {
13603                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13604                }
13605                if (!pkgSetting.getInstalled(userId)) {
13606                    pkgSetting.setInstalled(true, userId);
13607                    pkgSetting.setHidden(false, userId);
13608                    pkgSetting.setInstallReason(installReason, userId);
13609                    mSettings.writePackageRestrictionsLPr(userId);
13610                    mSettings.writeKernelMappingLPr(pkgSetting);
13611                    installed = true;
13612                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13613                    // upgrade app from instant to full; we don't allow app downgrade
13614                    installed = true;
13615                }
13616                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13617            }
13618
13619            if (installed) {
13620                if (pkgSetting.pkg != null) {
13621                    synchronized (mInstallLock) {
13622                        // We don't need to freeze for a brand new install
13623                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13624                    }
13625                }
13626                sendPackageAddedForUser(packageName, pkgSetting, userId);
13627                synchronized (mPackages) {
13628                    updateSequenceNumberLP(packageName, new int[]{ userId });
13629                }
13630            }
13631        } finally {
13632            Binder.restoreCallingIdentity(callingId);
13633        }
13634
13635        return PackageManager.INSTALL_SUCCEEDED;
13636    }
13637
13638    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13639            boolean instantApp, boolean fullApp) {
13640        // no state specified; do nothing
13641        if (!instantApp && !fullApp) {
13642            return;
13643        }
13644        if (userId != UserHandle.USER_ALL) {
13645            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13646                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13647            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13648                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13649            }
13650        } else {
13651            for (int currentUserId : sUserManager.getUserIds()) {
13652                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13653                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13654                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13655                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13656                }
13657            }
13658        }
13659    }
13660
13661    boolean isUserRestricted(int userId, String restrictionKey) {
13662        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13663        if (restrictions.getBoolean(restrictionKey, false)) {
13664            Log.w(TAG, "User is restricted: " + restrictionKey);
13665            return true;
13666        }
13667        return false;
13668    }
13669
13670    @Override
13671    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13672            int userId) {
13673        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13674        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13675                true /* requireFullPermission */, true /* checkShell */,
13676                "setPackagesSuspended for user " + userId);
13677
13678        if (ArrayUtils.isEmpty(packageNames)) {
13679            return packageNames;
13680        }
13681
13682        // List of package names for whom the suspended state has changed.
13683        List<String> changedPackages = new ArrayList<>(packageNames.length);
13684        // List of package names for whom the suspended state is not set as requested in this
13685        // method.
13686        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13687        long callingId = Binder.clearCallingIdentity();
13688        try {
13689            for (int i = 0; i < packageNames.length; i++) {
13690                String packageName = packageNames[i];
13691                boolean changed = false;
13692                final int appId;
13693                synchronized (mPackages) {
13694                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13695                    if (pkgSetting == null) {
13696                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13697                                + "\". Skipping suspending/un-suspending.");
13698                        unactionedPackages.add(packageName);
13699                        continue;
13700                    }
13701                    appId = pkgSetting.appId;
13702                    if (pkgSetting.getSuspended(userId) != suspended) {
13703                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13704                            unactionedPackages.add(packageName);
13705                            continue;
13706                        }
13707                        pkgSetting.setSuspended(suspended, userId);
13708                        mSettings.writePackageRestrictionsLPr(userId);
13709                        changed = true;
13710                        changedPackages.add(packageName);
13711                    }
13712                }
13713
13714                if (changed && suspended) {
13715                    killApplication(packageName, UserHandle.getUid(userId, appId),
13716                            "suspending package");
13717                }
13718            }
13719        } finally {
13720            Binder.restoreCallingIdentity(callingId);
13721        }
13722
13723        if (!changedPackages.isEmpty()) {
13724            sendPackagesSuspendedForUser(changedPackages.toArray(
13725                    new String[changedPackages.size()]), userId, suspended);
13726        }
13727
13728        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13729    }
13730
13731    @Override
13732    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13733        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13734                true /* requireFullPermission */, false /* checkShell */,
13735                "isPackageSuspendedForUser for user " + userId);
13736        synchronized (mPackages) {
13737            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13738            if (pkgSetting == null) {
13739                throw new IllegalArgumentException("Unknown target package: " + packageName);
13740            }
13741            return pkgSetting.getSuspended(userId);
13742        }
13743    }
13744
13745    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13746        if (isPackageDeviceAdmin(packageName, userId)) {
13747            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13748                    + "\": has an active device admin");
13749            return false;
13750        }
13751
13752        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13753        if (packageName.equals(activeLauncherPackageName)) {
13754            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13755                    + "\": contains the active launcher");
13756            return false;
13757        }
13758
13759        if (packageName.equals(mRequiredInstallerPackage)) {
13760            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13761                    + "\": required for package installation");
13762            return false;
13763        }
13764
13765        if (packageName.equals(mRequiredUninstallerPackage)) {
13766            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13767                    + "\": required for package uninstallation");
13768            return false;
13769        }
13770
13771        if (packageName.equals(mRequiredVerifierPackage)) {
13772            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13773                    + "\": required for package verification");
13774            return false;
13775        }
13776
13777        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13778            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13779                    + "\": is the default dialer");
13780            return false;
13781        }
13782
13783        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13784            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13785                    + "\": protected package");
13786            return false;
13787        }
13788
13789        // Cannot suspend static shared libs as they are considered
13790        // a part of the using app (emulating static linking). Also
13791        // static libs are installed always on internal storage.
13792        PackageParser.Package pkg = mPackages.get(packageName);
13793        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13794            Slog.w(TAG, "Cannot suspend package: " + packageName
13795                    + " providing static shared library: "
13796                    + pkg.staticSharedLibName);
13797            return false;
13798        }
13799
13800        return true;
13801    }
13802
13803    private String getActiveLauncherPackageName(int userId) {
13804        Intent intent = new Intent(Intent.ACTION_MAIN);
13805        intent.addCategory(Intent.CATEGORY_HOME);
13806        ResolveInfo resolveInfo = resolveIntent(
13807                intent,
13808                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13809                PackageManager.MATCH_DEFAULT_ONLY,
13810                userId);
13811
13812        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13813    }
13814
13815    private String getDefaultDialerPackageName(int userId) {
13816        synchronized (mPackages) {
13817            return mSettings.getDefaultDialerPackageNameLPw(userId);
13818        }
13819    }
13820
13821    @Override
13822    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13823        mContext.enforceCallingOrSelfPermission(
13824                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13825                "Only package verification agents can verify applications");
13826
13827        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13828        final PackageVerificationResponse response = new PackageVerificationResponse(
13829                verificationCode, Binder.getCallingUid());
13830        msg.arg1 = id;
13831        msg.obj = response;
13832        mHandler.sendMessage(msg);
13833    }
13834
13835    @Override
13836    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13837            long millisecondsToDelay) {
13838        mContext.enforceCallingOrSelfPermission(
13839                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13840                "Only package verification agents can extend verification timeouts");
13841
13842        final PackageVerificationState state = mPendingVerification.get(id);
13843        final PackageVerificationResponse response = new PackageVerificationResponse(
13844                verificationCodeAtTimeout, Binder.getCallingUid());
13845
13846        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13847            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13848        }
13849        if (millisecondsToDelay < 0) {
13850            millisecondsToDelay = 0;
13851        }
13852        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13853                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13854            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13855        }
13856
13857        if ((state != null) && !state.timeoutExtended()) {
13858            state.extendTimeout();
13859
13860            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13861            msg.arg1 = id;
13862            msg.obj = response;
13863            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13864        }
13865    }
13866
13867    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13868            int verificationCode, UserHandle user) {
13869        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13870        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13871        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13872        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13873        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13874
13875        mContext.sendBroadcastAsUser(intent, user,
13876                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13877    }
13878
13879    private ComponentName matchComponentForVerifier(String packageName,
13880            List<ResolveInfo> receivers) {
13881        ActivityInfo targetReceiver = null;
13882
13883        final int NR = receivers.size();
13884        for (int i = 0; i < NR; i++) {
13885            final ResolveInfo info = receivers.get(i);
13886            if (info.activityInfo == null) {
13887                continue;
13888            }
13889
13890            if (packageName.equals(info.activityInfo.packageName)) {
13891                targetReceiver = info.activityInfo;
13892                break;
13893            }
13894        }
13895
13896        if (targetReceiver == null) {
13897            return null;
13898        }
13899
13900        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13901    }
13902
13903    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13904            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13905        if (pkgInfo.verifiers.length == 0) {
13906            return null;
13907        }
13908
13909        final int N = pkgInfo.verifiers.length;
13910        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13911        for (int i = 0; i < N; i++) {
13912            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13913
13914            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13915                    receivers);
13916            if (comp == null) {
13917                continue;
13918            }
13919
13920            final int verifierUid = getUidForVerifier(verifierInfo);
13921            if (verifierUid == -1) {
13922                continue;
13923            }
13924
13925            if (DEBUG_VERIFY) {
13926                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13927                        + " with the correct signature");
13928            }
13929            sufficientVerifiers.add(comp);
13930            verificationState.addSufficientVerifier(verifierUid);
13931        }
13932
13933        return sufficientVerifiers;
13934    }
13935
13936    private int getUidForVerifier(VerifierInfo verifierInfo) {
13937        synchronized (mPackages) {
13938            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13939            if (pkg == null) {
13940                return -1;
13941            } else if (pkg.mSignatures.length != 1) {
13942                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13943                        + " has more than one signature; ignoring");
13944                return -1;
13945            }
13946
13947            /*
13948             * If the public key of the package's signature does not match
13949             * our expected public key, then this is a different package and
13950             * we should skip.
13951             */
13952
13953            final byte[] expectedPublicKey;
13954            try {
13955                final Signature verifierSig = pkg.mSignatures[0];
13956                final PublicKey publicKey = verifierSig.getPublicKey();
13957                expectedPublicKey = publicKey.getEncoded();
13958            } catch (CertificateException e) {
13959                return -1;
13960            }
13961
13962            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13963
13964            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13965                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13966                        + " does not have the expected public key; ignoring");
13967                return -1;
13968            }
13969
13970            return pkg.applicationInfo.uid;
13971        }
13972    }
13973
13974    @Override
13975    public void finishPackageInstall(int token, boolean didLaunch) {
13976        enforceSystemOrRoot("Only the system is allowed to finish installs");
13977
13978        if (DEBUG_INSTALL) {
13979            Slog.v(TAG, "BM finishing package install for " + token);
13980        }
13981        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13982
13983        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13984        mHandler.sendMessage(msg);
13985    }
13986
13987    /**
13988     * Get the verification agent timeout.  Used for both the APK verifier and the
13989     * intent filter verifier.
13990     *
13991     * @return verification timeout in milliseconds
13992     */
13993    private long getVerificationTimeout() {
13994        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13995                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13996                DEFAULT_VERIFICATION_TIMEOUT);
13997    }
13998
13999    /**
14000     * Get the default verification agent response code.
14001     *
14002     * @return default verification response code
14003     */
14004    private int getDefaultVerificationResponse() {
14005        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14006                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14007                DEFAULT_VERIFICATION_RESPONSE);
14008    }
14009
14010    /**
14011     * Check whether or not package verification has been enabled.
14012     *
14013     * @return true if verification should be performed
14014     */
14015    private boolean isVerificationEnabled(int userId, int installFlags) {
14016        if (!DEFAULT_VERIFY_ENABLE) {
14017            return false;
14018        }
14019
14020        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14021
14022        // Check if installing from ADB
14023        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14024            // Do not run verification in a test harness environment
14025            if (ActivityManager.isRunningInTestHarness()) {
14026                return false;
14027            }
14028            if (ensureVerifyAppsEnabled) {
14029                return true;
14030            }
14031            // Check if the developer does not want package verification for ADB installs
14032            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14033                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14034                return false;
14035            }
14036        }
14037
14038        if (ensureVerifyAppsEnabled) {
14039            return true;
14040        }
14041
14042        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14043                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14044    }
14045
14046    @Override
14047    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14048            throws RemoteException {
14049        mContext.enforceCallingOrSelfPermission(
14050                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14051                "Only intentfilter verification agents can verify applications");
14052
14053        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14054        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14055                Binder.getCallingUid(), verificationCode, failedDomains);
14056        msg.arg1 = id;
14057        msg.obj = response;
14058        mHandler.sendMessage(msg);
14059    }
14060
14061    @Override
14062    public int getIntentVerificationStatus(String packageName, int userId) {
14063        synchronized (mPackages) {
14064            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14065        }
14066    }
14067
14068    @Override
14069    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14070        mContext.enforceCallingOrSelfPermission(
14071                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14072
14073        boolean result = false;
14074        synchronized (mPackages) {
14075            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14076        }
14077        if (result) {
14078            scheduleWritePackageRestrictionsLocked(userId);
14079        }
14080        return result;
14081    }
14082
14083    @Override
14084    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14085            String packageName) {
14086        synchronized (mPackages) {
14087            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14088        }
14089    }
14090
14091    @Override
14092    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14093        if (TextUtils.isEmpty(packageName)) {
14094            return ParceledListSlice.emptyList();
14095        }
14096        synchronized (mPackages) {
14097            PackageParser.Package pkg = mPackages.get(packageName);
14098            if (pkg == null || pkg.activities == null) {
14099                return ParceledListSlice.emptyList();
14100            }
14101            final int count = pkg.activities.size();
14102            ArrayList<IntentFilter> result = new ArrayList<>();
14103            for (int n=0; n<count; n++) {
14104                PackageParser.Activity activity = pkg.activities.get(n);
14105                if (activity.intents != null && activity.intents.size() > 0) {
14106                    result.addAll(activity.intents);
14107                }
14108            }
14109            return new ParceledListSlice<>(result);
14110        }
14111    }
14112
14113    @Override
14114    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14115        mContext.enforceCallingOrSelfPermission(
14116                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14117
14118        synchronized (mPackages) {
14119            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14120            if (packageName != null) {
14121                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14122                        packageName, userId);
14123            }
14124            return result;
14125        }
14126    }
14127
14128    @Override
14129    public String getDefaultBrowserPackageName(int userId) {
14130        synchronized (mPackages) {
14131            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14132        }
14133    }
14134
14135    /**
14136     * Get the "allow unknown sources" setting.
14137     *
14138     * @return the current "allow unknown sources" setting
14139     */
14140    private int getUnknownSourcesSettings() {
14141        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14142                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14143                -1);
14144    }
14145
14146    @Override
14147    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14148        final int uid = Binder.getCallingUid();
14149        // writer
14150        synchronized (mPackages) {
14151            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14152            if (targetPackageSetting == null) {
14153                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14154            }
14155
14156            PackageSetting installerPackageSetting;
14157            if (installerPackageName != null) {
14158                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14159                if (installerPackageSetting == null) {
14160                    throw new IllegalArgumentException("Unknown installer package: "
14161                            + installerPackageName);
14162                }
14163            } else {
14164                installerPackageSetting = null;
14165            }
14166
14167            Signature[] callerSignature;
14168            Object obj = mSettings.getUserIdLPr(uid);
14169            if (obj != null) {
14170                if (obj instanceof SharedUserSetting) {
14171                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14172                } else if (obj instanceof PackageSetting) {
14173                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14174                } else {
14175                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
14176                }
14177            } else {
14178                throw new SecurityException("Unknown calling UID: " + uid);
14179            }
14180
14181            // Verify: can't set installerPackageName to a package that is
14182            // not signed with the same cert as the caller.
14183            if (installerPackageSetting != null) {
14184                if (compareSignatures(callerSignature,
14185                        installerPackageSetting.signatures.mSignatures)
14186                        != PackageManager.SIGNATURE_MATCH) {
14187                    throw new SecurityException(
14188                            "Caller does not have same cert as new installer package "
14189                            + installerPackageName);
14190                }
14191            }
14192
14193            // Verify: if target already has an installer package, it must
14194            // be signed with the same cert as the caller.
14195            if (targetPackageSetting.installerPackageName != null) {
14196                PackageSetting setting = mSettings.mPackages.get(
14197                        targetPackageSetting.installerPackageName);
14198                // If the currently set package isn't valid, then it's always
14199                // okay to change it.
14200                if (setting != null) {
14201                    if (compareSignatures(callerSignature,
14202                            setting.signatures.mSignatures)
14203                            != PackageManager.SIGNATURE_MATCH) {
14204                        throw new SecurityException(
14205                                "Caller does not have same cert as old installer package "
14206                                + targetPackageSetting.installerPackageName);
14207                    }
14208                }
14209            }
14210
14211            // Okay!
14212            targetPackageSetting.installerPackageName = installerPackageName;
14213            if (installerPackageName != null) {
14214                mSettings.mInstallerPackages.add(installerPackageName);
14215            }
14216            scheduleWriteSettingsLocked();
14217        }
14218    }
14219
14220    @Override
14221    public void setApplicationCategoryHint(String packageName, int categoryHint,
14222            String callerPackageName) {
14223        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14224                callerPackageName);
14225        synchronized (mPackages) {
14226            PackageSetting ps = mSettings.mPackages.get(packageName);
14227            if (ps == null) {
14228                throw new IllegalArgumentException("Unknown target package " + packageName);
14229            }
14230
14231            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14232                throw new IllegalArgumentException("Calling package " + callerPackageName
14233                        + " is not installer for " + packageName);
14234            }
14235
14236            if (ps.categoryHint != categoryHint) {
14237                ps.categoryHint = categoryHint;
14238                scheduleWriteSettingsLocked();
14239            }
14240        }
14241    }
14242
14243    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14244        // Queue up an async operation since the package installation may take a little while.
14245        mHandler.post(new Runnable() {
14246            public void run() {
14247                mHandler.removeCallbacks(this);
14248                 // Result object to be returned
14249                PackageInstalledInfo res = new PackageInstalledInfo();
14250                res.setReturnCode(currentStatus);
14251                res.uid = -1;
14252                res.pkg = null;
14253                res.removedInfo = null;
14254                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14255                    args.doPreInstall(res.returnCode);
14256                    synchronized (mInstallLock) {
14257                        installPackageTracedLI(args, res);
14258                    }
14259                    args.doPostInstall(res.returnCode, res.uid);
14260                }
14261
14262                // A restore should be performed at this point if (a) the install
14263                // succeeded, (b) the operation is not an update, and (c) the new
14264                // package has not opted out of backup participation.
14265                final boolean update = res.removedInfo != null
14266                        && res.removedInfo.removedPackage != null;
14267                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14268                boolean doRestore = !update
14269                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14270
14271                // Set up the post-install work request bookkeeping.  This will be used
14272                // and cleaned up by the post-install event handling regardless of whether
14273                // there's a restore pass performed.  Token values are >= 1.
14274                int token;
14275                if (mNextInstallToken < 0) mNextInstallToken = 1;
14276                token = mNextInstallToken++;
14277
14278                PostInstallData data = new PostInstallData(args, res);
14279                mRunningInstalls.put(token, data);
14280                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14281
14282                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14283                    // Pass responsibility to the Backup Manager.  It will perform a
14284                    // restore if appropriate, then pass responsibility back to the
14285                    // Package Manager to run the post-install observer callbacks
14286                    // and broadcasts.
14287                    IBackupManager bm = IBackupManager.Stub.asInterface(
14288                            ServiceManager.getService(Context.BACKUP_SERVICE));
14289                    if (bm != null) {
14290                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14291                                + " to BM for possible restore");
14292                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14293                        try {
14294                            // TODO: http://b/22388012
14295                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14296                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14297                            } else {
14298                                doRestore = false;
14299                            }
14300                        } catch (RemoteException e) {
14301                            // can't happen; the backup manager is local
14302                        } catch (Exception e) {
14303                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14304                            doRestore = false;
14305                        }
14306                    } else {
14307                        Slog.e(TAG, "Backup Manager not found!");
14308                        doRestore = false;
14309                    }
14310                }
14311
14312                if (!doRestore) {
14313                    // No restore possible, or the Backup Manager was mysteriously not
14314                    // available -- just fire the post-install work request directly.
14315                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14316
14317                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14318
14319                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14320                    mHandler.sendMessage(msg);
14321                }
14322            }
14323        });
14324    }
14325
14326    /**
14327     * Callback from PackageSettings whenever an app is first transitioned out of the
14328     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14329     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14330     * here whether the app is the target of an ongoing install, and only send the
14331     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14332     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14333     * handling.
14334     */
14335    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14336        // Serialize this with the rest of the install-process message chain.  In the
14337        // restore-at-install case, this Runnable will necessarily run before the
14338        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14339        // are coherent.  In the non-restore case, the app has already completed install
14340        // and been launched through some other means, so it is not in a problematic
14341        // state for observers to see the FIRST_LAUNCH signal.
14342        mHandler.post(new Runnable() {
14343            @Override
14344            public void run() {
14345                for (int i = 0; i < mRunningInstalls.size(); i++) {
14346                    final PostInstallData data = mRunningInstalls.valueAt(i);
14347                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14348                        continue;
14349                    }
14350                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14351                        // right package; but is it for the right user?
14352                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14353                            if (userId == data.res.newUsers[uIndex]) {
14354                                if (DEBUG_BACKUP) {
14355                                    Slog.i(TAG, "Package " + pkgName
14356                                            + " being restored so deferring FIRST_LAUNCH");
14357                                }
14358                                return;
14359                            }
14360                        }
14361                    }
14362                }
14363                // didn't find it, so not being restored
14364                if (DEBUG_BACKUP) {
14365                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14366                }
14367                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14368            }
14369        });
14370    }
14371
14372    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14373        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14374                installerPkg, null, userIds);
14375    }
14376
14377    private abstract class HandlerParams {
14378        private static final int MAX_RETRIES = 4;
14379
14380        /**
14381         * Number of times startCopy() has been attempted and had a non-fatal
14382         * error.
14383         */
14384        private int mRetries = 0;
14385
14386        /** User handle for the user requesting the information or installation. */
14387        private final UserHandle mUser;
14388        String traceMethod;
14389        int traceCookie;
14390
14391        HandlerParams(UserHandle user) {
14392            mUser = user;
14393        }
14394
14395        UserHandle getUser() {
14396            return mUser;
14397        }
14398
14399        HandlerParams setTraceMethod(String traceMethod) {
14400            this.traceMethod = traceMethod;
14401            return this;
14402        }
14403
14404        HandlerParams setTraceCookie(int traceCookie) {
14405            this.traceCookie = traceCookie;
14406            return this;
14407        }
14408
14409        final boolean startCopy() {
14410            boolean res;
14411            try {
14412                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14413
14414                if (++mRetries > MAX_RETRIES) {
14415                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14416                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14417                    handleServiceError();
14418                    return false;
14419                } else {
14420                    handleStartCopy();
14421                    res = true;
14422                }
14423            } catch (RemoteException e) {
14424                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14425                mHandler.sendEmptyMessage(MCS_RECONNECT);
14426                res = false;
14427            }
14428            handleReturnCode();
14429            return res;
14430        }
14431
14432        final void serviceError() {
14433            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14434            handleServiceError();
14435            handleReturnCode();
14436        }
14437
14438        abstract void handleStartCopy() throws RemoteException;
14439        abstract void handleServiceError();
14440        abstract void handleReturnCode();
14441    }
14442
14443    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14444        for (File path : paths) {
14445            try {
14446                mcs.clearDirectory(path.getAbsolutePath());
14447            } catch (RemoteException e) {
14448            }
14449        }
14450    }
14451
14452    static class OriginInfo {
14453        /**
14454         * Location where install is coming from, before it has been
14455         * copied/renamed into place. This could be a single monolithic APK
14456         * file, or a cluster directory. This location may be untrusted.
14457         */
14458        final File file;
14459        final String cid;
14460
14461        /**
14462         * Flag indicating that {@link #file} or {@link #cid} has already been
14463         * staged, meaning downstream users don't need to defensively copy the
14464         * contents.
14465         */
14466        final boolean staged;
14467
14468        /**
14469         * Flag indicating that {@link #file} or {@link #cid} is an already
14470         * installed app that is being moved.
14471         */
14472        final boolean existing;
14473
14474        final String resolvedPath;
14475        final File resolvedFile;
14476
14477        static OriginInfo fromNothing() {
14478            return new OriginInfo(null, null, false, false);
14479        }
14480
14481        static OriginInfo fromUntrustedFile(File file) {
14482            return new OriginInfo(file, null, false, false);
14483        }
14484
14485        static OriginInfo fromExistingFile(File file) {
14486            return new OriginInfo(file, null, false, true);
14487        }
14488
14489        static OriginInfo fromStagedFile(File file) {
14490            return new OriginInfo(file, null, true, false);
14491        }
14492
14493        static OriginInfo fromStagedContainer(String cid) {
14494            return new OriginInfo(null, cid, true, false);
14495        }
14496
14497        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14498            this.file = file;
14499            this.cid = cid;
14500            this.staged = staged;
14501            this.existing = existing;
14502
14503            if (cid != null) {
14504                resolvedPath = PackageHelper.getSdDir(cid);
14505                resolvedFile = new File(resolvedPath);
14506            } else if (file != null) {
14507                resolvedPath = file.getAbsolutePath();
14508                resolvedFile = file;
14509            } else {
14510                resolvedPath = null;
14511                resolvedFile = null;
14512            }
14513        }
14514    }
14515
14516    static class MoveInfo {
14517        final int moveId;
14518        final String fromUuid;
14519        final String toUuid;
14520        final String packageName;
14521        final String dataAppName;
14522        final int appId;
14523        final String seinfo;
14524        final int targetSdkVersion;
14525
14526        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14527                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14528            this.moveId = moveId;
14529            this.fromUuid = fromUuid;
14530            this.toUuid = toUuid;
14531            this.packageName = packageName;
14532            this.dataAppName = dataAppName;
14533            this.appId = appId;
14534            this.seinfo = seinfo;
14535            this.targetSdkVersion = targetSdkVersion;
14536        }
14537    }
14538
14539    static class VerificationInfo {
14540        /** A constant used to indicate that a uid value is not present. */
14541        public static final int NO_UID = -1;
14542
14543        /** URI referencing where the package was downloaded from. */
14544        final Uri originatingUri;
14545
14546        /** HTTP referrer URI associated with the originatingURI. */
14547        final Uri referrer;
14548
14549        /** UID of the application that the install request originated from. */
14550        final int originatingUid;
14551
14552        /** UID of application requesting the install */
14553        final int installerUid;
14554
14555        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14556            this.originatingUri = originatingUri;
14557            this.referrer = referrer;
14558            this.originatingUid = originatingUid;
14559            this.installerUid = installerUid;
14560        }
14561    }
14562
14563    class InstallParams extends HandlerParams {
14564        final OriginInfo origin;
14565        final MoveInfo move;
14566        final IPackageInstallObserver2 observer;
14567        int installFlags;
14568        final String installerPackageName;
14569        final String volumeUuid;
14570        private InstallArgs mArgs;
14571        private int mRet;
14572        final String packageAbiOverride;
14573        final String[] grantedRuntimePermissions;
14574        final VerificationInfo verificationInfo;
14575        final Certificate[][] certificates;
14576        final int installReason;
14577
14578        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14579                int installFlags, String installerPackageName, String volumeUuid,
14580                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14581                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14582            super(user);
14583            this.origin = origin;
14584            this.move = move;
14585            this.observer = observer;
14586            this.installFlags = installFlags;
14587            this.installerPackageName = installerPackageName;
14588            this.volumeUuid = volumeUuid;
14589            this.verificationInfo = verificationInfo;
14590            this.packageAbiOverride = packageAbiOverride;
14591            this.grantedRuntimePermissions = grantedPermissions;
14592            this.certificates = certificates;
14593            this.installReason = installReason;
14594        }
14595
14596        @Override
14597        public String toString() {
14598            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14599                    + " file=" + origin.file + " cid=" + origin.cid + "}";
14600        }
14601
14602        private int installLocationPolicy(PackageInfoLite pkgLite) {
14603            String packageName = pkgLite.packageName;
14604            int installLocation = pkgLite.installLocation;
14605            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14606            // reader
14607            synchronized (mPackages) {
14608                // Currently installed package which the new package is attempting to replace or
14609                // null if no such package is installed.
14610                PackageParser.Package installedPkg = mPackages.get(packageName);
14611                // Package which currently owns the data which the new package will own if installed.
14612                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14613                // will be null whereas dataOwnerPkg will contain information about the package
14614                // which was uninstalled while keeping its data.
14615                PackageParser.Package dataOwnerPkg = installedPkg;
14616                if (dataOwnerPkg  == null) {
14617                    PackageSetting ps = mSettings.mPackages.get(packageName);
14618                    if (ps != null) {
14619                        dataOwnerPkg = ps.pkg;
14620                    }
14621                }
14622
14623                if (dataOwnerPkg != null) {
14624                    // If installed, the package will get access to data left on the device by its
14625                    // predecessor. As a security measure, this is permited only if this is not a
14626                    // version downgrade or if the predecessor package is marked as debuggable and
14627                    // a downgrade is explicitly requested.
14628                    //
14629                    // On debuggable platform builds, downgrades are permitted even for
14630                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14631                    // not offer security guarantees and thus it's OK to disable some security
14632                    // mechanisms to make debugging/testing easier on those builds. However, even on
14633                    // debuggable builds downgrades of packages are permitted only if requested via
14634                    // installFlags. This is because we aim to keep the behavior of debuggable
14635                    // platform builds as close as possible to the behavior of non-debuggable
14636                    // platform builds.
14637                    final boolean downgradeRequested =
14638                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14639                    final boolean packageDebuggable =
14640                                (dataOwnerPkg.applicationInfo.flags
14641                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14642                    final boolean downgradePermitted =
14643                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14644                    if (!downgradePermitted) {
14645                        try {
14646                            checkDowngrade(dataOwnerPkg, pkgLite);
14647                        } catch (PackageManagerException e) {
14648                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14649                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14650                        }
14651                    }
14652                }
14653
14654                if (installedPkg != null) {
14655                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14656                        // Check for updated system application.
14657                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14658                            if (onSd) {
14659                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14660                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14661                            }
14662                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14663                        } else {
14664                            if (onSd) {
14665                                // Install flag overrides everything.
14666                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14667                            }
14668                            // If current upgrade specifies particular preference
14669                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14670                                // Application explicitly specified internal.
14671                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14672                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14673                                // App explictly prefers external. Let policy decide
14674                            } else {
14675                                // Prefer previous location
14676                                if (isExternal(installedPkg)) {
14677                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14678                                }
14679                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14680                            }
14681                        }
14682                    } else {
14683                        // Invalid install. Return error code
14684                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14685                    }
14686                }
14687            }
14688            // All the special cases have been taken care of.
14689            // Return result based on recommended install location.
14690            if (onSd) {
14691                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14692            }
14693            return pkgLite.recommendedInstallLocation;
14694        }
14695
14696        /*
14697         * Invoke remote method to get package information and install
14698         * location values. Override install location based on default
14699         * policy if needed and then create install arguments based
14700         * on the install location.
14701         */
14702        public void handleStartCopy() throws RemoteException {
14703            int ret = PackageManager.INSTALL_SUCCEEDED;
14704
14705            // If we're already staged, we've firmly committed to an install location
14706            if (origin.staged) {
14707                if (origin.file != null) {
14708                    installFlags |= PackageManager.INSTALL_INTERNAL;
14709                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14710                } else if (origin.cid != null) {
14711                    installFlags |= PackageManager.INSTALL_EXTERNAL;
14712                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
14713                } else {
14714                    throw new IllegalStateException("Invalid stage location");
14715                }
14716            }
14717
14718            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14719            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14720            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14721            PackageInfoLite pkgLite = null;
14722
14723            if (onInt && onSd) {
14724                // Check if both bits are set.
14725                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14726                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14727            } else if (onSd && ephemeral) {
14728                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14729                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14730            } else {
14731                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14732                        packageAbiOverride);
14733
14734                if (DEBUG_EPHEMERAL && ephemeral) {
14735                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14736                }
14737
14738                /*
14739                 * If we have too little free space, try to free cache
14740                 * before giving up.
14741                 */
14742                if (!origin.staged && pkgLite.recommendedInstallLocation
14743                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14744                    // TODO: focus freeing disk space on the target device
14745                    final StorageManager storage = StorageManager.from(mContext);
14746                    final long lowThreshold = storage.getStorageLowBytes(
14747                            Environment.getDataDirectory());
14748
14749                    final long sizeBytes = mContainerService.calculateInstalledSize(
14750                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
14751
14752                    try {
14753                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
14754                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14755                                installFlags, packageAbiOverride);
14756                    } catch (InstallerException e) {
14757                        Slog.w(TAG, "Failed to free cache", e);
14758                    }
14759
14760                    /*
14761                     * The cache free must have deleted the file we
14762                     * downloaded to install.
14763                     *
14764                     * TODO: fix the "freeCache" call to not delete
14765                     *       the file we care about.
14766                     */
14767                    if (pkgLite.recommendedInstallLocation
14768                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14769                        pkgLite.recommendedInstallLocation
14770                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14771                    }
14772                }
14773            }
14774
14775            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14776                int loc = pkgLite.recommendedInstallLocation;
14777                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14778                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14779                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14780                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14781                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14782                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14783                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14784                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14785                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14786                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14787                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14788                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14789                } else {
14790                    // Override with defaults if needed.
14791                    loc = installLocationPolicy(pkgLite);
14792                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14793                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14794                    } else if (!onSd && !onInt) {
14795                        // Override install location with flags
14796                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14797                            // Set the flag to install on external media.
14798                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14799                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14800                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14801                            if (DEBUG_EPHEMERAL) {
14802                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14803                            }
14804                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14805                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14806                                    |PackageManager.INSTALL_INTERNAL);
14807                        } else {
14808                            // Make sure the flag for installing on external
14809                            // media is unset
14810                            installFlags |= PackageManager.INSTALL_INTERNAL;
14811                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14812                        }
14813                    }
14814                }
14815            }
14816
14817            final InstallArgs args = createInstallArgs(this);
14818            mArgs = args;
14819
14820            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14821                // TODO: http://b/22976637
14822                // Apps installed for "all" users use the device owner to verify the app
14823                UserHandle verifierUser = getUser();
14824                if (verifierUser == UserHandle.ALL) {
14825                    verifierUser = UserHandle.SYSTEM;
14826                }
14827
14828                /*
14829                 * Determine if we have any installed package verifiers. If we
14830                 * do, then we'll defer to them to verify the packages.
14831                 */
14832                final int requiredUid = mRequiredVerifierPackage == null ? -1
14833                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14834                                verifierUser.getIdentifier());
14835                if (!origin.existing && requiredUid != -1
14836                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
14837                    final Intent verification = new Intent(
14838                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14839                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14840                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14841                            PACKAGE_MIME_TYPE);
14842                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14843
14844                    // Query all live verifiers based on current user state
14845                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14846                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
14847
14848                    if (DEBUG_VERIFY) {
14849                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14850                                + verification.toString() + " with " + pkgLite.verifiers.length
14851                                + " optional verifiers");
14852                    }
14853
14854                    final int verificationId = mPendingVerificationToken++;
14855
14856                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14857
14858                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14859                            installerPackageName);
14860
14861                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14862                            installFlags);
14863
14864                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14865                            pkgLite.packageName);
14866
14867                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14868                            pkgLite.versionCode);
14869
14870                    if (verificationInfo != null) {
14871                        if (verificationInfo.originatingUri != null) {
14872                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14873                                    verificationInfo.originatingUri);
14874                        }
14875                        if (verificationInfo.referrer != null) {
14876                            verification.putExtra(Intent.EXTRA_REFERRER,
14877                                    verificationInfo.referrer);
14878                        }
14879                        if (verificationInfo.originatingUid >= 0) {
14880                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14881                                    verificationInfo.originatingUid);
14882                        }
14883                        if (verificationInfo.installerUid >= 0) {
14884                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14885                                    verificationInfo.installerUid);
14886                        }
14887                    }
14888
14889                    final PackageVerificationState verificationState = new PackageVerificationState(
14890                            requiredUid, args);
14891
14892                    mPendingVerification.append(verificationId, verificationState);
14893
14894                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14895                            receivers, verificationState);
14896
14897                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14898                    final long idleDuration = getVerificationTimeout();
14899
14900                    /*
14901                     * If any sufficient verifiers were listed in the package
14902                     * manifest, attempt to ask them.
14903                     */
14904                    if (sufficientVerifiers != null) {
14905                        final int N = sufficientVerifiers.size();
14906                        if (N == 0) {
14907                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14908                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14909                        } else {
14910                            for (int i = 0; i < N; i++) {
14911                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14912                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14913                                        verifierComponent.getPackageName(), idleDuration,
14914                                        verifierUser.getIdentifier(), false, "package verifier");
14915
14916                                final Intent sufficientIntent = new Intent(verification);
14917                                sufficientIntent.setComponent(verifierComponent);
14918                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14919                            }
14920                        }
14921                    }
14922
14923                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14924                            mRequiredVerifierPackage, receivers);
14925                    if (ret == PackageManager.INSTALL_SUCCEEDED
14926                            && mRequiredVerifierPackage != null) {
14927                        Trace.asyncTraceBegin(
14928                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14929                        /*
14930                         * Send the intent to the required verification agent,
14931                         * but only start the verification timeout after the
14932                         * target BroadcastReceivers have run.
14933                         */
14934                        verification.setComponent(requiredVerifierComponent);
14935                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14936                                mRequiredVerifierPackage, idleDuration,
14937                                verifierUser.getIdentifier(), false, "package verifier");
14938                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14939                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14940                                new BroadcastReceiver() {
14941                                    @Override
14942                                    public void onReceive(Context context, Intent intent) {
14943                                        final Message msg = mHandler
14944                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14945                                        msg.arg1 = verificationId;
14946                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14947                                    }
14948                                }, null, 0, null, null);
14949
14950                        /*
14951                         * We don't want the copy to proceed until verification
14952                         * succeeds, so null out this field.
14953                         */
14954                        mArgs = null;
14955                    }
14956                } else {
14957                    /*
14958                     * No package verification is enabled, so immediately start
14959                     * the remote call to initiate copy using temporary file.
14960                     */
14961                    ret = args.copyApk(mContainerService, true);
14962                }
14963            }
14964
14965            mRet = ret;
14966        }
14967
14968        @Override
14969        void handleReturnCode() {
14970            // If mArgs is null, then MCS couldn't be reached. When it
14971            // reconnects, it will try again to install. At that point, this
14972            // will succeed.
14973            if (mArgs != null) {
14974                processPendingInstall(mArgs, mRet);
14975            }
14976        }
14977
14978        @Override
14979        void handleServiceError() {
14980            mArgs = createInstallArgs(this);
14981            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14982        }
14983
14984        public boolean isForwardLocked() {
14985            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14986        }
14987    }
14988
14989    /**
14990     * Used during creation of InstallArgs
14991     *
14992     * @param installFlags package installation flags
14993     * @return true if should be installed on external storage
14994     */
14995    private static boolean installOnExternalAsec(int installFlags) {
14996        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
14997            return false;
14998        }
14999        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15000            return true;
15001        }
15002        return false;
15003    }
15004
15005    /**
15006     * Used during creation of InstallArgs
15007     *
15008     * @param installFlags package installation flags
15009     * @return true if should be installed as forward locked
15010     */
15011    private static boolean installForwardLocked(int installFlags) {
15012        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15013    }
15014
15015    private InstallArgs createInstallArgs(InstallParams params) {
15016        if (params.move != null) {
15017            return new MoveInstallArgs(params);
15018        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15019            return new AsecInstallArgs(params);
15020        } else {
15021            return new FileInstallArgs(params);
15022        }
15023    }
15024
15025    /**
15026     * Create args that describe an existing installed package. Typically used
15027     * when cleaning up old installs, or used as a move source.
15028     */
15029    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15030            String resourcePath, String[] instructionSets) {
15031        final boolean isInAsec;
15032        if (installOnExternalAsec(installFlags)) {
15033            /* Apps on SD card are always in ASEC containers. */
15034            isInAsec = true;
15035        } else if (installForwardLocked(installFlags)
15036                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15037            /*
15038             * Forward-locked apps are only in ASEC containers if they're the
15039             * new style
15040             */
15041            isInAsec = true;
15042        } else {
15043            isInAsec = false;
15044        }
15045
15046        if (isInAsec) {
15047            return new AsecInstallArgs(codePath, instructionSets,
15048                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15049        } else {
15050            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15051        }
15052    }
15053
15054    static abstract class InstallArgs {
15055        /** @see InstallParams#origin */
15056        final OriginInfo origin;
15057        /** @see InstallParams#move */
15058        final MoveInfo move;
15059
15060        final IPackageInstallObserver2 observer;
15061        // Always refers to PackageManager flags only
15062        final int installFlags;
15063        final String installerPackageName;
15064        final String volumeUuid;
15065        final UserHandle user;
15066        final String abiOverride;
15067        final String[] installGrantPermissions;
15068        /** If non-null, drop an async trace when the install completes */
15069        final String traceMethod;
15070        final int traceCookie;
15071        final Certificate[][] certificates;
15072        final int installReason;
15073
15074        // The list of instruction sets supported by this app. This is currently
15075        // only used during the rmdex() phase to clean up resources. We can get rid of this
15076        // if we move dex files under the common app path.
15077        /* nullable */ String[] instructionSets;
15078
15079        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15080                int installFlags, String installerPackageName, String volumeUuid,
15081                UserHandle user, String[] instructionSets,
15082                String abiOverride, String[] installGrantPermissions,
15083                String traceMethod, int traceCookie, Certificate[][] certificates,
15084                int installReason) {
15085            this.origin = origin;
15086            this.move = move;
15087            this.installFlags = installFlags;
15088            this.observer = observer;
15089            this.installerPackageName = installerPackageName;
15090            this.volumeUuid = volumeUuid;
15091            this.user = user;
15092            this.instructionSets = instructionSets;
15093            this.abiOverride = abiOverride;
15094            this.installGrantPermissions = installGrantPermissions;
15095            this.traceMethod = traceMethod;
15096            this.traceCookie = traceCookie;
15097            this.certificates = certificates;
15098            this.installReason = installReason;
15099        }
15100
15101        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15102        abstract int doPreInstall(int status);
15103
15104        /**
15105         * Rename package into final resting place. All paths on the given
15106         * scanned package should be updated to reflect the rename.
15107         */
15108        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15109        abstract int doPostInstall(int status, int uid);
15110
15111        /** @see PackageSettingBase#codePathString */
15112        abstract String getCodePath();
15113        /** @see PackageSettingBase#resourcePathString */
15114        abstract String getResourcePath();
15115
15116        // Need installer lock especially for dex file removal.
15117        abstract void cleanUpResourcesLI();
15118        abstract boolean doPostDeleteLI(boolean delete);
15119
15120        /**
15121         * Called before the source arguments are copied. This is used mostly
15122         * for MoveParams when it needs to read the source file to put it in the
15123         * destination.
15124         */
15125        int doPreCopy() {
15126            return PackageManager.INSTALL_SUCCEEDED;
15127        }
15128
15129        /**
15130         * Called after the source arguments are copied. This is used mostly for
15131         * MoveParams when it needs to read the source file to put it in the
15132         * destination.
15133         */
15134        int doPostCopy(int uid) {
15135            return PackageManager.INSTALL_SUCCEEDED;
15136        }
15137
15138        protected boolean isFwdLocked() {
15139            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15140        }
15141
15142        protected boolean isExternalAsec() {
15143            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15144        }
15145
15146        protected boolean isEphemeral() {
15147            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15148        }
15149
15150        UserHandle getUser() {
15151            return user;
15152        }
15153    }
15154
15155    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15156        if (!allCodePaths.isEmpty()) {
15157            if (instructionSets == null) {
15158                throw new IllegalStateException("instructionSet == null");
15159            }
15160            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15161            for (String codePath : allCodePaths) {
15162                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15163                    try {
15164                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15165                    } catch (InstallerException ignored) {
15166                    }
15167                }
15168            }
15169        }
15170    }
15171
15172    /**
15173     * Logic to handle installation of non-ASEC applications, including copying
15174     * and renaming logic.
15175     */
15176    class FileInstallArgs extends InstallArgs {
15177        private File codeFile;
15178        private File resourceFile;
15179
15180        // Example topology:
15181        // /data/app/com.example/base.apk
15182        // /data/app/com.example/split_foo.apk
15183        // /data/app/com.example/lib/arm/libfoo.so
15184        // /data/app/com.example/lib/arm64/libfoo.so
15185        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15186
15187        /** New install */
15188        FileInstallArgs(InstallParams params) {
15189            super(params.origin, params.move, params.observer, params.installFlags,
15190                    params.installerPackageName, params.volumeUuid,
15191                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15192                    params.grantedRuntimePermissions,
15193                    params.traceMethod, params.traceCookie, params.certificates,
15194                    params.installReason);
15195            if (isFwdLocked()) {
15196                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15197            }
15198        }
15199
15200        /** Existing install */
15201        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15202            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15203                    null, null, null, 0, null /*certificates*/,
15204                    PackageManager.INSTALL_REASON_UNKNOWN);
15205            this.codeFile = (codePath != null) ? new File(codePath) : null;
15206            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15207        }
15208
15209        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15210            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15211            try {
15212                return doCopyApk(imcs, temp);
15213            } finally {
15214                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15215            }
15216        }
15217
15218        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15219            if (origin.staged) {
15220                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15221                codeFile = origin.file;
15222                resourceFile = origin.file;
15223                return PackageManager.INSTALL_SUCCEEDED;
15224            }
15225
15226            try {
15227                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15228                final File tempDir =
15229                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15230                codeFile = tempDir;
15231                resourceFile = tempDir;
15232            } catch (IOException e) {
15233                Slog.w(TAG, "Failed to create copy file: " + e);
15234                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15235            }
15236
15237            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15238                @Override
15239                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15240                    if (!FileUtils.isValidExtFilename(name)) {
15241                        throw new IllegalArgumentException("Invalid filename: " + name);
15242                    }
15243                    try {
15244                        final File file = new File(codeFile, name);
15245                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15246                                O_RDWR | O_CREAT, 0644);
15247                        Os.chmod(file.getAbsolutePath(), 0644);
15248                        return new ParcelFileDescriptor(fd);
15249                    } catch (ErrnoException e) {
15250                        throw new RemoteException("Failed to open: " + e.getMessage());
15251                    }
15252                }
15253            };
15254
15255            int ret = PackageManager.INSTALL_SUCCEEDED;
15256            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15257            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15258                Slog.e(TAG, "Failed to copy package");
15259                return ret;
15260            }
15261
15262            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15263            NativeLibraryHelper.Handle handle = null;
15264            try {
15265                handle = NativeLibraryHelper.Handle.create(codeFile);
15266                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15267                        abiOverride);
15268            } catch (IOException e) {
15269                Slog.e(TAG, "Copying native libraries failed", e);
15270                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15271            } finally {
15272                IoUtils.closeQuietly(handle);
15273            }
15274
15275            return ret;
15276        }
15277
15278        int doPreInstall(int status) {
15279            if (status != PackageManager.INSTALL_SUCCEEDED) {
15280                cleanUp();
15281            }
15282            return status;
15283        }
15284
15285        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15286            if (status != PackageManager.INSTALL_SUCCEEDED) {
15287                cleanUp();
15288                return false;
15289            }
15290
15291            final File targetDir = codeFile.getParentFile();
15292            final File beforeCodeFile = codeFile;
15293            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15294
15295            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15296            try {
15297                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15298            } catch (ErrnoException e) {
15299                Slog.w(TAG, "Failed to rename", e);
15300                return false;
15301            }
15302
15303            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15304                Slog.w(TAG, "Failed to restorecon");
15305                return false;
15306            }
15307
15308            // Reflect the rename internally
15309            codeFile = afterCodeFile;
15310            resourceFile = afterCodeFile;
15311
15312            // Reflect the rename in scanned details
15313            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15314            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15315                    afterCodeFile, pkg.baseCodePath));
15316            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15317                    afterCodeFile, pkg.splitCodePaths));
15318
15319            // Reflect the rename in app info
15320            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15321            pkg.setApplicationInfoCodePath(pkg.codePath);
15322            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15323            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15324            pkg.setApplicationInfoResourcePath(pkg.codePath);
15325            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15326            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15327
15328            return true;
15329        }
15330
15331        int doPostInstall(int status, int uid) {
15332            if (status != PackageManager.INSTALL_SUCCEEDED) {
15333                cleanUp();
15334            }
15335            return status;
15336        }
15337
15338        @Override
15339        String getCodePath() {
15340            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15341        }
15342
15343        @Override
15344        String getResourcePath() {
15345            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15346        }
15347
15348        private boolean cleanUp() {
15349            if (codeFile == null || !codeFile.exists()) {
15350                return false;
15351            }
15352
15353            removeCodePathLI(codeFile);
15354
15355            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15356                resourceFile.delete();
15357            }
15358
15359            return true;
15360        }
15361
15362        void cleanUpResourcesLI() {
15363            // Try enumerating all code paths before deleting
15364            List<String> allCodePaths = Collections.EMPTY_LIST;
15365            if (codeFile != null && codeFile.exists()) {
15366                try {
15367                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15368                    allCodePaths = pkg.getAllCodePaths();
15369                } catch (PackageParserException e) {
15370                    // Ignored; we tried our best
15371                }
15372            }
15373
15374            cleanUp();
15375            removeDexFiles(allCodePaths, instructionSets);
15376        }
15377
15378        boolean doPostDeleteLI(boolean delete) {
15379            // XXX err, shouldn't we respect the delete flag?
15380            cleanUpResourcesLI();
15381            return true;
15382        }
15383    }
15384
15385    private boolean isAsecExternal(String cid) {
15386        final String asecPath = PackageHelper.getSdFilesystem(cid);
15387        return !asecPath.startsWith(mAsecInternalPath);
15388    }
15389
15390    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15391            PackageManagerException {
15392        if (copyRet < 0) {
15393            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15394                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15395                throw new PackageManagerException(copyRet, message);
15396            }
15397        }
15398    }
15399
15400    /**
15401     * Extract the StorageManagerService "container ID" from the full code path of an
15402     * .apk.
15403     */
15404    static String cidFromCodePath(String fullCodePath) {
15405        int eidx = fullCodePath.lastIndexOf("/");
15406        String subStr1 = fullCodePath.substring(0, eidx);
15407        int sidx = subStr1.lastIndexOf("/");
15408        return subStr1.substring(sidx+1, eidx);
15409    }
15410
15411    /**
15412     * Logic to handle installation of ASEC applications, including copying and
15413     * renaming logic.
15414     */
15415    class AsecInstallArgs extends InstallArgs {
15416        static final String RES_FILE_NAME = "pkg.apk";
15417        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15418
15419        String cid;
15420        String packagePath;
15421        String resourcePath;
15422
15423        /** New install */
15424        AsecInstallArgs(InstallParams params) {
15425            super(params.origin, params.move, params.observer, params.installFlags,
15426                    params.installerPackageName, params.volumeUuid,
15427                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15428                    params.grantedRuntimePermissions,
15429                    params.traceMethod, params.traceCookie, params.certificates,
15430                    params.installReason);
15431        }
15432
15433        /** Existing install */
15434        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15435                        boolean isExternal, boolean isForwardLocked) {
15436            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15437                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15438                    instructionSets, null, null, null, 0, null /*certificates*/,
15439                    PackageManager.INSTALL_REASON_UNKNOWN);
15440            // Hackily pretend we're still looking at a full code path
15441            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15442                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15443            }
15444
15445            // Extract cid from fullCodePath
15446            int eidx = fullCodePath.lastIndexOf("/");
15447            String subStr1 = fullCodePath.substring(0, eidx);
15448            int sidx = subStr1.lastIndexOf("/");
15449            cid = subStr1.substring(sidx+1, eidx);
15450            setMountPath(subStr1);
15451        }
15452
15453        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15454            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15455                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15456                    instructionSets, null, null, null, 0, null /*certificates*/,
15457                    PackageManager.INSTALL_REASON_UNKNOWN);
15458            this.cid = cid;
15459            setMountPath(PackageHelper.getSdDir(cid));
15460        }
15461
15462        void createCopyFile() {
15463            cid = mInstallerService.allocateExternalStageCidLegacy();
15464        }
15465
15466        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15467            if (origin.staged && origin.cid != null) {
15468                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15469                cid = origin.cid;
15470                setMountPath(PackageHelper.getSdDir(cid));
15471                return PackageManager.INSTALL_SUCCEEDED;
15472            }
15473
15474            if (temp) {
15475                createCopyFile();
15476            } else {
15477                /*
15478                 * Pre-emptively destroy the container since it's destroyed if
15479                 * copying fails due to it existing anyway.
15480                 */
15481                PackageHelper.destroySdDir(cid);
15482            }
15483
15484            final String newMountPath = imcs.copyPackageToContainer(
15485                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15486                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15487
15488            if (newMountPath != null) {
15489                setMountPath(newMountPath);
15490                return PackageManager.INSTALL_SUCCEEDED;
15491            } else {
15492                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15493            }
15494        }
15495
15496        @Override
15497        String getCodePath() {
15498            return packagePath;
15499        }
15500
15501        @Override
15502        String getResourcePath() {
15503            return resourcePath;
15504        }
15505
15506        int doPreInstall(int status) {
15507            if (status != PackageManager.INSTALL_SUCCEEDED) {
15508                // Destroy container
15509                PackageHelper.destroySdDir(cid);
15510            } else {
15511                boolean mounted = PackageHelper.isContainerMounted(cid);
15512                if (!mounted) {
15513                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15514                            Process.SYSTEM_UID);
15515                    if (newMountPath != null) {
15516                        setMountPath(newMountPath);
15517                    } else {
15518                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15519                    }
15520                }
15521            }
15522            return status;
15523        }
15524
15525        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15526            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15527            String newMountPath = null;
15528            if (PackageHelper.isContainerMounted(cid)) {
15529                // Unmount the container
15530                if (!PackageHelper.unMountSdDir(cid)) {
15531                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15532                    return false;
15533                }
15534            }
15535            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15536                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15537                        " which might be stale. Will try to clean up.");
15538                // Clean up the stale container and proceed to recreate.
15539                if (!PackageHelper.destroySdDir(newCacheId)) {
15540                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15541                    return false;
15542                }
15543                // Successfully cleaned up stale container. Try to rename again.
15544                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15545                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15546                            + " inspite of cleaning it up.");
15547                    return false;
15548                }
15549            }
15550            if (!PackageHelper.isContainerMounted(newCacheId)) {
15551                Slog.w(TAG, "Mounting container " + newCacheId);
15552                newMountPath = PackageHelper.mountSdDir(newCacheId,
15553                        getEncryptKey(), Process.SYSTEM_UID);
15554            } else {
15555                newMountPath = PackageHelper.getSdDir(newCacheId);
15556            }
15557            if (newMountPath == null) {
15558                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15559                return false;
15560            }
15561            Log.i(TAG, "Succesfully renamed " + cid +
15562                    " to " + newCacheId +
15563                    " at new path: " + newMountPath);
15564            cid = newCacheId;
15565
15566            final File beforeCodeFile = new File(packagePath);
15567            setMountPath(newMountPath);
15568            final File afterCodeFile = new File(packagePath);
15569
15570            // Reflect the rename in scanned details
15571            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15572            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15573                    afterCodeFile, pkg.baseCodePath));
15574            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15575                    afterCodeFile, pkg.splitCodePaths));
15576
15577            // Reflect the rename in app info
15578            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15579            pkg.setApplicationInfoCodePath(pkg.codePath);
15580            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15581            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15582            pkg.setApplicationInfoResourcePath(pkg.codePath);
15583            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15584            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15585
15586            return true;
15587        }
15588
15589        private void setMountPath(String mountPath) {
15590            final File mountFile = new File(mountPath);
15591
15592            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15593            if (monolithicFile.exists()) {
15594                packagePath = monolithicFile.getAbsolutePath();
15595                if (isFwdLocked()) {
15596                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15597                } else {
15598                    resourcePath = packagePath;
15599                }
15600            } else {
15601                packagePath = mountFile.getAbsolutePath();
15602                resourcePath = packagePath;
15603            }
15604        }
15605
15606        int doPostInstall(int status, int uid) {
15607            if (status != PackageManager.INSTALL_SUCCEEDED) {
15608                cleanUp();
15609            } else {
15610                final int groupOwner;
15611                final String protectedFile;
15612                if (isFwdLocked()) {
15613                    groupOwner = UserHandle.getSharedAppGid(uid);
15614                    protectedFile = RES_FILE_NAME;
15615                } else {
15616                    groupOwner = -1;
15617                    protectedFile = null;
15618                }
15619
15620                if (uid < Process.FIRST_APPLICATION_UID
15621                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15622                    Slog.e(TAG, "Failed to finalize " + cid);
15623                    PackageHelper.destroySdDir(cid);
15624                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15625                }
15626
15627                boolean mounted = PackageHelper.isContainerMounted(cid);
15628                if (!mounted) {
15629                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15630                }
15631            }
15632            return status;
15633        }
15634
15635        private void cleanUp() {
15636            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15637
15638            // Destroy secure container
15639            PackageHelper.destroySdDir(cid);
15640        }
15641
15642        private List<String> getAllCodePaths() {
15643            final File codeFile = new File(getCodePath());
15644            if (codeFile != null && codeFile.exists()) {
15645                try {
15646                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15647                    return pkg.getAllCodePaths();
15648                } catch (PackageParserException e) {
15649                    // Ignored; we tried our best
15650                }
15651            }
15652            return Collections.EMPTY_LIST;
15653        }
15654
15655        void cleanUpResourcesLI() {
15656            // Enumerate all code paths before deleting
15657            cleanUpResourcesLI(getAllCodePaths());
15658        }
15659
15660        private void cleanUpResourcesLI(List<String> allCodePaths) {
15661            cleanUp();
15662            removeDexFiles(allCodePaths, instructionSets);
15663        }
15664
15665        String getPackageName() {
15666            return getAsecPackageName(cid);
15667        }
15668
15669        boolean doPostDeleteLI(boolean delete) {
15670            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
15671            final List<String> allCodePaths = getAllCodePaths();
15672            boolean mounted = PackageHelper.isContainerMounted(cid);
15673            if (mounted) {
15674                // Unmount first
15675                if (PackageHelper.unMountSdDir(cid)) {
15676                    mounted = false;
15677                }
15678            }
15679            if (!mounted && delete) {
15680                cleanUpResourcesLI(allCodePaths);
15681            }
15682            return !mounted;
15683        }
15684
15685        @Override
15686        int doPreCopy() {
15687            if (isFwdLocked()) {
15688                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
15689                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
15690                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15691                }
15692            }
15693
15694            return PackageManager.INSTALL_SUCCEEDED;
15695        }
15696
15697        @Override
15698        int doPostCopy(int uid) {
15699            if (isFwdLocked()) {
15700                if (uid < Process.FIRST_APPLICATION_UID
15701                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
15702                                RES_FILE_NAME)) {
15703                    Slog.e(TAG, "Failed to finalize " + cid);
15704                    PackageHelper.destroySdDir(cid);
15705                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15706                }
15707            }
15708
15709            return PackageManager.INSTALL_SUCCEEDED;
15710        }
15711    }
15712
15713    /**
15714     * Logic to handle movement of existing installed applications.
15715     */
15716    class MoveInstallArgs extends InstallArgs {
15717        private File codeFile;
15718        private File resourceFile;
15719
15720        /** New install */
15721        MoveInstallArgs(InstallParams params) {
15722            super(params.origin, params.move, params.observer, params.installFlags,
15723                    params.installerPackageName, params.volumeUuid,
15724                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15725                    params.grantedRuntimePermissions,
15726                    params.traceMethod, params.traceCookie, params.certificates,
15727                    params.installReason);
15728        }
15729
15730        int copyApk(IMediaContainerService imcs, boolean temp) {
15731            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15732                    + move.fromUuid + " to " + move.toUuid);
15733            synchronized (mInstaller) {
15734                try {
15735                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15736                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15737                } catch (InstallerException e) {
15738                    Slog.w(TAG, "Failed to move app", e);
15739                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15740                }
15741            }
15742
15743            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15744            resourceFile = codeFile;
15745            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15746
15747            return PackageManager.INSTALL_SUCCEEDED;
15748        }
15749
15750        int doPreInstall(int status) {
15751            if (status != PackageManager.INSTALL_SUCCEEDED) {
15752                cleanUp(move.toUuid);
15753            }
15754            return status;
15755        }
15756
15757        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15758            if (status != PackageManager.INSTALL_SUCCEEDED) {
15759                cleanUp(move.toUuid);
15760                return false;
15761            }
15762
15763            // Reflect the move in app info
15764            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15765            pkg.setApplicationInfoCodePath(pkg.codePath);
15766            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15767            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15768            pkg.setApplicationInfoResourcePath(pkg.codePath);
15769            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15770            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15771
15772            return true;
15773        }
15774
15775        int doPostInstall(int status, int uid) {
15776            if (status == PackageManager.INSTALL_SUCCEEDED) {
15777                cleanUp(move.fromUuid);
15778            } else {
15779                cleanUp(move.toUuid);
15780            }
15781            return status;
15782        }
15783
15784        @Override
15785        String getCodePath() {
15786            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15787        }
15788
15789        @Override
15790        String getResourcePath() {
15791            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15792        }
15793
15794        private boolean cleanUp(String volumeUuid) {
15795            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15796                    move.dataAppName);
15797            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15798            final int[] userIds = sUserManager.getUserIds();
15799            synchronized (mInstallLock) {
15800                // Clean up both app data and code
15801                // All package moves are frozen until finished
15802                for (int userId : userIds) {
15803                    try {
15804                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15805                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15806                    } catch (InstallerException e) {
15807                        Slog.w(TAG, String.valueOf(e));
15808                    }
15809                }
15810                removeCodePathLI(codeFile);
15811            }
15812            return true;
15813        }
15814
15815        void cleanUpResourcesLI() {
15816            throw new UnsupportedOperationException();
15817        }
15818
15819        boolean doPostDeleteLI(boolean delete) {
15820            throw new UnsupportedOperationException();
15821        }
15822    }
15823
15824    static String getAsecPackageName(String packageCid) {
15825        int idx = packageCid.lastIndexOf("-");
15826        if (idx == -1) {
15827            return packageCid;
15828        }
15829        return packageCid.substring(0, idx);
15830    }
15831
15832    // Utility method used to create code paths based on package name and available index.
15833    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15834        String idxStr = "";
15835        int idx = 1;
15836        // Fall back to default value of idx=1 if prefix is not
15837        // part of oldCodePath
15838        if (oldCodePath != null) {
15839            String subStr = oldCodePath;
15840            // Drop the suffix right away
15841            if (suffix != null && subStr.endsWith(suffix)) {
15842                subStr = subStr.substring(0, subStr.length() - suffix.length());
15843            }
15844            // If oldCodePath already contains prefix find out the
15845            // ending index to either increment or decrement.
15846            int sidx = subStr.lastIndexOf(prefix);
15847            if (sidx != -1) {
15848                subStr = subStr.substring(sidx + prefix.length());
15849                if (subStr != null) {
15850                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15851                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15852                    }
15853                    try {
15854                        idx = Integer.parseInt(subStr);
15855                        if (idx <= 1) {
15856                            idx++;
15857                        } else {
15858                            idx--;
15859                        }
15860                    } catch(NumberFormatException e) {
15861                    }
15862                }
15863            }
15864        }
15865        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15866        return prefix + idxStr;
15867    }
15868
15869    private File getNextCodePath(File targetDir, String packageName) {
15870        File result;
15871        SecureRandom random = new SecureRandom();
15872        byte[] bytes = new byte[16];
15873        do {
15874            random.nextBytes(bytes);
15875            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15876            result = new File(targetDir, packageName + "-" + suffix);
15877        } while (result.exists());
15878        return result;
15879    }
15880
15881    // Utility method that returns the relative package path with respect
15882    // to the installation directory. Like say for /data/data/com.test-1.apk
15883    // string com.test-1 is returned.
15884    static String deriveCodePathName(String codePath) {
15885        if (codePath == null) {
15886            return null;
15887        }
15888        final File codeFile = new File(codePath);
15889        final String name = codeFile.getName();
15890        if (codeFile.isDirectory()) {
15891            return name;
15892        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15893            final int lastDot = name.lastIndexOf('.');
15894            return name.substring(0, lastDot);
15895        } else {
15896            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15897            return null;
15898        }
15899    }
15900
15901    static class PackageInstalledInfo {
15902        String name;
15903        int uid;
15904        // The set of users that originally had this package installed.
15905        int[] origUsers;
15906        // The set of users that now have this package installed.
15907        int[] newUsers;
15908        PackageParser.Package pkg;
15909        int returnCode;
15910        String returnMsg;
15911        PackageRemovedInfo removedInfo;
15912        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15913
15914        public void setError(int code, String msg) {
15915            setReturnCode(code);
15916            setReturnMessage(msg);
15917            Slog.w(TAG, msg);
15918        }
15919
15920        public void setError(String msg, PackageParserException e) {
15921            setReturnCode(e.error);
15922            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15923            Slog.w(TAG, msg, e);
15924        }
15925
15926        public void setError(String msg, PackageManagerException e) {
15927            returnCode = e.error;
15928            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15929            Slog.w(TAG, msg, e);
15930        }
15931
15932        public void setReturnCode(int returnCode) {
15933            this.returnCode = returnCode;
15934            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15935            for (int i = 0; i < childCount; i++) {
15936                addedChildPackages.valueAt(i).returnCode = returnCode;
15937            }
15938        }
15939
15940        private void setReturnMessage(String returnMsg) {
15941            this.returnMsg = returnMsg;
15942            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15943            for (int i = 0; i < childCount; i++) {
15944                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15945            }
15946        }
15947
15948        // In some error cases we want to convey more info back to the observer
15949        String origPackage;
15950        String origPermission;
15951    }
15952
15953    /*
15954     * Install a non-existing package.
15955     */
15956    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
15957            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
15958            PackageInstalledInfo res, int installReason) {
15959        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15960
15961        // Remember this for later, in case we need to rollback this install
15962        String pkgName = pkg.packageName;
15963
15964        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15965
15966        synchronized(mPackages) {
15967            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15968            if (renamedPackage != null) {
15969                // A package with the same name is already installed, though
15970                // it has been renamed to an older name.  The package we
15971                // are trying to install should be installed as an update to
15972                // the existing one, but that has not been requested, so bail.
15973                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15974                        + " without first uninstalling package running as "
15975                        + renamedPackage);
15976                return;
15977            }
15978            if (mPackages.containsKey(pkgName)) {
15979                // Don't allow installation over an existing package with the same name.
15980                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15981                        + " without first uninstalling.");
15982                return;
15983            }
15984        }
15985
15986        try {
15987            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
15988                    System.currentTimeMillis(), user);
15989
15990            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15991
15992            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15993                prepareAppDataAfterInstallLIF(newPackage);
15994
15995            } else {
15996                // Remove package from internal structures, but keep around any
15997                // data that might have already existed
15998                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15999                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16000            }
16001        } catch (PackageManagerException e) {
16002            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16003        }
16004
16005        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16006    }
16007
16008    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16009        // Can't rotate keys during boot or if sharedUser.
16010        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16011                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16012            return false;
16013        }
16014        // app is using upgradeKeySets; make sure all are valid
16015        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16016        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16017        for (int i = 0; i < upgradeKeySets.length; i++) {
16018            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16019                Slog.wtf(TAG, "Package "
16020                         + (oldPs.name != null ? oldPs.name : "<null>")
16021                         + " contains upgrade-key-set reference to unknown key-set: "
16022                         + upgradeKeySets[i]
16023                         + " reverting to signatures check.");
16024                return false;
16025            }
16026        }
16027        return true;
16028    }
16029
16030    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16031        // Upgrade keysets are being used.  Determine if new package has a superset of the
16032        // required keys.
16033        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16034        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16035        for (int i = 0; i < upgradeKeySets.length; i++) {
16036            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16037            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16038                return true;
16039            }
16040        }
16041        return false;
16042    }
16043
16044    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16045        try (DigestInputStream digestStream =
16046                new DigestInputStream(new FileInputStream(file), digest)) {
16047            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16048        }
16049    }
16050
16051    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16052            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16053            int installReason) {
16054        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16055
16056        final PackageParser.Package oldPackage;
16057        final PackageSetting ps;
16058        final String pkgName = pkg.packageName;
16059        final int[] allUsers;
16060        final int[] installedUsers;
16061
16062        synchronized(mPackages) {
16063            oldPackage = mPackages.get(pkgName);
16064            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16065
16066            // don't allow upgrade to target a release SDK from a pre-release SDK
16067            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16068                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16069            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16070                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16071            if (oldTargetsPreRelease
16072                    && !newTargetsPreRelease
16073                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16074                Slog.w(TAG, "Can't install package targeting released sdk");
16075                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16076                return;
16077            }
16078
16079            ps = mSettings.mPackages.get(pkgName);
16080
16081            // verify signatures are valid
16082            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16083                if (!checkUpgradeKeySetLP(ps, pkg)) {
16084                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16085                            "New package not signed by keys specified by upgrade-keysets: "
16086                                    + pkgName);
16087                    return;
16088                }
16089            } else {
16090                // default to original signature matching
16091                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16092                        != PackageManager.SIGNATURE_MATCH) {
16093                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16094                            "New package has a different signature: " + pkgName);
16095                    return;
16096                }
16097            }
16098
16099            // don't allow a system upgrade unless the upgrade hash matches
16100            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16101                byte[] digestBytes = null;
16102                try {
16103                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16104                    updateDigest(digest, new File(pkg.baseCodePath));
16105                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16106                        for (String path : pkg.splitCodePaths) {
16107                            updateDigest(digest, new File(path));
16108                        }
16109                    }
16110                    digestBytes = digest.digest();
16111                } catch (NoSuchAlgorithmException | IOException e) {
16112                    res.setError(INSTALL_FAILED_INVALID_APK,
16113                            "Could not compute hash: " + pkgName);
16114                    return;
16115                }
16116                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16117                    res.setError(INSTALL_FAILED_INVALID_APK,
16118                            "New package fails restrict-update check: " + pkgName);
16119                    return;
16120                }
16121                // retain upgrade restriction
16122                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16123            }
16124
16125            // Check for shared user id changes
16126            String invalidPackageName =
16127                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16128            if (invalidPackageName != null) {
16129                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16130                        "Package " + invalidPackageName + " tried to change user "
16131                                + oldPackage.mSharedUserId);
16132                return;
16133            }
16134
16135            // In case of rollback, remember per-user/profile install state
16136            allUsers = sUserManager.getUserIds();
16137            installedUsers = ps.queryInstalledUsers(allUsers, true);
16138
16139            // don't allow an upgrade from full to ephemeral
16140            if (isInstantApp) {
16141                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16142                    for (int currentUser : allUsers) {
16143                        if (!ps.getInstantApp(currentUser)) {
16144                            // can't downgrade from full to instant
16145                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16146                                    + " for user: " + currentUser);
16147                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16148                            return;
16149                        }
16150                    }
16151                } else if (!ps.getInstantApp(user.getIdentifier())) {
16152                    // can't downgrade from full to instant
16153                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16154                            + " for user: " + user.getIdentifier());
16155                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16156                    return;
16157                }
16158            }
16159        }
16160
16161        // Update what is removed
16162        res.removedInfo = new PackageRemovedInfo(this);
16163        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16164        res.removedInfo.removedPackage = oldPackage.packageName;
16165        res.removedInfo.installerPackageName = ps.installerPackageName;
16166        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16167        res.removedInfo.isUpdate = true;
16168        res.removedInfo.origUsers = installedUsers;
16169        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16170        for (int i = 0; i < installedUsers.length; i++) {
16171            final int userId = installedUsers[i];
16172            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16173        }
16174
16175        final int childCount = (oldPackage.childPackages != null)
16176                ? oldPackage.childPackages.size() : 0;
16177        for (int i = 0; i < childCount; i++) {
16178            boolean childPackageUpdated = false;
16179            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16180            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16181            if (res.addedChildPackages != null) {
16182                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16183                if (childRes != null) {
16184                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16185                    childRes.removedInfo.removedPackage = childPkg.packageName;
16186                    if (childPs != null) {
16187                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16188                    }
16189                    childRes.removedInfo.isUpdate = true;
16190                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16191                    childPackageUpdated = true;
16192                }
16193            }
16194            if (!childPackageUpdated) {
16195                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16196                childRemovedRes.removedPackage = childPkg.packageName;
16197                if (childPs != null) {
16198                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16199                }
16200                childRemovedRes.isUpdate = false;
16201                childRemovedRes.dataRemoved = true;
16202                synchronized (mPackages) {
16203                    if (childPs != null) {
16204                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16205                    }
16206                }
16207                if (res.removedInfo.removedChildPackages == null) {
16208                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16209                }
16210                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16211            }
16212        }
16213
16214        boolean sysPkg = (isSystemApp(oldPackage));
16215        if (sysPkg) {
16216            // Set the system/privileged flags as needed
16217            final boolean privileged =
16218                    (oldPackage.applicationInfo.privateFlags
16219                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16220            final int systemPolicyFlags = policyFlags
16221                    | PackageParser.PARSE_IS_SYSTEM
16222                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16223
16224            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16225                    user, allUsers, installerPackageName, res, installReason);
16226        } else {
16227            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16228                    user, allUsers, installerPackageName, res, installReason);
16229        }
16230    }
16231
16232    public List<String> getPreviousCodePaths(String packageName) {
16233        final PackageSetting ps = mSettings.mPackages.get(packageName);
16234        final List<String> result = new ArrayList<String>();
16235        if (ps != null && ps.oldCodePaths != null) {
16236            result.addAll(ps.oldCodePaths);
16237        }
16238        return result;
16239    }
16240
16241    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16242            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16243            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16244            int installReason) {
16245        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16246                + deletedPackage);
16247
16248        String pkgName = deletedPackage.packageName;
16249        boolean deletedPkg = true;
16250        boolean addedPkg = false;
16251        boolean updatedSettings = false;
16252        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16253        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16254                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16255
16256        final long origUpdateTime = (pkg.mExtras != null)
16257                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16258
16259        // First delete the existing package while retaining the data directory
16260        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16261                res.removedInfo, true, pkg)) {
16262            // If the existing package wasn't successfully deleted
16263            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16264            deletedPkg = false;
16265        } else {
16266            // Successfully deleted the old package; proceed with replace.
16267
16268            // If deleted package lived in a container, give users a chance to
16269            // relinquish resources before killing.
16270            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16271                if (DEBUG_INSTALL) {
16272                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16273                }
16274                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16275                final ArrayList<String> pkgList = new ArrayList<String>(1);
16276                pkgList.add(deletedPackage.applicationInfo.packageName);
16277                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16278            }
16279
16280            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16281                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16282            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16283
16284            try {
16285                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16286                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16287                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16288                        installReason);
16289
16290                // Update the in-memory copy of the previous code paths.
16291                PackageSetting ps = mSettings.mPackages.get(pkgName);
16292                if (!killApp) {
16293                    if (ps.oldCodePaths == null) {
16294                        ps.oldCodePaths = new ArraySet<>();
16295                    }
16296                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16297                    if (deletedPackage.splitCodePaths != null) {
16298                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16299                    }
16300                } else {
16301                    ps.oldCodePaths = null;
16302                }
16303                if (ps.childPackageNames != null) {
16304                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16305                        final String childPkgName = ps.childPackageNames.get(i);
16306                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16307                        childPs.oldCodePaths = ps.oldCodePaths;
16308                    }
16309                }
16310                // set instant app status, but, only if it's explicitly specified
16311                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16312                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16313                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16314                prepareAppDataAfterInstallLIF(newPackage);
16315                addedPkg = true;
16316                mDexManager.notifyPackageUpdated(newPackage.packageName,
16317                        newPackage.baseCodePath, newPackage.splitCodePaths);
16318            } catch (PackageManagerException e) {
16319                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16320            }
16321        }
16322
16323        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16324            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16325
16326            // Revert all internal state mutations and added folders for the failed install
16327            if (addedPkg) {
16328                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16329                        res.removedInfo, true, null);
16330            }
16331
16332            // Restore the old package
16333            if (deletedPkg) {
16334                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16335                File restoreFile = new File(deletedPackage.codePath);
16336                // Parse old package
16337                boolean oldExternal = isExternal(deletedPackage);
16338                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16339                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16340                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16341                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16342                try {
16343                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16344                            null);
16345                } catch (PackageManagerException e) {
16346                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16347                            + e.getMessage());
16348                    return;
16349                }
16350
16351                synchronized (mPackages) {
16352                    // Ensure the installer package name up to date
16353                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16354
16355                    // Update permissions for restored package
16356                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16357
16358                    mSettings.writeLPr();
16359                }
16360
16361                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16362            }
16363        } else {
16364            synchronized (mPackages) {
16365                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16366                if (ps != null) {
16367                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16368                    if (res.removedInfo.removedChildPackages != null) {
16369                        final int childCount = res.removedInfo.removedChildPackages.size();
16370                        // Iterate in reverse as we may modify the collection
16371                        for (int i = childCount - 1; i >= 0; i--) {
16372                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16373                            if (res.addedChildPackages.containsKey(childPackageName)) {
16374                                res.removedInfo.removedChildPackages.removeAt(i);
16375                            } else {
16376                                PackageRemovedInfo childInfo = res.removedInfo
16377                                        .removedChildPackages.valueAt(i);
16378                                childInfo.removedForAllUsers = mPackages.get(
16379                                        childInfo.removedPackage) == null;
16380                            }
16381                        }
16382                    }
16383                }
16384            }
16385        }
16386    }
16387
16388    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16389            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16390            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16391            int installReason) {
16392        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16393                + ", old=" + deletedPackage);
16394
16395        final boolean disabledSystem;
16396
16397        // Remove existing system package
16398        removePackageLI(deletedPackage, true);
16399
16400        synchronized (mPackages) {
16401            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16402        }
16403        if (!disabledSystem) {
16404            // We didn't need to disable the .apk as a current system package,
16405            // which means we are replacing another update that is already
16406            // installed.  We need to make sure to delete the older one's .apk.
16407            res.removedInfo.args = createInstallArgsForExisting(0,
16408                    deletedPackage.applicationInfo.getCodePath(),
16409                    deletedPackage.applicationInfo.getResourcePath(),
16410                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16411        } else {
16412            res.removedInfo.args = null;
16413        }
16414
16415        // Successfully disabled the old package. Now proceed with re-installation
16416        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16417                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16418        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16419
16420        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16421        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16422                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16423
16424        PackageParser.Package newPackage = null;
16425        try {
16426            // Add the package to the internal data structures
16427            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16428
16429            // Set the update and install times
16430            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16431            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16432                    System.currentTimeMillis());
16433
16434            // Update the package dynamic state if succeeded
16435            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16436                // Now that the install succeeded make sure we remove data
16437                // directories for any child package the update removed.
16438                final int deletedChildCount = (deletedPackage.childPackages != null)
16439                        ? deletedPackage.childPackages.size() : 0;
16440                final int newChildCount = (newPackage.childPackages != null)
16441                        ? newPackage.childPackages.size() : 0;
16442                for (int i = 0; i < deletedChildCount; i++) {
16443                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16444                    boolean childPackageDeleted = true;
16445                    for (int j = 0; j < newChildCount; j++) {
16446                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16447                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16448                            childPackageDeleted = false;
16449                            break;
16450                        }
16451                    }
16452                    if (childPackageDeleted) {
16453                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16454                                deletedChildPkg.packageName);
16455                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16456                            PackageRemovedInfo removedChildRes = res.removedInfo
16457                                    .removedChildPackages.get(deletedChildPkg.packageName);
16458                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16459                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16460                        }
16461                    }
16462                }
16463
16464                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16465                        installReason);
16466                prepareAppDataAfterInstallLIF(newPackage);
16467
16468                mDexManager.notifyPackageUpdated(newPackage.packageName,
16469                            newPackage.baseCodePath, newPackage.splitCodePaths);
16470            }
16471        } catch (PackageManagerException e) {
16472            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16473            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16474        }
16475
16476        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16477            // Re installation failed. Restore old information
16478            // Remove new pkg information
16479            if (newPackage != null) {
16480                removeInstalledPackageLI(newPackage, true);
16481            }
16482            // Add back the old system package
16483            try {
16484                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16485            } catch (PackageManagerException e) {
16486                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16487            }
16488
16489            synchronized (mPackages) {
16490                if (disabledSystem) {
16491                    enableSystemPackageLPw(deletedPackage);
16492                }
16493
16494                // Ensure the installer package name up to date
16495                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16496
16497                // Update permissions for restored package
16498                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16499
16500                mSettings.writeLPr();
16501            }
16502
16503            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16504                    + " after failed upgrade");
16505        }
16506    }
16507
16508    /**
16509     * Checks whether the parent or any of the child packages have a change shared
16510     * user. For a package to be a valid update the shred users of the parent and
16511     * the children should match. We may later support changing child shared users.
16512     * @param oldPkg The updated package.
16513     * @param newPkg The update package.
16514     * @return The shared user that change between the versions.
16515     */
16516    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16517            PackageParser.Package newPkg) {
16518        // Check parent shared user
16519        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16520            return newPkg.packageName;
16521        }
16522        // Check child shared users
16523        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16524        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16525        for (int i = 0; i < newChildCount; i++) {
16526            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16527            // If this child was present, did it have the same shared user?
16528            for (int j = 0; j < oldChildCount; j++) {
16529                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16530                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16531                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16532                    return newChildPkg.packageName;
16533                }
16534            }
16535        }
16536        return null;
16537    }
16538
16539    private void removeNativeBinariesLI(PackageSetting ps) {
16540        // Remove the lib path for the parent package
16541        if (ps != null) {
16542            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16543            // Remove the lib path for the child packages
16544            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16545            for (int i = 0; i < childCount; i++) {
16546                PackageSetting childPs = null;
16547                synchronized (mPackages) {
16548                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16549                }
16550                if (childPs != null) {
16551                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16552                            .legacyNativeLibraryPathString);
16553                }
16554            }
16555        }
16556    }
16557
16558    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16559        // Enable the parent package
16560        mSettings.enableSystemPackageLPw(pkg.packageName);
16561        // Enable the child packages
16562        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16563        for (int i = 0; i < childCount; i++) {
16564            PackageParser.Package childPkg = pkg.childPackages.get(i);
16565            mSettings.enableSystemPackageLPw(childPkg.packageName);
16566        }
16567    }
16568
16569    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16570            PackageParser.Package newPkg) {
16571        // Disable the parent package (parent always replaced)
16572        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16573        // Disable the child packages
16574        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16575        for (int i = 0; i < childCount; i++) {
16576            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16577            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16578            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16579        }
16580        return disabled;
16581    }
16582
16583    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16584            String installerPackageName) {
16585        // Enable the parent package
16586        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16587        // Enable the child packages
16588        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16589        for (int i = 0; i < childCount; i++) {
16590            PackageParser.Package childPkg = pkg.childPackages.get(i);
16591            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16592        }
16593    }
16594
16595    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16596        // Collect all used permissions in the UID
16597        ArraySet<String> usedPermissions = new ArraySet<>();
16598        final int packageCount = su.packages.size();
16599        for (int i = 0; i < packageCount; i++) {
16600            PackageSetting ps = su.packages.valueAt(i);
16601            if (ps.pkg == null) {
16602                continue;
16603            }
16604            final int requestedPermCount = ps.pkg.requestedPermissions.size();
16605            for (int j = 0; j < requestedPermCount; j++) {
16606                String permission = ps.pkg.requestedPermissions.get(j);
16607                BasePermission bp = mSettings.mPermissions.get(permission);
16608                if (bp != null) {
16609                    usedPermissions.add(permission);
16610                }
16611            }
16612        }
16613
16614        PermissionsState permissionsState = su.getPermissionsState();
16615        // Prune install permissions
16616        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16617        final int installPermCount = installPermStates.size();
16618        for (int i = installPermCount - 1; i >= 0;  i--) {
16619            PermissionState permissionState = installPermStates.get(i);
16620            if (!usedPermissions.contains(permissionState.getName())) {
16621                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16622                if (bp != null) {
16623                    permissionsState.revokeInstallPermission(bp);
16624                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16625                            PackageManager.MASK_PERMISSION_FLAGS, 0);
16626                }
16627            }
16628        }
16629
16630        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16631
16632        // Prune runtime permissions
16633        for (int userId : allUserIds) {
16634            List<PermissionState> runtimePermStates = permissionsState
16635                    .getRuntimePermissionStates(userId);
16636            final int runtimePermCount = runtimePermStates.size();
16637            for (int i = runtimePermCount - 1; i >= 0; i--) {
16638                PermissionState permissionState = runtimePermStates.get(i);
16639                if (!usedPermissions.contains(permissionState.getName())) {
16640                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16641                    if (bp != null) {
16642                        permissionsState.revokeRuntimePermission(bp, userId);
16643                        permissionsState.updatePermissionFlags(bp, userId,
16644                                PackageManager.MASK_PERMISSION_FLAGS, 0);
16645                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
16646                                runtimePermissionChangedUserIds, userId);
16647                    }
16648                }
16649            }
16650        }
16651
16652        return runtimePermissionChangedUserIds;
16653    }
16654
16655    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16656            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16657        // Update the parent package setting
16658        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16659                res, user, installReason);
16660        // Update the child packages setting
16661        final int childCount = (newPackage.childPackages != null)
16662                ? newPackage.childPackages.size() : 0;
16663        for (int i = 0; i < childCount; i++) {
16664            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16665            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16666            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16667                    childRes.origUsers, childRes, user, installReason);
16668        }
16669    }
16670
16671    private void updateSettingsInternalLI(PackageParser.Package newPackage,
16672            String installerPackageName, int[] allUsers, int[] installedForUsers,
16673            PackageInstalledInfo res, UserHandle user, int installReason) {
16674        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16675
16676        String pkgName = newPackage.packageName;
16677        synchronized (mPackages) {
16678            //write settings. the installStatus will be incomplete at this stage.
16679            //note that the new package setting would have already been
16680            //added to mPackages. It hasn't been persisted yet.
16681            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16682            // TODO: Remove this write? It's also written at the end of this method
16683            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16684            mSettings.writeLPr();
16685            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16686        }
16687
16688        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
16689        synchronized (mPackages) {
16690            updatePermissionsLPw(newPackage.packageName, newPackage,
16691                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
16692                            ? UPDATE_PERMISSIONS_ALL : 0));
16693            // For system-bundled packages, we assume that installing an upgraded version
16694            // of the package implies that the user actually wants to run that new code,
16695            // so we enable the package.
16696            PackageSetting ps = mSettings.mPackages.get(pkgName);
16697            final int userId = user.getIdentifier();
16698            if (ps != null) {
16699                if (isSystemApp(newPackage)) {
16700                    if (DEBUG_INSTALL) {
16701                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16702                    }
16703                    // Enable system package for requested users
16704                    if (res.origUsers != null) {
16705                        for (int origUserId : res.origUsers) {
16706                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16707                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16708                                        origUserId, installerPackageName);
16709                            }
16710                        }
16711                    }
16712                    // Also convey the prior install/uninstall state
16713                    if (allUsers != null && installedForUsers != null) {
16714                        for (int currentUserId : allUsers) {
16715                            final boolean installed = ArrayUtils.contains(
16716                                    installedForUsers, currentUserId);
16717                            if (DEBUG_INSTALL) {
16718                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16719                            }
16720                            ps.setInstalled(installed, currentUserId);
16721                        }
16722                        // these install state changes will be persisted in the
16723                        // upcoming call to mSettings.writeLPr().
16724                    }
16725                }
16726                // It's implied that when a user requests installation, they want the app to be
16727                // installed and enabled.
16728                if (userId != UserHandle.USER_ALL) {
16729                    ps.setInstalled(true, userId);
16730                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16731                }
16732
16733                // When replacing an existing package, preserve the original install reason for all
16734                // users that had the package installed before.
16735                final Set<Integer> previousUserIds = new ArraySet<>();
16736                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16737                    final int installReasonCount = res.removedInfo.installReasons.size();
16738                    for (int i = 0; i < installReasonCount; i++) {
16739                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16740                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16741                        ps.setInstallReason(previousInstallReason, previousUserId);
16742                        previousUserIds.add(previousUserId);
16743                    }
16744                }
16745
16746                // Set install reason for users that are having the package newly installed.
16747                if (userId == UserHandle.USER_ALL) {
16748                    for (int currentUserId : sUserManager.getUserIds()) {
16749                        if (!previousUserIds.contains(currentUserId)) {
16750                            ps.setInstallReason(installReason, currentUserId);
16751                        }
16752                    }
16753                } else if (!previousUserIds.contains(userId)) {
16754                    ps.setInstallReason(installReason, userId);
16755                }
16756                mSettings.writeKernelMappingLPr(ps);
16757            }
16758            res.name = pkgName;
16759            res.uid = newPackage.applicationInfo.uid;
16760            res.pkg = newPackage;
16761            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16762            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16763            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16764            //to update install status
16765            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16766            mSettings.writeLPr();
16767            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16768        }
16769
16770        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16771    }
16772
16773    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16774        try {
16775            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16776            installPackageLI(args, res);
16777        } finally {
16778            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16779        }
16780    }
16781
16782    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16783        final int installFlags = args.installFlags;
16784        final String installerPackageName = args.installerPackageName;
16785        final String volumeUuid = args.volumeUuid;
16786        final File tmpPackageFile = new File(args.getCodePath());
16787        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16788        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16789                || (args.volumeUuid != null));
16790        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16791        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16792        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16793        boolean replace = false;
16794        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16795        if (args.move != null) {
16796            // moving a complete application; perform an initial scan on the new install location
16797            scanFlags |= SCAN_INITIAL;
16798        }
16799        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16800            scanFlags |= SCAN_DONT_KILL_APP;
16801        }
16802        if (instantApp) {
16803            scanFlags |= SCAN_AS_INSTANT_APP;
16804        }
16805        if (fullApp) {
16806            scanFlags |= SCAN_AS_FULL_APP;
16807        }
16808
16809        // Result object to be returned
16810        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16811
16812        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16813
16814        // Sanity check
16815        if (instantApp && (forwardLocked || onExternal)) {
16816            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16817                    + " external=" + onExternal);
16818            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16819            return;
16820        }
16821
16822        // Retrieve PackageSettings and parse package
16823        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16824                | PackageParser.PARSE_ENFORCE_CODE
16825                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16826                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16827                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16828                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16829        PackageParser pp = new PackageParser();
16830        pp.setSeparateProcesses(mSeparateProcesses);
16831        pp.setDisplayMetrics(mMetrics);
16832        pp.setCallback(mPackageParserCallback);
16833
16834        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16835        final PackageParser.Package pkg;
16836        try {
16837            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16838        } catch (PackageParserException e) {
16839            res.setError("Failed parse during installPackageLI", e);
16840            return;
16841        } finally {
16842            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16843        }
16844
16845        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16846        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16847            Slog.w(TAG, "Instant app package " + pkg.packageName
16848                    + " does not target O, this will be a fatal error.");
16849            // STOPSHIP: Make this a fatal error
16850            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
16851        }
16852        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16853            Slog.w(TAG, "Instant app package " + pkg.packageName
16854                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
16855            // STOPSHIP: Make this a fatal error
16856            pkg.applicationInfo.targetSandboxVersion = 2;
16857        }
16858
16859        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16860            // Static shared libraries have synthetic package names
16861            renameStaticSharedLibraryPackage(pkg);
16862
16863            // No static shared libs on external storage
16864            if (onExternal) {
16865                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16866                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16867                        "Packages declaring static-shared libs cannot be updated");
16868                return;
16869            }
16870        }
16871
16872        // If we are installing a clustered package add results for the children
16873        if (pkg.childPackages != null) {
16874            synchronized (mPackages) {
16875                final int childCount = pkg.childPackages.size();
16876                for (int i = 0; i < childCount; i++) {
16877                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16878                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16879                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16880                    childRes.pkg = childPkg;
16881                    childRes.name = childPkg.packageName;
16882                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16883                    if (childPs != null) {
16884                        childRes.origUsers = childPs.queryInstalledUsers(
16885                                sUserManager.getUserIds(), true);
16886                    }
16887                    if ((mPackages.containsKey(childPkg.packageName))) {
16888                        childRes.removedInfo = new PackageRemovedInfo(this);
16889                        childRes.removedInfo.removedPackage = childPkg.packageName;
16890                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16891                    }
16892                    if (res.addedChildPackages == null) {
16893                        res.addedChildPackages = new ArrayMap<>();
16894                    }
16895                    res.addedChildPackages.put(childPkg.packageName, childRes);
16896                }
16897            }
16898        }
16899
16900        // If package doesn't declare API override, mark that we have an install
16901        // time CPU ABI override.
16902        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16903            pkg.cpuAbiOverride = args.abiOverride;
16904        }
16905
16906        String pkgName = res.name = pkg.packageName;
16907        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16908            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16909                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16910                return;
16911            }
16912        }
16913
16914        try {
16915            // either use what we've been given or parse directly from the APK
16916            if (args.certificates != null) {
16917                try {
16918                    PackageParser.populateCertificates(pkg, args.certificates);
16919                } catch (PackageParserException e) {
16920                    // there was something wrong with the certificates we were given;
16921                    // try to pull them from the APK
16922                    PackageParser.collectCertificates(pkg, parseFlags);
16923                }
16924            } else {
16925                PackageParser.collectCertificates(pkg, parseFlags);
16926            }
16927        } catch (PackageParserException e) {
16928            res.setError("Failed collect during installPackageLI", e);
16929            return;
16930        }
16931
16932        // Get rid of all references to package scan path via parser.
16933        pp = null;
16934        String oldCodePath = null;
16935        boolean systemApp = false;
16936        synchronized (mPackages) {
16937            // Check if installing already existing package
16938            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16939                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16940                if (pkg.mOriginalPackages != null
16941                        && pkg.mOriginalPackages.contains(oldName)
16942                        && mPackages.containsKey(oldName)) {
16943                    // This package is derived from an original package,
16944                    // and this device has been updating from that original
16945                    // name.  We must continue using the original name, so
16946                    // rename the new package here.
16947                    pkg.setPackageName(oldName);
16948                    pkgName = pkg.packageName;
16949                    replace = true;
16950                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16951                            + oldName + " pkgName=" + pkgName);
16952                } else if (mPackages.containsKey(pkgName)) {
16953                    // This package, under its official name, already exists
16954                    // on the device; we should replace it.
16955                    replace = true;
16956                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16957                }
16958
16959                // Child packages are installed through the parent package
16960                if (pkg.parentPackage != null) {
16961                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16962                            "Package " + pkg.packageName + " is child of package "
16963                                    + pkg.parentPackage.parentPackage + ". Child packages "
16964                                    + "can be updated only through the parent package.");
16965                    return;
16966                }
16967
16968                if (replace) {
16969                    // Prevent apps opting out from runtime permissions
16970                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16971                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16972                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16973                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16974                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16975                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16976                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16977                                        + " doesn't support runtime permissions but the old"
16978                                        + " target SDK " + oldTargetSdk + " does.");
16979                        return;
16980                    }
16981                    // Prevent apps from downgrading their targetSandbox.
16982                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16983                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16984                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16985                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16986                                "Package " + pkg.packageName + " new target sandbox "
16987                                + newTargetSandbox + " is incompatible with the previous value of"
16988                                + oldTargetSandbox + ".");
16989                        return;
16990                    }
16991
16992                    // Prevent installing of child packages
16993                    if (oldPackage.parentPackage != null) {
16994                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16995                                "Package " + pkg.packageName + " is child of package "
16996                                        + oldPackage.parentPackage + ". Child packages "
16997                                        + "can be updated only through the parent package.");
16998                        return;
16999                    }
17000                }
17001            }
17002
17003            PackageSetting ps = mSettings.mPackages.get(pkgName);
17004            if (ps != null) {
17005                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17006
17007                // Static shared libs have same package with different versions where
17008                // we internally use a synthetic package name to allow multiple versions
17009                // of the same package, therefore we need to compare signatures against
17010                // the package setting for the latest library version.
17011                PackageSetting signatureCheckPs = ps;
17012                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17013                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17014                    if (libraryEntry != null) {
17015                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17016                    }
17017                }
17018
17019                // Quick sanity check that we're signed correctly if updating;
17020                // we'll check this again later when scanning, but we want to
17021                // bail early here before tripping over redefined permissions.
17022                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17023                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17024                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17025                                + pkg.packageName + " upgrade keys do not match the "
17026                                + "previously installed version");
17027                        return;
17028                    }
17029                } else {
17030                    try {
17031                        verifySignaturesLP(signatureCheckPs, pkg);
17032                    } catch (PackageManagerException e) {
17033                        res.setError(e.error, e.getMessage());
17034                        return;
17035                    }
17036                }
17037
17038                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17039                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17040                    systemApp = (ps.pkg.applicationInfo.flags &
17041                            ApplicationInfo.FLAG_SYSTEM) != 0;
17042                }
17043                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17044            }
17045
17046            int N = pkg.permissions.size();
17047            for (int i = N-1; i >= 0; i--) {
17048                PackageParser.Permission perm = pkg.permissions.get(i);
17049                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17050
17051                // Don't allow anyone but the platform to define ephemeral permissions.
17052                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17053                        && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17054                    Slog.w(TAG, "Package " + pkg.packageName
17055                            + " attempting to delcare ephemeral permission "
17056                            + perm.info.name + "; Removing ephemeral.");
17057                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17058                }
17059                // Check whether the newly-scanned package wants to define an already-defined perm
17060                if (bp != null) {
17061                    // If the defining package is signed with our cert, it's okay.  This
17062                    // also includes the "updating the same package" case, of course.
17063                    // "updating same package" could also involve key-rotation.
17064                    final boolean sigsOk;
17065                    if (bp.sourcePackage.equals(pkg.packageName)
17066                            && (bp.packageSetting instanceof PackageSetting)
17067                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17068                                    scanFlags))) {
17069                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17070                    } else {
17071                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17072                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17073                    }
17074                    if (!sigsOk) {
17075                        // If the owning package is the system itself, we log but allow
17076                        // install to proceed; we fail the install on all other permission
17077                        // redefinitions.
17078                        if (!bp.sourcePackage.equals("android")) {
17079                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17080                                    + pkg.packageName + " attempting to redeclare permission "
17081                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17082                            res.origPermission = perm.info.name;
17083                            res.origPackage = bp.sourcePackage;
17084                            return;
17085                        } else {
17086                            Slog.w(TAG, "Package " + pkg.packageName
17087                                    + " attempting to redeclare system permission "
17088                                    + perm.info.name + "; ignoring new declaration");
17089                            pkg.permissions.remove(i);
17090                        }
17091                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17092                        // Prevent apps to change protection level to dangerous from any other
17093                        // type as this would allow a privilege escalation where an app adds a
17094                        // normal/signature permission in other app's group and later redefines
17095                        // it as dangerous leading to the group auto-grant.
17096                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17097                                == PermissionInfo.PROTECTION_DANGEROUS) {
17098                            if (bp != null && !bp.isRuntime()) {
17099                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17100                                        + "non-runtime permission " + perm.info.name
17101                                        + " to runtime; keeping old protection level");
17102                                perm.info.protectionLevel = bp.protectionLevel;
17103                            }
17104                        }
17105                    }
17106                }
17107            }
17108        }
17109
17110        if (systemApp) {
17111            if (onExternal) {
17112                // Abort update; system app can't be replaced with app on sdcard
17113                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17114                        "Cannot install updates to system apps on sdcard");
17115                return;
17116            } else if (instantApp) {
17117                // Abort update; system app can't be replaced with an instant app
17118                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17119                        "Cannot update a system app with an instant app");
17120                return;
17121            }
17122        }
17123
17124        if (args.move != null) {
17125            // We did an in-place move, so dex is ready to roll
17126            scanFlags |= SCAN_NO_DEX;
17127            scanFlags |= SCAN_MOVE;
17128
17129            synchronized (mPackages) {
17130                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17131                if (ps == null) {
17132                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17133                            "Missing settings for moved package " + pkgName);
17134                }
17135
17136                // We moved the entire application as-is, so bring over the
17137                // previously derived ABI information.
17138                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17139                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17140            }
17141
17142        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17143            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17144            scanFlags |= SCAN_NO_DEX;
17145
17146            try {
17147                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17148                    args.abiOverride : pkg.cpuAbiOverride);
17149                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17150                        true /*extractLibs*/, mAppLib32InstallDir);
17151            } catch (PackageManagerException pme) {
17152                Slog.e(TAG, "Error deriving application ABI", pme);
17153                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17154                return;
17155            }
17156
17157            // Shared libraries for the package need to be updated.
17158            synchronized (mPackages) {
17159                try {
17160                    updateSharedLibrariesLPr(pkg, null);
17161                } catch (PackageManagerException e) {
17162                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17163                }
17164            }
17165
17166            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17167            // Do not run PackageDexOptimizer through the local performDexOpt
17168            // method because `pkg` may not be in `mPackages` yet.
17169            //
17170            // Also, don't fail application installs if the dexopt step fails.
17171            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17172                    null /* instructionSets */, false /* checkProfiles */,
17173                    getCompilerFilterForReason(REASON_INSTALL),
17174                    getOrCreateCompilerPackageStats(pkg),
17175                    mDexManager.isUsedByOtherApps(pkg.packageName));
17176            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17177
17178            // Notify BackgroundDexOptService that the package has been changed.
17179            // If this is an update of a package which used to fail to compile,
17180            // BDOS will remove it from its blacklist.
17181            // TODO: Layering violation
17182            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17183        }
17184
17185        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17186            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17187            return;
17188        }
17189
17190        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17191
17192        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17193                "installPackageLI")) {
17194            if (replace) {
17195                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17196                    // Static libs have a synthetic package name containing the version
17197                    // and cannot be updated as an update would get a new package name,
17198                    // unless this is the exact same version code which is useful for
17199                    // development.
17200                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17201                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17202                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17203                                + "static-shared libs cannot be updated");
17204                        return;
17205                    }
17206                }
17207                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17208                        installerPackageName, res, args.installReason);
17209            } else {
17210                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17211                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17212            }
17213        }
17214
17215        synchronized (mPackages) {
17216            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17217            if (ps != null) {
17218                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17219                ps.setUpdateAvailable(false /*updateAvailable*/);
17220            }
17221
17222            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17223            for (int i = 0; i < childCount; i++) {
17224                PackageParser.Package childPkg = pkg.childPackages.get(i);
17225                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17226                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17227                if (childPs != null) {
17228                    childRes.newUsers = childPs.queryInstalledUsers(
17229                            sUserManager.getUserIds(), true);
17230                }
17231            }
17232
17233            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17234                updateSequenceNumberLP(pkgName, res.newUsers);
17235                updateInstantAppInstallerLocked(pkgName);
17236            }
17237        }
17238    }
17239
17240    private void startIntentFilterVerifications(int userId, boolean replacing,
17241            PackageParser.Package pkg) {
17242        if (mIntentFilterVerifierComponent == null) {
17243            Slog.w(TAG, "No IntentFilter verification will not be done as "
17244                    + "there is no IntentFilterVerifier available!");
17245            return;
17246        }
17247
17248        final int verifierUid = getPackageUid(
17249                mIntentFilterVerifierComponent.getPackageName(),
17250                MATCH_DEBUG_TRIAGED_MISSING,
17251                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17252
17253        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17254        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17255        mHandler.sendMessage(msg);
17256
17257        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17258        for (int i = 0; i < childCount; i++) {
17259            PackageParser.Package childPkg = pkg.childPackages.get(i);
17260            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17261            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17262            mHandler.sendMessage(msg);
17263        }
17264    }
17265
17266    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17267            PackageParser.Package pkg) {
17268        int size = pkg.activities.size();
17269        if (size == 0) {
17270            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17271                    "No activity, so no need to verify any IntentFilter!");
17272            return;
17273        }
17274
17275        final boolean hasDomainURLs = hasDomainURLs(pkg);
17276        if (!hasDomainURLs) {
17277            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17278                    "No domain URLs, so no need to verify any IntentFilter!");
17279            return;
17280        }
17281
17282        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17283                + " if any IntentFilter from the " + size
17284                + " Activities needs verification ...");
17285
17286        int count = 0;
17287        final String packageName = pkg.packageName;
17288
17289        synchronized (mPackages) {
17290            // If this is a new install and we see that we've already run verification for this
17291            // package, we have nothing to do: it means the state was restored from backup.
17292            if (!replacing) {
17293                IntentFilterVerificationInfo ivi =
17294                        mSettings.getIntentFilterVerificationLPr(packageName);
17295                if (ivi != null) {
17296                    if (DEBUG_DOMAIN_VERIFICATION) {
17297                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17298                                + ivi.getStatusString());
17299                    }
17300                    return;
17301                }
17302            }
17303
17304            // If any filters need to be verified, then all need to be.
17305            boolean needToVerify = false;
17306            for (PackageParser.Activity a : pkg.activities) {
17307                for (ActivityIntentInfo filter : a.intents) {
17308                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17309                        if (DEBUG_DOMAIN_VERIFICATION) {
17310                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17311                        }
17312                        needToVerify = true;
17313                        break;
17314                    }
17315                }
17316            }
17317
17318            if (needToVerify) {
17319                final int verificationId = mIntentFilterVerificationToken++;
17320                for (PackageParser.Activity a : pkg.activities) {
17321                    for (ActivityIntentInfo filter : a.intents) {
17322                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17323                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17324                                    "Verification needed for IntentFilter:" + filter.toString());
17325                            mIntentFilterVerifier.addOneIntentFilterVerification(
17326                                    verifierUid, userId, verificationId, filter, packageName);
17327                            count++;
17328                        }
17329                    }
17330                }
17331            }
17332        }
17333
17334        if (count > 0) {
17335            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17336                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17337                    +  " for userId:" + userId);
17338            mIntentFilterVerifier.startVerifications(userId);
17339        } else {
17340            if (DEBUG_DOMAIN_VERIFICATION) {
17341                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17342            }
17343        }
17344    }
17345
17346    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17347        final ComponentName cn  = filter.activity.getComponentName();
17348        final String packageName = cn.getPackageName();
17349
17350        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17351                packageName);
17352        if (ivi == null) {
17353            return true;
17354        }
17355        int status = ivi.getStatus();
17356        switch (status) {
17357            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17358            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17359                return true;
17360
17361            default:
17362                // Nothing to do
17363                return false;
17364        }
17365    }
17366
17367    private static boolean isMultiArch(ApplicationInfo info) {
17368        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17369    }
17370
17371    private static boolean isExternal(PackageParser.Package pkg) {
17372        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17373    }
17374
17375    private static boolean isExternal(PackageSetting ps) {
17376        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17377    }
17378
17379    private static boolean isSystemApp(PackageParser.Package pkg) {
17380        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17381    }
17382
17383    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17384        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17385    }
17386
17387    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17388        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17389    }
17390
17391    private static boolean isSystemApp(PackageSetting ps) {
17392        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17393    }
17394
17395    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17396        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17397    }
17398
17399    private int packageFlagsToInstallFlags(PackageSetting ps) {
17400        int installFlags = 0;
17401        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17402            // This existing package was an external ASEC install when we have
17403            // the external flag without a UUID
17404            installFlags |= PackageManager.INSTALL_EXTERNAL;
17405        }
17406        if (ps.isForwardLocked()) {
17407            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17408        }
17409        return installFlags;
17410    }
17411
17412    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17413        if (isExternal(pkg)) {
17414            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17415                return StorageManager.UUID_PRIMARY_PHYSICAL;
17416            } else {
17417                return pkg.volumeUuid;
17418            }
17419        } else {
17420            return StorageManager.UUID_PRIVATE_INTERNAL;
17421        }
17422    }
17423
17424    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17425        if (isExternal(pkg)) {
17426            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17427                return mSettings.getExternalVersion();
17428            } else {
17429                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17430            }
17431        } else {
17432            return mSettings.getInternalVersion();
17433        }
17434    }
17435
17436    private void deleteTempPackageFiles() {
17437        final FilenameFilter filter = new FilenameFilter() {
17438            public boolean accept(File dir, String name) {
17439                return name.startsWith("vmdl") && name.endsWith(".tmp");
17440            }
17441        };
17442        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17443            file.delete();
17444        }
17445    }
17446
17447    @Override
17448    public void deletePackageAsUser(String packageName, int versionCode,
17449            IPackageDeleteObserver observer, int userId, int flags) {
17450        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17451                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17452    }
17453
17454    @Override
17455    public void deletePackageVersioned(VersionedPackage versionedPackage,
17456            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17457        mContext.enforceCallingOrSelfPermission(
17458                android.Manifest.permission.DELETE_PACKAGES, null);
17459        Preconditions.checkNotNull(versionedPackage);
17460        Preconditions.checkNotNull(observer);
17461        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17462                PackageManager.VERSION_CODE_HIGHEST,
17463                Integer.MAX_VALUE, "versionCode must be >= -1");
17464
17465        final String packageName = versionedPackage.getPackageName();
17466        // TODO: We will change version code to long, so in the new API it is long
17467        final int versionCode = (int) versionedPackage.getVersionCode();
17468        final String internalPackageName;
17469        synchronized (mPackages) {
17470            // Normalize package name to handle renamed packages and static libs
17471            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17472                    // TODO: We will change version code to long, so in the new API it is long
17473                    (int) versionedPackage.getVersionCode());
17474        }
17475
17476        final int uid = Binder.getCallingUid();
17477        if (!isOrphaned(internalPackageName)
17478                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17479            try {
17480                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17481                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17482                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17483                observer.onUserActionRequired(intent);
17484            } catch (RemoteException re) {
17485            }
17486            return;
17487        }
17488        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17489        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17490        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17491            mContext.enforceCallingOrSelfPermission(
17492                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17493                    "deletePackage for user " + userId);
17494        }
17495
17496        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17497            try {
17498                observer.onPackageDeleted(packageName,
17499                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17500            } catch (RemoteException re) {
17501            }
17502            return;
17503        }
17504
17505        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17506            try {
17507                observer.onPackageDeleted(packageName,
17508                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17509            } catch (RemoteException re) {
17510            }
17511            return;
17512        }
17513
17514        if (DEBUG_REMOVE) {
17515            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17516                    + " deleteAllUsers: " + deleteAllUsers + " version="
17517                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17518                    ? "VERSION_CODE_HIGHEST" : versionCode));
17519        }
17520        // Queue up an async operation since the package deletion may take a little while.
17521        mHandler.post(new Runnable() {
17522            public void run() {
17523                mHandler.removeCallbacks(this);
17524                int returnCode;
17525                if (!deleteAllUsers) {
17526                    returnCode = deletePackageX(internalPackageName, versionCode,
17527                            userId, deleteFlags);
17528                } else {
17529                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
17530                            internalPackageName, users);
17531                    // If nobody is blocking uninstall, proceed with delete for all users
17532                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17533                        returnCode = deletePackageX(internalPackageName, versionCode,
17534                                userId, deleteFlags);
17535                    } else {
17536                        // Otherwise uninstall individually for users with blockUninstalls=false
17537                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17538                        for (int userId : users) {
17539                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17540                                returnCode = deletePackageX(internalPackageName, versionCode,
17541                                        userId, userFlags);
17542                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17543                                    Slog.w(TAG, "Package delete failed for user " + userId
17544                                            + ", returnCode " + returnCode);
17545                                }
17546                            }
17547                        }
17548                        // The app has only been marked uninstalled for certain users.
17549                        // We still need to report that delete was blocked
17550                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17551                    }
17552                }
17553                try {
17554                    observer.onPackageDeleted(packageName, returnCode, null);
17555                } catch (RemoteException e) {
17556                    Log.i(TAG, "Observer no longer exists.");
17557                } //end catch
17558            } //end run
17559        });
17560    }
17561
17562    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17563        if (pkg.staticSharedLibName != null) {
17564            return pkg.manifestPackageName;
17565        }
17566        return pkg.packageName;
17567    }
17568
17569    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17570        // Handle renamed packages
17571        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17572        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17573
17574        // Is this a static library?
17575        SparseArray<SharedLibraryEntry> versionedLib =
17576                mStaticLibsByDeclaringPackage.get(packageName);
17577        if (versionedLib == null || versionedLib.size() <= 0) {
17578            return packageName;
17579        }
17580
17581        // Figure out which lib versions the caller can see
17582        SparseIntArray versionsCallerCanSee = null;
17583        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17584        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17585                && callingAppId != Process.ROOT_UID) {
17586            versionsCallerCanSee = new SparseIntArray();
17587            String libName = versionedLib.valueAt(0).info.getName();
17588            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17589            if (uidPackages != null) {
17590                for (String uidPackage : uidPackages) {
17591                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17592                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17593                    if (libIdx >= 0) {
17594                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17595                        versionsCallerCanSee.append(libVersion, libVersion);
17596                    }
17597                }
17598            }
17599        }
17600
17601        // Caller can see nothing - done
17602        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17603            return packageName;
17604        }
17605
17606        // Find the version the caller can see and the app version code
17607        SharedLibraryEntry highestVersion = null;
17608        final int versionCount = versionedLib.size();
17609        for (int i = 0; i < versionCount; i++) {
17610            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17611            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17612                    // TODO: Remove cast for lib version once internally we support longs.
17613                    (int) libEntry.info.getVersion()) < 0) {
17614                continue;
17615            }
17616            // TODO: We will change version code to long, so in the new API it is long
17617            final int libVersionCode = (int) libEntry.info.getDeclaringPackage().getVersionCode();
17618            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17619                if (libVersionCode == versionCode) {
17620                    return libEntry.apk;
17621                }
17622            } else if (highestVersion == null) {
17623                highestVersion = libEntry;
17624            } else if (libVersionCode  > highestVersion.info
17625                    .getDeclaringPackage().getVersionCode()) {
17626                highestVersion = libEntry;
17627            }
17628        }
17629
17630        if (highestVersion != null) {
17631            return highestVersion.apk;
17632        }
17633
17634        return packageName;
17635    }
17636
17637    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17638        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17639              || callingUid == Process.SYSTEM_UID) {
17640            return true;
17641        }
17642        final int callingUserId = UserHandle.getUserId(callingUid);
17643        // If the caller installed the pkgName, then allow it to silently uninstall.
17644        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17645            return true;
17646        }
17647
17648        // Allow package verifier to silently uninstall.
17649        if (mRequiredVerifierPackage != null &&
17650                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17651            return true;
17652        }
17653
17654        // Allow package uninstaller to silently uninstall.
17655        if (mRequiredUninstallerPackage != null &&
17656                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17657            return true;
17658        }
17659
17660        // Allow storage manager to silently uninstall.
17661        if (mStorageManagerPackage != null &&
17662                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17663            return true;
17664        }
17665        return false;
17666    }
17667
17668    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17669        int[] result = EMPTY_INT_ARRAY;
17670        for (int userId : userIds) {
17671            if (getBlockUninstallForUser(packageName, userId)) {
17672                result = ArrayUtils.appendInt(result, userId);
17673            }
17674        }
17675        return result;
17676    }
17677
17678    @Override
17679    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17680        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17681    }
17682
17683    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17684        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17685                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17686        try {
17687            if (dpm != null) {
17688                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17689                        /* callingUserOnly =*/ false);
17690                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17691                        : deviceOwnerComponentName.getPackageName();
17692                // Does the package contains the device owner?
17693                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17694                // this check is probably not needed, since DO should be registered as a device
17695                // admin on some user too. (Original bug for this: b/17657954)
17696                if (packageName.equals(deviceOwnerPackageName)) {
17697                    return true;
17698                }
17699                // Does it contain a device admin for any user?
17700                int[] users;
17701                if (userId == UserHandle.USER_ALL) {
17702                    users = sUserManager.getUserIds();
17703                } else {
17704                    users = new int[]{userId};
17705                }
17706                for (int i = 0; i < users.length; ++i) {
17707                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17708                        return true;
17709                    }
17710                }
17711            }
17712        } catch (RemoteException e) {
17713        }
17714        return false;
17715    }
17716
17717    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17718        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17719    }
17720
17721    /**
17722     *  This method is an internal method that could be get invoked either
17723     *  to delete an installed package or to clean up a failed installation.
17724     *  After deleting an installed package, a broadcast is sent to notify any
17725     *  listeners that the package has been removed. For cleaning up a failed
17726     *  installation, the broadcast is not necessary since the package's
17727     *  installation wouldn't have sent the initial broadcast either
17728     *  The key steps in deleting a package are
17729     *  deleting the package information in internal structures like mPackages,
17730     *  deleting the packages base directories through installd
17731     *  updating mSettings to reflect current status
17732     *  persisting settings for later use
17733     *  sending a broadcast if necessary
17734     */
17735    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
17736        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17737        final boolean res;
17738
17739        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17740                ? UserHandle.USER_ALL : userId;
17741
17742        if (isPackageDeviceAdmin(packageName, removeUser)) {
17743            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17744            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17745        }
17746
17747        PackageSetting uninstalledPs = null;
17748        PackageParser.Package pkg = null;
17749
17750        // for the uninstall-updates case and restricted profiles, remember the per-
17751        // user handle installed state
17752        int[] allUsers;
17753        synchronized (mPackages) {
17754            uninstalledPs = mSettings.mPackages.get(packageName);
17755            if (uninstalledPs == null) {
17756                Slog.w(TAG, "Not removing non-existent package " + packageName);
17757                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17758            }
17759
17760            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17761                    && uninstalledPs.versionCode != versionCode) {
17762                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17763                        + uninstalledPs.versionCode + " != " + versionCode);
17764                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17765            }
17766
17767            // Static shared libs can be declared by any package, so let us not
17768            // allow removing a package if it provides a lib others depend on.
17769            pkg = mPackages.get(packageName);
17770            if (pkg != null && pkg.staticSharedLibName != null) {
17771                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17772                        pkg.staticSharedLibVersion);
17773                if (libEntry != null) {
17774                    List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17775                            libEntry.info, 0, userId);
17776                    if (!ArrayUtils.isEmpty(libClientPackages)) {
17777                        Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17778                                + " hosting lib " + libEntry.info.getName() + " version "
17779                                + libEntry.info.getVersion()  + " used by " + libClientPackages);
17780                        return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17781                    }
17782                }
17783            }
17784
17785            allUsers = sUserManager.getUserIds();
17786            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17787        }
17788
17789        final int freezeUser;
17790        if (isUpdatedSystemApp(uninstalledPs)
17791                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17792            // We're downgrading a system app, which will apply to all users, so
17793            // freeze them all during the downgrade
17794            freezeUser = UserHandle.USER_ALL;
17795        } else {
17796            freezeUser = removeUser;
17797        }
17798
17799        synchronized (mInstallLock) {
17800            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17801            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17802                    deleteFlags, "deletePackageX")) {
17803                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17804                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
17805            }
17806            synchronized (mPackages) {
17807                if (res) {
17808                    if (pkg != null) {
17809                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17810                    }
17811                    updateSequenceNumberLP(packageName, info.removedUsers);
17812                    updateInstantAppInstallerLocked(packageName);
17813                }
17814            }
17815        }
17816
17817        if (res) {
17818            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17819            info.sendPackageRemovedBroadcasts(killApp);
17820            info.sendSystemPackageUpdatedBroadcasts();
17821            info.sendSystemPackageAppearedBroadcasts();
17822        }
17823        // Force a gc here.
17824        Runtime.getRuntime().gc();
17825        // Delete the resources here after sending the broadcast to let
17826        // other processes clean up before deleting resources.
17827        if (info.args != null) {
17828            synchronized (mInstallLock) {
17829                info.args.doPostDeleteLI(true);
17830            }
17831        }
17832
17833        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17834    }
17835
17836    static class PackageRemovedInfo {
17837        final PackageSender packageSender;
17838        String removedPackage;
17839        String installerPackageName;
17840        int uid = -1;
17841        int removedAppId = -1;
17842        int[] origUsers;
17843        int[] removedUsers = null;
17844        int[] broadcastUsers = null;
17845        SparseArray<Integer> installReasons;
17846        boolean isRemovedPackageSystemUpdate = false;
17847        boolean isUpdate;
17848        boolean dataRemoved;
17849        boolean removedForAllUsers;
17850        boolean isStaticSharedLib;
17851        // Clean up resources deleted packages.
17852        InstallArgs args = null;
17853        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17854        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17855
17856        PackageRemovedInfo(PackageSender packageSender) {
17857            this.packageSender = packageSender;
17858        }
17859
17860        void sendPackageRemovedBroadcasts(boolean killApp) {
17861            sendPackageRemovedBroadcastInternal(killApp);
17862            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17863            for (int i = 0; i < childCount; i++) {
17864                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17865                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17866            }
17867        }
17868
17869        void sendSystemPackageUpdatedBroadcasts() {
17870            if (isRemovedPackageSystemUpdate) {
17871                sendSystemPackageUpdatedBroadcastsInternal();
17872                final int childCount = (removedChildPackages != null)
17873                        ? removedChildPackages.size() : 0;
17874                for (int i = 0; i < childCount; i++) {
17875                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17876                    if (childInfo.isRemovedPackageSystemUpdate) {
17877                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17878                    }
17879                }
17880            }
17881        }
17882
17883        void sendSystemPackageAppearedBroadcasts() {
17884            final int packageCount = (appearedChildPackages != null)
17885                    ? appearedChildPackages.size() : 0;
17886            for (int i = 0; i < packageCount; i++) {
17887                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17888                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17889                    true, UserHandle.getAppId(installedInfo.uid),
17890                    installedInfo.newUsers);
17891            }
17892        }
17893
17894        private void sendSystemPackageUpdatedBroadcastsInternal() {
17895            Bundle extras = new Bundle(2);
17896            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17897            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17898            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17899                removedPackage, extras, 0, null /*targetPackage*/, null, null);
17900            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17901                removedPackage, extras, 0, null /*targetPackage*/, null, null);
17902            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17903                null, null, 0, removedPackage, null, null);
17904            if (installerPackageName != null) {
17905                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17906                        removedPackage, extras, 0 /*flags*/,
17907                        installerPackageName, null, null);
17908                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17909                        removedPackage, extras, 0 /*flags*/,
17910                        installerPackageName, null, null);
17911            }
17912        }
17913
17914        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17915            // Don't send static shared library removal broadcasts as these
17916            // libs are visible only the the apps that depend on them an one
17917            // cannot remove the library if it has a dependency.
17918            if (isStaticSharedLib) {
17919                return;
17920            }
17921            Bundle extras = new Bundle(2);
17922            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17923            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17924            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17925            if (isUpdate || isRemovedPackageSystemUpdate) {
17926                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17927            }
17928            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17929            if (removedPackage != null) {
17930                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17931                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
17932                if (installerPackageName != null) {
17933                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17934                            removedPackage, extras, 0 /*flags*/,
17935                            installerPackageName, null, broadcastUsers);
17936                }
17937                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17938                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17939                        removedPackage, extras,
17940                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17941                        null, null, broadcastUsers);
17942                }
17943            }
17944            if (removedAppId >= 0) {
17945                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
17946                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
17947            }
17948        }
17949
17950        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17951            removedUsers = userIds;
17952            if (removedUsers == null) {
17953                broadcastUsers = null;
17954                return;
17955            }
17956
17957            broadcastUsers = EMPTY_INT_ARRAY;
17958            for (int i = userIds.length - 1; i >= 0; --i) {
17959                final int userId = userIds[i];
17960                if (deletedPackageSetting.getInstantApp(userId)) {
17961                    continue;
17962                }
17963                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17964            }
17965        }
17966    }
17967
17968    /*
17969     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17970     * flag is not set, the data directory is removed as well.
17971     * make sure this flag is set for partially installed apps. If not its meaningless to
17972     * delete a partially installed application.
17973     */
17974    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17975            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17976        String packageName = ps.name;
17977        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17978        // Retrieve object to delete permissions for shared user later on
17979        final PackageParser.Package deletedPkg;
17980        final PackageSetting deletedPs;
17981        // reader
17982        synchronized (mPackages) {
17983            deletedPkg = mPackages.get(packageName);
17984            deletedPs = mSettings.mPackages.get(packageName);
17985            if (outInfo != null) {
17986                outInfo.removedPackage = packageName;
17987                outInfo.installerPackageName = ps.installerPackageName;
17988                outInfo.isStaticSharedLib = deletedPkg != null
17989                        && deletedPkg.staticSharedLibName != null;
17990                outInfo.populateUsers(deletedPs == null ? null
17991                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17992            }
17993        }
17994
17995        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
17996
17997        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17998            final PackageParser.Package resolvedPkg;
17999            if (deletedPkg != null) {
18000                resolvedPkg = deletedPkg;
18001            } else {
18002                // We don't have a parsed package when it lives on an ejected
18003                // adopted storage device, so fake something together
18004                resolvedPkg = new PackageParser.Package(ps.name);
18005                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18006            }
18007            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18008                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18009            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18010            if (outInfo != null) {
18011                outInfo.dataRemoved = true;
18012            }
18013            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18014        }
18015
18016        int removedAppId = -1;
18017
18018        // writer
18019        synchronized (mPackages) {
18020            boolean installedStateChanged = false;
18021            if (deletedPs != null) {
18022                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18023                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18024                    clearDefaultBrowserIfNeeded(packageName);
18025                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18026                    removedAppId = mSettings.removePackageLPw(packageName);
18027                    if (outInfo != null) {
18028                        outInfo.removedAppId = removedAppId;
18029                    }
18030                    updatePermissionsLPw(deletedPs.name, null, 0);
18031                    if (deletedPs.sharedUser != null) {
18032                        // Remove permissions associated with package. Since runtime
18033                        // permissions are per user we have to kill the removed package
18034                        // or packages running under the shared user of the removed
18035                        // package if revoking the permissions requested only by the removed
18036                        // package is successful and this causes a change in gids.
18037                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18038                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18039                                    userId);
18040                            if (userIdToKill == UserHandle.USER_ALL
18041                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18042                                // If gids changed for this user, kill all affected packages.
18043                                mHandler.post(new Runnable() {
18044                                    @Override
18045                                    public void run() {
18046                                        // This has to happen with no lock held.
18047                                        killApplication(deletedPs.name, deletedPs.appId,
18048                                                KILL_APP_REASON_GIDS_CHANGED);
18049                                    }
18050                                });
18051                                break;
18052                            }
18053                        }
18054                    }
18055                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18056                }
18057                // make sure to preserve per-user disabled state if this removal was just
18058                // a downgrade of a system app to the factory package
18059                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18060                    if (DEBUG_REMOVE) {
18061                        Slog.d(TAG, "Propagating install state across downgrade");
18062                    }
18063                    for (int userId : allUserHandles) {
18064                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18065                        if (DEBUG_REMOVE) {
18066                            Slog.d(TAG, "    user " + userId + " => " + installed);
18067                        }
18068                        if (installed != ps.getInstalled(userId)) {
18069                            installedStateChanged = true;
18070                        }
18071                        ps.setInstalled(installed, userId);
18072                    }
18073                }
18074            }
18075            // can downgrade to reader
18076            if (writeSettings) {
18077                // Save settings now
18078                mSettings.writeLPr();
18079            }
18080            if (installedStateChanged) {
18081                mSettings.writeKernelMappingLPr(ps);
18082            }
18083        }
18084        if (removedAppId != -1) {
18085            // A user ID was deleted here. Go through all users and remove it
18086            // from KeyStore.
18087            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18088        }
18089    }
18090
18091    static boolean locationIsPrivileged(File path) {
18092        try {
18093            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18094                    .getCanonicalPath();
18095            return path.getCanonicalPath().startsWith(privilegedAppDir);
18096        } catch (IOException e) {
18097            Slog.e(TAG, "Unable to access code path " + path);
18098        }
18099        return false;
18100    }
18101
18102    /*
18103     * Tries to delete system package.
18104     */
18105    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18106            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18107            boolean writeSettings) {
18108        if (deletedPs.parentPackageName != null) {
18109            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18110            return false;
18111        }
18112
18113        final boolean applyUserRestrictions
18114                = (allUserHandles != null) && (outInfo.origUsers != null);
18115        final PackageSetting disabledPs;
18116        // Confirm if the system package has been updated
18117        // An updated system app can be deleted. This will also have to restore
18118        // the system pkg from system partition
18119        // reader
18120        synchronized (mPackages) {
18121            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18122        }
18123
18124        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18125                + " disabledPs=" + disabledPs);
18126
18127        if (disabledPs == null) {
18128            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18129            return false;
18130        } else if (DEBUG_REMOVE) {
18131            Slog.d(TAG, "Deleting system pkg from data partition");
18132        }
18133
18134        if (DEBUG_REMOVE) {
18135            if (applyUserRestrictions) {
18136                Slog.d(TAG, "Remembering install states:");
18137                for (int userId : allUserHandles) {
18138                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18139                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18140                }
18141            }
18142        }
18143
18144        // Delete the updated package
18145        outInfo.isRemovedPackageSystemUpdate = true;
18146        if (outInfo.removedChildPackages != null) {
18147            final int childCount = (deletedPs.childPackageNames != null)
18148                    ? deletedPs.childPackageNames.size() : 0;
18149            for (int i = 0; i < childCount; i++) {
18150                String childPackageName = deletedPs.childPackageNames.get(i);
18151                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18152                        .contains(childPackageName)) {
18153                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18154                            childPackageName);
18155                    if (childInfo != null) {
18156                        childInfo.isRemovedPackageSystemUpdate = true;
18157                    }
18158                }
18159            }
18160        }
18161
18162        if (disabledPs.versionCode < deletedPs.versionCode) {
18163            // Delete data for downgrades
18164            flags &= ~PackageManager.DELETE_KEEP_DATA;
18165        } else {
18166            // Preserve data by setting flag
18167            flags |= PackageManager.DELETE_KEEP_DATA;
18168        }
18169
18170        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18171                outInfo, writeSettings, disabledPs.pkg);
18172        if (!ret) {
18173            return false;
18174        }
18175
18176        // writer
18177        synchronized (mPackages) {
18178            // Reinstate the old system package
18179            enableSystemPackageLPw(disabledPs.pkg);
18180            // Remove any native libraries from the upgraded package.
18181            removeNativeBinariesLI(deletedPs);
18182        }
18183
18184        // Install the system package
18185        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18186        int parseFlags = mDefParseFlags
18187                | PackageParser.PARSE_MUST_BE_APK
18188                | PackageParser.PARSE_IS_SYSTEM
18189                | PackageParser.PARSE_IS_SYSTEM_DIR;
18190        if (locationIsPrivileged(disabledPs.codePath)) {
18191            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18192        }
18193
18194        final PackageParser.Package newPkg;
18195        try {
18196            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18197                0 /* currentTime */, null);
18198        } catch (PackageManagerException e) {
18199            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18200                    + e.getMessage());
18201            return false;
18202        }
18203
18204        try {
18205            // update shared libraries for the newly re-installed system package
18206            updateSharedLibrariesLPr(newPkg, null);
18207        } catch (PackageManagerException e) {
18208            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18209        }
18210
18211        prepareAppDataAfterInstallLIF(newPkg);
18212
18213        // writer
18214        synchronized (mPackages) {
18215            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18216
18217            // Propagate the permissions state as we do not want to drop on the floor
18218            // runtime permissions. The update permissions method below will take
18219            // care of removing obsolete permissions and grant install permissions.
18220            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18221            updatePermissionsLPw(newPkg.packageName, newPkg,
18222                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18223
18224            if (applyUserRestrictions) {
18225                boolean installedStateChanged = false;
18226                if (DEBUG_REMOVE) {
18227                    Slog.d(TAG, "Propagating install state across reinstall");
18228                }
18229                for (int userId : allUserHandles) {
18230                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18231                    if (DEBUG_REMOVE) {
18232                        Slog.d(TAG, "    user " + userId + " => " + installed);
18233                    }
18234                    if (installed != ps.getInstalled(userId)) {
18235                        installedStateChanged = true;
18236                    }
18237                    ps.setInstalled(installed, userId);
18238
18239                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18240                }
18241                // Regardless of writeSettings we need to ensure that this restriction
18242                // state propagation is persisted
18243                mSettings.writeAllUsersPackageRestrictionsLPr();
18244                if (installedStateChanged) {
18245                    mSettings.writeKernelMappingLPr(ps);
18246                }
18247            }
18248            // can downgrade to reader here
18249            if (writeSettings) {
18250                mSettings.writeLPr();
18251            }
18252        }
18253        return true;
18254    }
18255
18256    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18257            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18258            PackageRemovedInfo outInfo, boolean writeSettings,
18259            PackageParser.Package replacingPackage) {
18260        synchronized (mPackages) {
18261            if (outInfo != null) {
18262                outInfo.uid = ps.appId;
18263            }
18264
18265            if (outInfo != null && outInfo.removedChildPackages != null) {
18266                final int childCount = (ps.childPackageNames != null)
18267                        ? ps.childPackageNames.size() : 0;
18268                for (int i = 0; i < childCount; i++) {
18269                    String childPackageName = ps.childPackageNames.get(i);
18270                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18271                    if (childPs == null) {
18272                        return false;
18273                    }
18274                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18275                            childPackageName);
18276                    if (childInfo != null) {
18277                        childInfo.uid = childPs.appId;
18278                    }
18279                }
18280            }
18281        }
18282
18283        // Delete package data from internal structures and also remove data if flag is set
18284        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18285
18286        // Delete the child packages data
18287        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18288        for (int i = 0; i < childCount; i++) {
18289            PackageSetting childPs;
18290            synchronized (mPackages) {
18291                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18292            }
18293            if (childPs != null) {
18294                PackageRemovedInfo childOutInfo = (outInfo != null
18295                        && outInfo.removedChildPackages != null)
18296                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18297                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18298                        && (replacingPackage != null
18299                        && !replacingPackage.hasChildPackage(childPs.name))
18300                        ? flags & ~DELETE_KEEP_DATA : flags;
18301                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18302                        deleteFlags, writeSettings);
18303            }
18304        }
18305
18306        // Delete application code and resources only for parent packages
18307        if (ps.parentPackageName == null) {
18308            if (deleteCodeAndResources && (outInfo != null)) {
18309                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18310                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18311                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18312            }
18313        }
18314
18315        return true;
18316    }
18317
18318    @Override
18319    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18320            int userId) {
18321        mContext.enforceCallingOrSelfPermission(
18322                android.Manifest.permission.DELETE_PACKAGES, null);
18323        synchronized (mPackages) {
18324            PackageSetting ps = mSettings.mPackages.get(packageName);
18325            if (ps == null) {
18326                Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
18327                return false;
18328            }
18329            // Cannot block uninstall of static shared libs as they are
18330            // considered a part of the using app (emulating static linking).
18331            // Also static libs are installed always on internal storage.
18332            PackageParser.Package pkg = mPackages.get(packageName);
18333            if (pkg != null && pkg.staticSharedLibName != null) {
18334                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18335                        + " providing static shared library: " + pkg.staticSharedLibName);
18336                return false;
18337            }
18338            if (!ps.getInstalled(userId)) {
18339                // Can't block uninstall for an app that is not installed or enabled.
18340                Log.i(TAG, "Package not installed in set block uninstall " + packageName);
18341                return false;
18342            }
18343            ps.setBlockUninstall(blockUninstall, userId);
18344            mSettings.writePackageRestrictionsLPr(userId);
18345        }
18346        return true;
18347    }
18348
18349    @Override
18350    public boolean getBlockUninstallForUser(String packageName, int userId) {
18351        synchronized (mPackages) {
18352            PackageSetting ps = mSettings.mPackages.get(packageName);
18353            if (ps == null) {
18354                Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
18355                return false;
18356            }
18357            return ps.getBlockUninstall(userId);
18358        }
18359    }
18360
18361    @Override
18362    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18363        int callingUid = Binder.getCallingUid();
18364        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18365            throw new SecurityException(
18366                    "setRequiredForSystemUser can only be run by the system or root");
18367        }
18368        synchronized (mPackages) {
18369            PackageSetting ps = mSettings.mPackages.get(packageName);
18370            if (ps == null) {
18371                Log.w(TAG, "Package doesn't exist: " + packageName);
18372                return false;
18373            }
18374            if (systemUserApp) {
18375                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18376            } else {
18377                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18378            }
18379            mSettings.writeLPr();
18380        }
18381        return true;
18382    }
18383
18384    /*
18385     * This method handles package deletion in general
18386     */
18387    private boolean deletePackageLIF(String packageName, UserHandle user,
18388            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18389            PackageRemovedInfo outInfo, boolean writeSettings,
18390            PackageParser.Package replacingPackage) {
18391        if (packageName == null) {
18392            Slog.w(TAG, "Attempt to delete null packageName.");
18393            return false;
18394        }
18395
18396        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18397
18398        PackageSetting ps;
18399        synchronized (mPackages) {
18400            ps = mSettings.mPackages.get(packageName);
18401            if (ps == null) {
18402                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18403                return false;
18404            }
18405
18406            if (ps.parentPackageName != null && (!isSystemApp(ps)
18407                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18408                if (DEBUG_REMOVE) {
18409                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18410                            + ((user == null) ? UserHandle.USER_ALL : user));
18411                }
18412                final int removedUserId = (user != null) ? user.getIdentifier()
18413                        : UserHandle.USER_ALL;
18414                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18415                    return false;
18416                }
18417                markPackageUninstalledForUserLPw(ps, user);
18418                scheduleWritePackageRestrictionsLocked(user);
18419                return true;
18420            }
18421        }
18422
18423        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18424                && user.getIdentifier() != UserHandle.USER_ALL)) {
18425            // The caller is asking that the package only be deleted for a single
18426            // user.  To do this, we just mark its uninstalled state and delete
18427            // its data. If this is a system app, we only allow this to happen if
18428            // they have set the special DELETE_SYSTEM_APP which requests different
18429            // semantics than normal for uninstalling system apps.
18430            markPackageUninstalledForUserLPw(ps, user);
18431
18432            if (!isSystemApp(ps)) {
18433                // Do not uninstall the APK if an app should be cached
18434                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18435                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18436                    // Other user still have this package installed, so all
18437                    // we need to do is clear this user's data and save that
18438                    // it is uninstalled.
18439                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18440                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18441                        return false;
18442                    }
18443                    scheduleWritePackageRestrictionsLocked(user);
18444                    return true;
18445                } else {
18446                    // We need to set it back to 'installed' so the uninstall
18447                    // broadcasts will be sent correctly.
18448                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18449                    ps.setInstalled(true, user.getIdentifier());
18450                    mSettings.writeKernelMappingLPr(ps);
18451                }
18452            } else {
18453                // This is a system app, so we assume that the
18454                // other users still have this package installed, so all
18455                // we need to do is clear this user's data and save that
18456                // it is uninstalled.
18457                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18458                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18459                    return false;
18460                }
18461                scheduleWritePackageRestrictionsLocked(user);
18462                return true;
18463            }
18464        }
18465
18466        // If we are deleting a composite package for all users, keep track
18467        // of result for each child.
18468        if (ps.childPackageNames != null && outInfo != null) {
18469            synchronized (mPackages) {
18470                final int childCount = ps.childPackageNames.size();
18471                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18472                for (int i = 0; i < childCount; i++) {
18473                    String childPackageName = ps.childPackageNames.get(i);
18474                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18475                    childInfo.removedPackage = childPackageName;
18476                    childInfo.installerPackageName = ps.installerPackageName;
18477                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18478                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18479                    if (childPs != null) {
18480                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18481                    }
18482                }
18483            }
18484        }
18485
18486        boolean ret = false;
18487        if (isSystemApp(ps)) {
18488            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18489            // When an updated system application is deleted we delete the existing resources
18490            // as well and fall back to existing code in system partition
18491            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18492        } else {
18493            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18494            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18495                    outInfo, writeSettings, replacingPackage);
18496        }
18497
18498        // Take a note whether we deleted the package for all users
18499        if (outInfo != null) {
18500            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18501            if (outInfo.removedChildPackages != null) {
18502                synchronized (mPackages) {
18503                    final int childCount = outInfo.removedChildPackages.size();
18504                    for (int i = 0; i < childCount; i++) {
18505                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18506                        if (childInfo != null) {
18507                            childInfo.removedForAllUsers = mPackages.get(
18508                                    childInfo.removedPackage) == null;
18509                        }
18510                    }
18511                }
18512            }
18513            // If we uninstalled an update to a system app there may be some
18514            // child packages that appeared as they are declared in the system
18515            // app but were not declared in the update.
18516            if (isSystemApp(ps)) {
18517                synchronized (mPackages) {
18518                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18519                    final int childCount = (updatedPs.childPackageNames != null)
18520                            ? updatedPs.childPackageNames.size() : 0;
18521                    for (int i = 0; i < childCount; i++) {
18522                        String childPackageName = updatedPs.childPackageNames.get(i);
18523                        if (outInfo.removedChildPackages == null
18524                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18525                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18526                            if (childPs == null) {
18527                                continue;
18528                            }
18529                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18530                            installRes.name = childPackageName;
18531                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18532                            installRes.pkg = mPackages.get(childPackageName);
18533                            installRes.uid = childPs.pkg.applicationInfo.uid;
18534                            if (outInfo.appearedChildPackages == null) {
18535                                outInfo.appearedChildPackages = new ArrayMap<>();
18536                            }
18537                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18538                        }
18539                    }
18540                }
18541            }
18542        }
18543
18544        return ret;
18545    }
18546
18547    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18548        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18549                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18550        for (int nextUserId : userIds) {
18551            if (DEBUG_REMOVE) {
18552                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18553            }
18554            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18555                    false /*installed*/,
18556                    true /*stopped*/,
18557                    true /*notLaunched*/,
18558                    false /*hidden*/,
18559                    false /*suspended*/,
18560                    false /*instantApp*/,
18561                    null /*lastDisableAppCaller*/,
18562                    null /*enabledComponents*/,
18563                    null /*disabledComponents*/,
18564                    false /*blockUninstall*/,
18565                    ps.readUserState(nextUserId).domainVerificationStatus,
18566                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18567        }
18568        mSettings.writeKernelMappingLPr(ps);
18569    }
18570
18571    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18572            PackageRemovedInfo outInfo) {
18573        final PackageParser.Package pkg;
18574        synchronized (mPackages) {
18575            pkg = mPackages.get(ps.name);
18576        }
18577
18578        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18579                : new int[] {userId};
18580        for (int nextUserId : userIds) {
18581            if (DEBUG_REMOVE) {
18582                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18583                        + nextUserId);
18584            }
18585
18586            destroyAppDataLIF(pkg, userId,
18587                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18588            destroyAppProfilesLIF(pkg, userId);
18589            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18590            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18591            schedulePackageCleaning(ps.name, nextUserId, false);
18592            synchronized (mPackages) {
18593                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18594                    scheduleWritePackageRestrictionsLocked(nextUserId);
18595                }
18596                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18597            }
18598        }
18599
18600        if (outInfo != null) {
18601            outInfo.removedPackage = ps.name;
18602            outInfo.installerPackageName = ps.installerPackageName;
18603            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18604            outInfo.removedAppId = ps.appId;
18605            outInfo.removedUsers = userIds;
18606            outInfo.broadcastUsers = userIds;
18607        }
18608
18609        return true;
18610    }
18611
18612    private final class ClearStorageConnection implements ServiceConnection {
18613        IMediaContainerService mContainerService;
18614
18615        @Override
18616        public void onServiceConnected(ComponentName name, IBinder service) {
18617            synchronized (this) {
18618                mContainerService = IMediaContainerService.Stub
18619                        .asInterface(Binder.allowBlocking(service));
18620                notifyAll();
18621            }
18622        }
18623
18624        @Override
18625        public void onServiceDisconnected(ComponentName name) {
18626        }
18627    }
18628
18629    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18630        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18631
18632        final boolean mounted;
18633        if (Environment.isExternalStorageEmulated()) {
18634            mounted = true;
18635        } else {
18636            final String status = Environment.getExternalStorageState();
18637
18638            mounted = status.equals(Environment.MEDIA_MOUNTED)
18639                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18640        }
18641
18642        if (!mounted) {
18643            return;
18644        }
18645
18646        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18647        int[] users;
18648        if (userId == UserHandle.USER_ALL) {
18649            users = sUserManager.getUserIds();
18650        } else {
18651            users = new int[] { userId };
18652        }
18653        final ClearStorageConnection conn = new ClearStorageConnection();
18654        if (mContext.bindServiceAsUser(
18655                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18656            try {
18657                for (int curUser : users) {
18658                    long timeout = SystemClock.uptimeMillis() + 5000;
18659                    synchronized (conn) {
18660                        long now;
18661                        while (conn.mContainerService == null &&
18662                                (now = SystemClock.uptimeMillis()) < timeout) {
18663                            try {
18664                                conn.wait(timeout - now);
18665                            } catch (InterruptedException e) {
18666                            }
18667                        }
18668                    }
18669                    if (conn.mContainerService == null) {
18670                        return;
18671                    }
18672
18673                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18674                    clearDirectory(conn.mContainerService,
18675                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18676                    if (allData) {
18677                        clearDirectory(conn.mContainerService,
18678                                userEnv.buildExternalStorageAppDataDirs(packageName));
18679                        clearDirectory(conn.mContainerService,
18680                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18681                    }
18682                }
18683            } finally {
18684                mContext.unbindService(conn);
18685            }
18686        }
18687    }
18688
18689    @Override
18690    public void clearApplicationProfileData(String packageName) {
18691        enforceSystemOrRoot("Only the system can clear all profile data");
18692
18693        final PackageParser.Package pkg;
18694        synchronized (mPackages) {
18695            pkg = mPackages.get(packageName);
18696        }
18697
18698        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18699            synchronized (mInstallLock) {
18700                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18701            }
18702        }
18703    }
18704
18705    @Override
18706    public void clearApplicationUserData(final String packageName,
18707            final IPackageDataObserver observer, final int userId) {
18708        mContext.enforceCallingOrSelfPermission(
18709                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18710
18711        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18712                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18713
18714        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18715            throw new SecurityException("Cannot clear data for a protected package: "
18716                    + packageName);
18717        }
18718        // Queue up an async operation since the package deletion may take a little while.
18719        mHandler.post(new Runnable() {
18720            public void run() {
18721                mHandler.removeCallbacks(this);
18722                final boolean succeeded;
18723                try (PackageFreezer freezer = freezePackage(packageName,
18724                        "clearApplicationUserData")) {
18725                    synchronized (mInstallLock) {
18726                        succeeded = clearApplicationUserDataLIF(packageName, userId);
18727                    }
18728                    clearExternalStorageDataSync(packageName, userId, true);
18729                    synchronized (mPackages) {
18730                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18731                                packageName, userId);
18732                    }
18733                }
18734                if (succeeded) {
18735                    // invoke DeviceStorageMonitor's update method to clear any notifications
18736                    DeviceStorageMonitorInternal dsm = LocalServices
18737                            .getService(DeviceStorageMonitorInternal.class);
18738                    if (dsm != null) {
18739                        dsm.checkMemory();
18740                    }
18741                }
18742                if(observer != null) {
18743                    try {
18744                        observer.onRemoveCompleted(packageName, succeeded);
18745                    } catch (RemoteException e) {
18746                        Log.i(TAG, "Observer no longer exists.");
18747                    }
18748                } //end if observer
18749            } //end run
18750        });
18751    }
18752
18753    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18754        if (packageName == null) {
18755            Slog.w(TAG, "Attempt to delete null packageName.");
18756            return false;
18757        }
18758
18759        // Try finding details about the requested package
18760        PackageParser.Package pkg;
18761        synchronized (mPackages) {
18762            pkg = mPackages.get(packageName);
18763            if (pkg == null) {
18764                final PackageSetting ps = mSettings.mPackages.get(packageName);
18765                if (ps != null) {
18766                    pkg = ps.pkg;
18767                }
18768            }
18769
18770            if (pkg == null) {
18771                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18772                return false;
18773            }
18774
18775            PackageSetting ps = (PackageSetting) pkg.mExtras;
18776            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18777        }
18778
18779        clearAppDataLIF(pkg, userId,
18780                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18781
18782        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18783        removeKeystoreDataIfNeeded(userId, appId);
18784
18785        UserManagerInternal umInternal = getUserManagerInternal();
18786        final int flags;
18787        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18788            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18789        } else if (umInternal.isUserRunning(userId)) {
18790            flags = StorageManager.FLAG_STORAGE_DE;
18791        } else {
18792            flags = 0;
18793        }
18794        prepareAppDataContentsLIF(pkg, userId, flags);
18795
18796        return true;
18797    }
18798
18799    /**
18800     * Reverts user permission state changes (permissions and flags) in
18801     * all packages for a given user.
18802     *
18803     * @param userId The device user for which to do a reset.
18804     */
18805    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18806        final int packageCount = mPackages.size();
18807        for (int i = 0; i < packageCount; i++) {
18808            PackageParser.Package pkg = mPackages.valueAt(i);
18809            PackageSetting ps = (PackageSetting) pkg.mExtras;
18810            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18811        }
18812    }
18813
18814    private void resetNetworkPolicies(int userId) {
18815        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18816    }
18817
18818    /**
18819     * Reverts user permission state changes (permissions and flags).
18820     *
18821     * @param ps The package for which to reset.
18822     * @param userId The device user for which to do a reset.
18823     */
18824    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18825            final PackageSetting ps, final int userId) {
18826        if (ps.pkg == null) {
18827            return;
18828        }
18829
18830        // These are flags that can change base on user actions.
18831        final int userSettableMask = FLAG_PERMISSION_USER_SET
18832                | FLAG_PERMISSION_USER_FIXED
18833                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18834                | FLAG_PERMISSION_REVIEW_REQUIRED;
18835
18836        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18837                | FLAG_PERMISSION_POLICY_FIXED;
18838
18839        boolean writeInstallPermissions = false;
18840        boolean writeRuntimePermissions = false;
18841
18842        final int permissionCount = ps.pkg.requestedPermissions.size();
18843        for (int i = 0; i < permissionCount; i++) {
18844            String permission = ps.pkg.requestedPermissions.get(i);
18845
18846            BasePermission bp = mSettings.mPermissions.get(permission);
18847            if (bp == null) {
18848                continue;
18849            }
18850
18851            // If shared user we just reset the state to which only this app contributed.
18852            if (ps.sharedUser != null) {
18853                boolean used = false;
18854                final int packageCount = ps.sharedUser.packages.size();
18855                for (int j = 0; j < packageCount; j++) {
18856                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18857                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18858                            && pkg.pkg.requestedPermissions.contains(permission)) {
18859                        used = true;
18860                        break;
18861                    }
18862                }
18863                if (used) {
18864                    continue;
18865                }
18866            }
18867
18868            PermissionsState permissionsState = ps.getPermissionsState();
18869
18870            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
18871
18872            // Always clear the user settable flags.
18873            final boolean hasInstallState = permissionsState.getInstallPermissionState(
18874                    bp.name) != null;
18875            // If permission review is enabled and this is a legacy app, mark the
18876            // permission as requiring a review as this is the initial state.
18877            int flags = 0;
18878            if (mPermissionReviewRequired
18879                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18880                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18881            }
18882            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18883                if (hasInstallState) {
18884                    writeInstallPermissions = true;
18885                } else {
18886                    writeRuntimePermissions = true;
18887                }
18888            }
18889
18890            // Below is only runtime permission handling.
18891            if (!bp.isRuntime()) {
18892                continue;
18893            }
18894
18895            // Never clobber system or policy.
18896            if ((oldFlags & policyOrSystemFlags) != 0) {
18897                continue;
18898            }
18899
18900            // If this permission was granted by default, make sure it is.
18901            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18902                if (permissionsState.grantRuntimePermission(bp, userId)
18903                        != PERMISSION_OPERATION_FAILURE) {
18904                    writeRuntimePermissions = true;
18905                }
18906            // If permission review is enabled the permissions for a legacy apps
18907            // are represented as constantly granted runtime ones, so don't revoke.
18908            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18909                // Otherwise, reset the permission.
18910                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18911                switch (revokeResult) {
18912                    case PERMISSION_OPERATION_SUCCESS:
18913                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18914                        writeRuntimePermissions = true;
18915                        final int appId = ps.appId;
18916                        mHandler.post(new Runnable() {
18917                            @Override
18918                            public void run() {
18919                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18920                            }
18921                        });
18922                    } break;
18923                }
18924            }
18925        }
18926
18927        // Synchronously write as we are taking permissions away.
18928        if (writeRuntimePermissions) {
18929            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18930        }
18931
18932        // Synchronously write as we are taking permissions away.
18933        if (writeInstallPermissions) {
18934            mSettings.writeLPr();
18935        }
18936    }
18937
18938    /**
18939     * Remove entries from the keystore daemon. Will only remove it if the
18940     * {@code appId} is valid.
18941     */
18942    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18943        if (appId < 0) {
18944            return;
18945        }
18946
18947        final KeyStore keyStore = KeyStore.getInstance();
18948        if (keyStore != null) {
18949            if (userId == UserHandle.USER_ALL) {
18950                for (final int individual : sUserManager.getUserIds()) {
18951                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18952                }
18953            } else {
18954                keyStore.clearUid(UserHandle.getUid(userId, appId));
18955            }
18956        } else {
18957            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18958        }
18959    }
18960
18961    @Override
18962    public void deleteApplicationCacheFiles(final String packageName,
18963            final IPackageDataObserver observer) {
18964        final int userId = UserHandle.getCallingUserId();
18965        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18966    }
18967
18968    @Override
18969    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18970            final IPackageDataObserver observer) {
18971        mContext.enforceCallingOrSelfPermission(
18972                android.Manifest.permission.DELETE_CACHE_FILES, null);
18973        enforceCrossUserPermission(Binder.getCallingUid(), userId,
18974                /* requireFullPermission= */ true, /* checkShell= */ false,
18975                "delete application cache files");
18976
18977        final PackageParser.Package pkg;
18978        synchronized (mPackages) {
18979            pkg = mPackages.get(packageName);
18980        }
18981
18982        // Queue up an async operation since the package deletion may take a little while.
18983        mHandler.post(new Runnable() {
18984            public void run() {
18985                synchronized (mInstallLock) {
18986                    final int flags = StorageManager.FLAG_STORAGE_DE
18987                            | StorageManager.FLAG_STORAGE_CE;
18988                    // We're only clearing cache files, so we don't care if the
18989                    // app is unfrozen and still able to run
18990                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18991                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18992                }
18993                clearExternalStorageDataSync(packageName, userId, false);
18994                if (observer != null) {
18995                    try {
18996                        observer.onRemoveCompleted(packageName, true);
18997                    } catch (RemoteException e) {
18998                        Log.i(TAG, "Observer no longer exists.");
18999                    }
19000                }
19001            }
19002        });
19003    }
19004
19005    @Override
19006    public void getPackageSizeInfo(final String packageName, int userHandle,
19007            final IPackageStatsObserver observer) {
19008        throw new UnsupportedOperationException(
19009                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19010    }
19011
19012    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19013        final PackageSetting ps;
19014        synchronized (mPackages) {
19015            ps = mSettings.mPackages.get(packageName);
19016            if (ps == null) {
19017                Slog.w(TAG, "Failed to find settings for " + packageName);
19018                return false;
19019            }
19020        }
19021
19022        final String[] packageNames = { packageName };
19023        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19024        final String[] codePaths = { ps.codePathString };
19025
19026        try {
19027            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19028                    ps.appId, ceDataInodes, codePaths, stats);
19029
19030            // For now, ignore code size of packages on system partition
19031            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19032                stats.codeSize = 0;
19033            }
19034
19035            // External clients expect these to be tracked separately
19036            stats.dataSize -= stats.cacheSize;
19037
19038        } catch (InstallerException e) {
19039            Slog.w(TAG, String.valueOf(e));
19040            return false;
19041        }
19042
19043        return true;
19044    }
19045
19046    private int getUidTargetSdkVersionLockedLPr(int uid) {
19047        Object obj = mSettings.getUserIdLPr(uid);
19048        if (obj instanceof SharedUserSetting) {
19049            final SharedUserSetting sus = (SharedUserSetting) obj;
19050            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19051            final Iterator<PackageSetting> it = sus.packages.iterator();
19052            while (it.hasNext()) {
19053                final PackageSetting ps = it.next();
19054                if (ps.pkg != null) {
19055                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19056                    if (v < vers) vers = v;
19057                }
19058            }
19059            return vers;
19060        } else if (obj instanceof PackageSetting) {
19061            final PackageSetting ps = (PackageSetting) obj;
19062            if (ps.pkg != null) {
19063                return ps.pkg.applicationInfo.targetSdkVersion;
19064            }
19065        }
19066        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19067    }
19068
19069    @Override
19070    public void addPreferredActivity(IntentFilter filter, int match,
19071            ComponentName[] set, ComponentName activity, int userId) {
19072        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19073                "Adding preferred");
19074    }
19075
19076    private void addPreferredActivityInternal(IntentFilter filter, int match,
19077            ComponentName[] set, ComponentName activity, boolean always, int userId,
19078            String opname) {
19079        // writer
19080        int callingUid = Binder.getCallingUid();
19081        enforceCrossUserPermission(callingUid, userId,
19082                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19083        if (filter.countActions() == 0) {
19084            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19085            return;
19086        }
19087        synchronized (mPackages) {
19088            if (mContext.checkCallingOrSelfPermission(
19089                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19090                    != PackageManager.PERMISSION_GRANTED) {
19091                if (getUidTargetSdkVersionLockedLPr(callingUid)
19092                        < Build.VERSION_CODES.FROYO) {
19093                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19094                            + callingUid);
19095                    return;
19096                }
19097                mContext.enforceCallingOrSelfPermission(
19098                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19099            }
19100
19101            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19102            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19103                    + userId + ":");
19104            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19105            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19106            scheduleWritePackageRestrictionsLocked(userId);
19107            postPreferredActivityChangedBroadcast(userId);
19108        }
19109    }
19110
19111    private void postPreferredActivityChangedBroadcast(int userId) {
19112        mHandler.post(() -> {
19113            final IActivityManager am = ActivityManager.getService();
19114            if (am == null) {
19115                return;
19116            }
19117
19118            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19119            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19120            try {
19121                am.broadcastIntent(null, intent, null, null,
19122                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19123                        null, false, false, userId);
19124            } catch (RemoteException e) {
19125            }
19126        });
19127    }
19128
19129    @Override
19130    public void replacePreferredActivity(IntentFilter filter, int match,
19131            ComponentName[] set, ComponentName activity, int userId) {
19132        if (filter.countActions() != 1) {
19133            throw new IllegalArgumentException(
19134                    "replacePreferredActivity expects filter to have only 1 action.");
19135        }
19136        if (filter.countDataAuthorities() != 0
19137                || filter.countDataPaths() != 0
19138                || filter.countDataSchemes() > 1
19139                || filter.countDataTypes() != 0) {
19140            throw new IllegalArgumentException(
19141                    "replacePreferredActivity expects filter to have no data authorities, " +
19142                    "paths, or types; and at most one scheme.");
19143        }
19144
19145        final int callingUid = Binder.getCallingUid();
19146        enforceCrossUserPermission(callingUid, userId,
19147                true /* requireFullPermission */, false /* checkShell */,
19148                "replace preferred activity");
19149        synchronized (mPackages) {
19150            if (mContext.checkCallingOrSelfPermission(
19151                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19152                    != PackageManager.PERMISSION_GRANTED) {
19153                if (getUidTargetSdkVersionLockedLPr(callingUid)
19154                        < Build.VERSION_CODES.FROYO) {
19155                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19156                            + Binder.getCallingUid());
19157                    return;
19158                }
19159                mContext.enforceCallingOrSelfPermission(
19160                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19161            }
19162
19163            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19164            if (pir != null) {
19165                // Get all of the existing entries that exactly match this filter.
19166                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19167                if (existing != null && existing.size() == 1) {
19168                    PreferredActivity cur = existing.get(0);
19169                    if (DEBUG_PREFERRED) {
19170                        Slog.i(TAG, "Checking replace of preferred:");
19171                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19172                        if (!cur.mPref.mAlways) {
19173                            Slog.i(TAG, "  -- CUR; not mAlways!");
19174                        } else {
19175                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19176                            Slog.i(TAG, "  -- CUR: mSet="
19177                                    + Arrays.toString(cur.mPref.mSetComponents));
19178                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19179                            Slog.i(TAG, "  -- NEW: mMatch="
19180                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19181                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19182                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19183                        }
19184                    }
19185                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19186                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19187                            && cur.mPref.sameSet(set)) {
19188                        // Setting the preferred activity to what it happens to be already
19189                        if (DEBUG_PREFERRED) {
19190                            Slog.i(TAG, "Replacing with same preferred activity "
19191                                    + cur.mPref.mShortComponent + " for user "
19192                                    + userId + ":");
19193                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19194                        }
19195                        return;
19196                    }
19197                }
19198
19199                if (existing != null) {
19200                    if (DEBUG_PREFERRED) {
19201                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19202                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19203                    }
19204                    for (int i = 0; i < existing.size(); i++) {
19205                        PreferredActivity pa = existing.get(i);
19206                        if (DEBUG_PREFERRED) {
19207                            Slog.i(TAG, "Removing existing preferred activity "
19208                                    + pa.mPref.mComponent + ":");
19209                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19210                        }
19211                        pir.removeFilter(pa);
19212                    }
19213                }
19214            }
19215            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19216                    "Replacing preferred");
19217        }
19218    }
19219
19220    @Override
19221    public void clearPackagePreferredActivities(String packageName) {
19222        final int uid = Binder.getCallingUid();
19223        // writer
19224        synchronized (mPackages) {
19225            PackageParser.Package pkg = mPackages.get(packageName);
19226            if (pkg == null || pkg.applicationInfo.uid != uid) {
19227                if (mContext.checkCallingOrSelfPermission(
19228                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19229                        != PackageManager.PERMISSION_GRANTED) {
19230                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19231                            < Build.VERSION_CODES.FROYO) {
19232                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19233                                + Binder.getCallingUid());
19234                        return;
19235                    }
19236                    mContext.enforceCallingOrSelfPermission(
19237                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19238                }
19239            }
19240
19241            int user = UserHandle.getCallingUserId();
19242            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19243                scheduleWritePackageRestrictionsLocked(user);
19244            }
19245        }
19246    }
19247
19248    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19249    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19250        ArrayList<PreferredActivity> removed = null;
19251        boolean changed = false;
19252        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19253            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19254            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19255            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19256                continue;
19257            }
19258            Iterator<PreferredActivity> it = pir.filterIterator();
19259            while (it.hasNext()) {
19260                PreferredActivity pa = it.next();
19261                // Mark entry for removal only if it matches the package name
19262                // and the entry is of type "always".
19263                if (packageName == null ||
19264                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19265                                && pa.mPref.mAlways)) {
19266                    if (removed == null) {
19267                        removed = new ArrayList<PreferredActivity>();
19268                    }
19269                    removed.add(pa);
19270                }
19271            }
19272            if (removed != null) {
19273                for (int j=0; j<removed.size(); j++) {
19274                    PreferredActivity pa = removed.get(j);
19275                    pir.removeFilter(pa);
19276                }
19277                changed = true;
19278            }
19279        }
19280        if (changed) {
19281            postPreferredActivityChangedBroadcast(userId);
19282        }
19283        return changed;
19284    }
19285
19286    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19287    private void clearIntentFilterVerificationsLPw(int userId) {
19288        final int packageCount = mPackages.size();
19289        for (int i = 0; i < packageCount; i++) {
19290            PackageParser.Package pkg = mPackages.valueAt(i);
19291            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19292        }
19293    }
19294
19295    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19296    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19297        if (userId == UserHandle.USER_ALL) {
19298            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19299                    sUserManager.getUserIds())) {
19300                for (int oneUserId : sUserManager.getUserIds()) {
19301                    scheduleWritePackageRestrictionsLocked(oneUserId);
19302                }
19303            }
19304        } else {
19305            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19306                scheduleWritePackageRestrictionsLocked(userId);
19307            }
19308        }
19309    }
19310
19311    /** Clears state for all users, and touches intent filter verification policy */
19312    void clearDefaultBrowserIfNeeded(String packageName) {
19313        for (int oneUserId : sUserManager.getUserIds()) {
19314            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19315        }
19316    }
19317
19318    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19319        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19320        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19321            if (packageName.equals(defaultBrowserPackageName)) {
19322                setDefaultBrowserPackageName(null, userId);
19323            }
19324        }
19325    }
19326
19327    @Override
19328    public void resetApplicationPreferences(int userId) {
19329        mContext.enforceCallingOrSelfPermission(
19330                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19331        final long identity = Binder.clearCallingIdentity();
19332        // writer
19333        try {
19334            synchronized (mPackages) {
19335                clearPackagePreferredActivitiesLPw(null, userId);
19336                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19337                // TODO: We have to reset the default SMS and Phone. This requires
19338                // significant refactoring to keep all default apps in the package
19339                // manager (cleaner but more work) or have the services provide
19340                // callbacks to the package manager to request a default app reset.
19341                applyFactoryDefaultBrowserLPw(userId);
19342                clearIntentFilterVerificationsLPw(userId);
19343                primeDomainVerificationsLPw(userId);
19344                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19345                scheduleWritePackageRestrictionsLocked(userId);
19346            }
19347            resetNetworkPolicies(userId);
19348        } finally {
19349            Binder.restoreCallingIdentity(identity);
19350        }
19351    }
19352
19353    @Override
19354    public int getPreferredActivities(List<IntentFilter> outFilters,
19355            List<ComponentName> outActivities, String packageName) {
19356
19357        int num = 0;
19358        final int userId = UserHandle.getCallingUserId();
19359        // reader
19360        synchronized (mPackages) {
19361            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19362            if (pir != null) {
19363                final Iterator<PreferredActivity> it = pir.filterIterator();
19364                while (it.hasNext()) {
19365                    final PreferredActivity pa = it.next();
19366                    if (packageName == null
19367                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19368                                    && pa.mPref.mAlways)) {
19369                        if (outFilters != null) {
19370                            outFilters.add(new IntentFilter(pa));
19371                        }
19372                        if (outActivities != null) {
19373                            outActivities.add(pa.mPref.mComponent);
19374                        }
19375                    }
19376                }
19377            }
19378        }
19379
19380        return num;
19381    }
19382
19383    @Override
19384    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19385            int userId) {
19386        int callingUid = Binder.getCallingUid();
19387        if (callingUid != Process.SYSTEM_UID) {
19388            throw new SecurityException(
19389                    "addPersistentPreferredActivity can only be run by the system");
19390        }
19391        if (filter.countActions() == 0) {
19392            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19393            return;
19394        }
19395        synchronized (mPackages) {
19396            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19397                    ":");
19398            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19399            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19400                    new PersistentPreferredActivity(filter, activity));
19401            scheduleWritePackageRestrictionsLocked(userId);
19402            postPreferredActivityChangedBroadcast(userId);
19403        }
19404    }
19405
19406    @Override
19407    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19408        int callingUid = Binder.getCallingUid();
19409        if (callingUid != Process.SYSTEM_UID) {
19410            throw new SecurityException(
19411                    "clearPackagePersistentPreferredActivities can only be run by the system");
19412        }
19413        ArrayList<PersistentPreferredActivity> removed = null;
19414        boolean changed = false;
19415        synchronized (mPackages) {
19416            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19417                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19418                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19419                        .valueAt(i);
19420                if (userId != thisUserId) {
19421                    continue;
19422                }
19423                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19424                while (it.hasNext()) {
19425                    PersistentPreferredActivity ppa = it.next();
19426                    // Mark entry for removal only if it matches the package name.
19427                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19428                        if (removed == null) {
19429                            removed = new ArrayList<PersistentPreferredActivity>();
19430                        }
19431                        removed.add(ppa);
19432                    }
19433                }
19434                if (removed != null) {
19435                    for (int j=0; j<removed.size(); j++) {
19436                        PersistentPreferredActivity ppa = removed.get(j);
19437                        ppir.removeFilter(ppa);
19438                    }
19439                    changed = true;
19440                }
19441            }
19442
19443            if (changed) {
19444                scheduleWritePackageRestrictionsLocked(userId);
19445                postPreferredActivityChangedBroadcast(userId);
19446            }
19447        }
19448    }
19449
19450    /**
19451     * Common machinery for picking apart a restored XML blob and passing
19452     * it to a caller-supplied functor to be applied to the running system.
19453     */
19454    private void restoreFromXml(XmlPullParser parser, int userId,
19455            String expectedStartTag, BlobXmlRestorer functor)
19456            throws IOException, XmlPullParserException {
19457        int type;
19458        while ((type = parser.next()) != XmlPullParser.START_TAG
19459                && type != XmlPullParser.END_DOCUMENT) {
19460        }
19461        if (type != XmlPullParser.START_TAG) {
19462            // oops didn't find a start tag?!
19463            if (DEBUG_BACKUP) {
19464                Slog.e(TAG, "Didn't find start tag during restore");
19465            }
19466            return;
19467        }
19468Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19469        // this is supposed to be TAG_PREFERRED_BACKUP
19470        if (!expectedStartTag.equals(parser.getName())) {
19471            if (DEBUG_BACKUP) {
19472                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19473            }
19474            return;
19475        }
19476
19477        // skip interfering stuff, then we're aligned with the backing implementation
19478        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19479Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19480        functor.apply(parser, userId);
19481    }
19482
19483    private interface BlobXmlRestorer {
19484        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19485    }
19486
19487    /**
19488     * Non-Binder method, support for the backup/restore mechanism: write the
19489     * full set of preferred activities in its canonical XML format.  Returns the
19490     * XML output as a byte array, or null if there is none.
19491     */
19492    @Override
19493    public byte[] getPreferredActivityBackup(int userId) {
19494        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19495            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19496        }
19497
19498        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19499        try {
19500            final XmlSerializer serializer = new FastXmlSerializer();
19501            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19502            serializer.startDocument(null, true);
19503            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19504
19505            synchronized (mPackages) {
19506                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19507            }
19508
19509            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19510            serializer.endDocument();
19511            serializer.flush();
19512        } catch (Exception e) {
19513            if (DEBUG_BACKUP) {
19514                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19515            }
19516            return null;
19517        }
19518
19519        return dataStream.toByteArray();
19520    }
19521
19522    @Override
19523    public void restorePreferredActivities(byte[] backup, int userId) {
19524        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19525            throw new SecurityException("Only the system may call restorePreferredActivities()");
19526        }
19527
19528        try {
19529            final XmlPullParser parser = Xml.newPullParser();
19530            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19531            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19532                    new BlobXmlRestorer() {
19533                        @Override
19534                        public void apply(XmlPullParser parser, int userId)
19535                                throws XmlPullParserException, IOException {
19536                            synchronized (mPackages) {
19537                                mSettings.readPreferredActivitiesLPw(parser, userId);
19538                            }
19539                        }
19540                    } );
19541        } catch (Exception e) {
19542            if (DEBUG_BACKUP) {
19543                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19544            }
19545        }
19546    }
19547
19548    /**
19549     * Non-Binder method, support for the backup/restore mechanism: write the
19550     * default browser (etc) settings in its canonical XML format.  Returns the default
19551     * browser XML representation as a byte array, or null if there is none.
19552     */
19553    @Override
19554    public byte[] getDefaultAppsBackup(int userId) {
19555        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19556            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19557        }
19558
19559        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19560        try {
19561            final XmlSerializer serializer = new FastXmlSerializer();
19562            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19563            serializer.startDocument(null, true);
19564            serializer.startTag(null, TAG_DEFAULT_APPS);
19565
19566            synchronized (mPackages) {
19567                mSettings.writeDefaultAppsLPr(serializer, userId);
19568            }
19569
19570            serializer.endTag(null, TAG_DEFAULT_APPS);
19571            serializer.endDocument();
19572            serializer.flush();
19573        } catch (Exception e) {
19574            if (DEBUG_BACKUP) {
19575                Slog.e(TAG, "Unable to write default apps for backup", e);
19576            }
19577            return null;
19578        }
19579
19580        return dataStream.toByteArray();
19581    }
19582
19583    @Override
19584    public void restoreDefaultApps(byte[] backup, int userId) {
19585        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19586            throw new SecurityException("Only the system may call restoreDefaultApps()");
19587        }
19588
19589        try {
19590            final XmlPullParser parser = Xml.newPullParser();
19591            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19592            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19593                    new BlobXmlRestorer() {
19594                        @Override
19595                        public void apply(XmlPullParser parser, int userId)
19596                                throws XmlPullParserException, IOException {
19597                            synchronized (mPackages) {
19598                                mSettings.readDefaultAppsLPw(parser, userId);
19599                            }
19600                        }
19601                    } );
19602        } catch (Exception e) {
19603            if (DEBUG_BACKUP) {
19604                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19605            }
19606        }
19607    }
19608
19609    @Override
19610    public byte[] getIntentFilterVerificationBackup(int userId) {
19611        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19612            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19613        }
19614
19615        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19616        try {
19617            final XmlSerializer serializer = new FastXmlSerializer();
19618            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19619            serializer.startDocument(null, true);
19620            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19621
19622            synchronized (mPackages) {
19623                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19624            }
19625
19626            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19627            serializer.endDocument();
19628            serializer.flush();
19629        } catch (Exception e) {
19630            if (DEBUG_BACKUP) {
19631                Slog.e(TAG, "Unable to write default apps for backup", e);
19632            }
19633            return null;
19634        }
19635
19636        return dataStream.toByteArray();
19637    }
19638
19639    @Override
19640    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19641        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19642            throw new SecurityException("Only the system may call restorePreferredActivities()");
19643        }
19644
19645        try {
19646            final XmlPullParser parser = Xml.newPullParser();
19647            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19648            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19649                    new BlobXmlRestorer() {
19650                        @Override
19651                        public void apply(XmlPullParser parser, int userId)
19652                                throws XmlPullParserException, IOException {
19653                            synchronized (mPackages) {
19654                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19655                                mSettings.writeLPr();
19656                            }
19657                        }
19658                    } );
19659        } catch (Exception e) {
19660            if (DEBUG_BACKUP) {
19661                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19662            }
19663        }
19664    }
19665
19666    @Override
19667    public byte[] getPermissionGrantBackup(int userId) {
19668        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19669            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19670        }
19671
19672        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19673        try {
19674            final XmlSerializer serializer = new FastXmlSerializer();
19675            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19676            serializer.startDocument(null, true);
19677            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19678
19679            synchronized (mPackages) {
19680                serializeRuntimePermissionGrantsLPr(serializer, userId);
19681            }
19682
19683            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19684            serializer.endDocument();
19685            serializer.flush();
19686        } catch (Exception e) {
19687            if (DEBUG_BACKUP) {
19688                Slog.e(TAG, "Unable to write default apps for backup", e);
19689            }
19690            return null;
19691        }
19692
19693        return dataStream.toByteArray();
19694    }
19695
19696    @Override
19697    public void restorePermissionGrants(byte[] backup, int userId) {
19698        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19699            throw new SecurityException("Only the system may call restorePermissionGrants()");
19700        }
19701
19702        try {
19703            final XmlPullParser parser = Xml.newPullParser();
19704            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19705            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19706                    new BlobXmlRestorer() {
19707                        @Override
19708                        public void apply(XmlPullParser parser, int userId)
19709                                throws XmlPullParserException, IOException {
19710                            synchronized (mPackages) {
19711                                processRestoredPermissionGrantsLPr(parser, userId);
19712                            }
19713                        }
19714                    } );
19715        } catch (Exception e) {
19716            if (DEBUG_BACKUP) {
19717                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19718            }
19719        }
19720    }
19721
19722    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19723            throws IOException {
19724        serializer.startTag(null, TAG_ALL_GRANTS);
19725
19726        final int N = mSettings.mPackages.size();
19727        for (int i = 0; i < N; i++) {
19728            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19729            boolean pkgGrantsKnown = false;
19730
19731            PermissionsState packagePerms = ps.getPermissionsState();
19732
19733            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19734                final int grantFlags = state.getFlags();
19735                // only look at grants that are not system/policy fixed
19736                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19737                    final boolean isGranted = state.isGranted();
19738                    // And only back up the user-twiddled state bits
19739                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19740                        final String packageName = mSettings.mPackages.keyAt(i);
19741                        if (!pkgGrantsKnown) {
19742                            serializer.startTag(null, TAG_GRANT);
19743                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19744                            pkgGrantsKnown = true;
19745                        }
19746
19747                        final boolean userSet =
19748                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19749                        final boolean userFixed =
19750                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19751                        final boolean revoke =
19752                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19753
19754                        serializer.startTag(null, TAG_PERMISSION);
19755                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19756                        if (isGranted) {
19757                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19758                        }
19759                        if (userSet) {
19760                            serializer.attribute(null, ATTR_USER_SET, "true");
19761                        }
19762                        if (userFixed) {
19763                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19764                        }
19765                        if (revoke) {
19766                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19767                        }
19768                        serializer.endTag(null, TAG_PERMISSION);
19769                    }
19770                }
19771            }
19772
19773            if (pkgGrantsKnown) {
19774                serializer.endTag(null, TAG_GRANT);
19775            }
19776        }
19777
19778        serializer.endTag(null, TAG_ALL_GRANTS);
19779    }
19780
19781    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19782            throws XmlPullParserException, IOException {
19783        String pkgName = null;
19784        int outerDepth = parser.getDepth();
19785        int type;
19786        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19787                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19788            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19789                continue;
19790            }
19791
19792            final String tagName = parser.getName();
19793            if (tagName.equals(TAG_GRANT)) {
19794                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19795                if (DEBUG_BACKUP) {
19796                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19797                }
19798            } else if (tagName.equals(TAG_PERMISSION)) {
19799
19800                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19801                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19802
19803                int newFlagSet = 0;
19804                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19805                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19806                }
19807                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19808                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19809                }
19810                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19811                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19812                }
19813                if (DEBUG_BACKUP) {
19814                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
19815                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
19816                }
19817                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19818                if (ps != null) {
19819                    // Already installed so we apply the grant immediately
19820                    if (DEBUG_BACKUP) {
19821                        Slog.v(TAG, "        + already installed; applying");
19822                    }
19823                    PermissionsState perms = ps.getPermissionsState();
19824                    BasePermission bp = mSettings.mPermissions.get(permName);
19825                    if (bp != null) {
19826                        if (isGranted) {
19827                            perms.grantRuntimePermission(bp, userId);
19828                        }
19829                        if (newFlagSet != 0) {
19830                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19831                        }
19832                    }
19833                } else {
19834                    // Need to wait for post-restore install to apply the grant
19835                    if (DEBUG_BACKUP) {
19836                        Slog.v(TAG, "        - not yet installed; saving for later");
19837                    }
19838                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19839                            isGranted, newFlagSet, userId);
19840                }
19841            } else {
19842                PackageManagerService.reportSettingsProblem(Log.WARN,
19843                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19844                XmlUtils.skipCurrentTag(parser);
19845            }
19846        }
19847
19848        scheduleWriteSettingsLocked();
19849        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19850    }
19851
19852    @Override
19853    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19854            int sourceUserId, int targetUserId, int flags) {
19855        mContext.enforceCallingOrSelfPermission(
19856                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19857        int callingUid = Binder.getCallingUid();
19858        enforceOwnerRights(ownerPackage, callingUid);
19859        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19860        if (intentFilter.countActions() == 0) {
19861            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19862            return;
19863        }
19864        synchronized (mPackages) {
19865            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19866                    ownerPackage, targetUserId, flags);
19867            CrossProfileIntentResolver resolver =
19868                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19869            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19870            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19871            if (existing != null) {
19872                int size = existing.size();
19873                for (int i = 0; i < size; i++) {
19874                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19875                        return;
19876                    }
19877                }
19878            }
19879            resolver.addFilter(newFilter);
19880            scheduleWritePackageRestrictionsLocked(sourceUserId);
19881        }
19882    }
19883
19884    @Override
19885    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19886        mContext.enforceCallingOrSelfPermission(
19887                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19888        int callingUid = Binder.getCallingUid();
19889        enforceOwnerRights(ownerPackage, callingUid);
19890        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19891        synchronized (mPackages) {
19892            CrossProfileIntentResolver resolver =
19893                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19894            ArraySet<CrossProfileIntentFilter> set =
19895                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19896            for (CrossProfileIntentFilter filter : set) {
19897                if (filter.getOwnerPackage().equals(ownerPackage)) {
19898                    resolver.removeFilter(filter);
19899                }
19900            }
19901            scheduleWritePackageRestrictionsLocked(sourceUserId);
19902        }
19903    }
19904
19905    // Enforcing that callingUid is owning pkg on userId
19906    private void enforceOwnerRights(String pkg, int callingUid) {
19907        // The system owns everything.
19908        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19909            return;
19910        }
19911        int callingUserId = UserHandle.getUserId(callingUid);
19912        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19913        if (pi == null) {
19914            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19915                    + callingUserId);
19916        }
19917        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19918            throw new SecurityException("Calling uid " + callingUid
19919                    + " does not own package " + pkg);
19920        }
19921    }
19922
19923    @Override
19924    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19925        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19926    }
19927
19928    /**
19929     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19930     * then reports the most likely home activity or null if there are more than one.
19931     */
19932    public ComponentName getDefaultHomeActivity(int userId) {
19933        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19934        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19935        if (cn != null) {
19936            return cn;
19937        }
19938
19939        // Find the launcher with the highest priority and return that component if there are no
19940        // other home activity with the same priority.
19941        int lastPriority = Integer.MIN_VALUE;
19942        ComponentName lastComponent = null;
19943        final int size = allHomeCandidates.size();
19944        for (int i = 0; i < size; i++) {
19945            final ResolveInfo ri = allHomeCandidates.get(i);
19946            if (ri.priority > lastPriority) {
19947                lastComponent = ri.activityInfo.getComponentName();
19948                lastPriority = ri.priority;
19949            } else if (ri.priority == lastPriority) {
19950                // Two components found with same priority.
19951                lastComponent = null;
19952            }
19953        }
19954        return lastComponent;
19955    }
19956
19957    private Intent getHomeIntent() {
19958        Intent intent = new Intent(Intent.ACTION_MAIN);
19959        intent.addCategory(Intent.CATEGORY_HOME);
19960        intent.addCategory(Intent.CATEGORY_DEFAULT);
19961        return intent;
19962    }
19963
19964    private IntentFilter getHomeFilter() {
19965        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19966        filter.addCategory(Intent.CATEGORY_HOME);
19967        filter.addCategory(Intent.CATEGORY_DEFAULT);
19968        return filter;
19969    }
19970
19971    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19972            int userId) {
19973        Intent intent  = getHomeIntent();
19974        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19975                PackageManager.GET_META_DATA, userId);
19976        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19977                true, false, false, userId);
19978
19979        allHomeCandidates.clear();
19980        if (list != null) {
19981            for (ResolveInfo ri : list) {
19982                allHomeCandidates.add(ri);
19983            }
19984        }
19985        return (preferred == null || preferred.activityInfo == null)
19986                ? null
19987                : new ComponentName(preferred.activityInfo.packageName,
19988                        preferred.activityInfo.name);
19989    }
19990
19991    @Override
19992    public void setHomeActivity(ComponentName comp, int userId) {
19993        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19994        getHomeActivitiesAsUser(homeActivities, userId);
19995
19996        boolean found = false;
19997
19998        final int size = homeActivities.size();
19999        final ComponentName[] set = new ComponentName[size];
20000        for (int i = 0; i < size; i++) {
20001            final ResolveInfo candidate = homeActivities.get(i);
20002            final ActivityInfo info = candidate.activityInfo;
20003            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20004            set[i] = activityName;
20005            if (!found && activityName.equals(comp)) {
20006                found = true;
20007            }
20008        }
20009        if (!found) {
20010            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20011                    + userId);
20012        }
20013        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20014                set, comp, userId);
20015    }
20016
20017    private @Nullable String getSetupWizardPackageName() {
20018        final Intent intent = new Intent(Intent.ACTION_MAIN);
20019        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20020
20021        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20022                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20023                        | MATCH_DISABLED_COMPONENTS,
20024                UserHandle.myUserId());
20025        if (matches.size() == 1) {
20026            return matches.get(0).getComponentInfo().packageName;
20027        } else {
20028            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20029                    + ": matches=" + matches);
20030            return null;
20031        }
20032    }
20033
20034    private @Nullable String getStorageManagerPackageName() {
20035        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20036
20037        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20038                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20039                        | MATCH_DISABLED_COMPONENTS,
20040                UserHandle.myUserId());
20041        if (matches.size() == 1) {
20042            return matches.get(0).getComponentInfo().packageName;
20043        } else {
20044            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20045                    + matches.size() + ": matches=" + matches);
20046            return null;
20047        }
20048    }
20049
20050    @Override
20051    public void setApplicationEnabledSetting(String appPackageName,
20052            int newState, int flags, int userId, String callingPackage) {
20053        if (!sUserManager.exists(userId)) return;
20054        if (callingPackage == null) {
20055            callingPackage = Integer.toString(Binder.getCallingUid());
20056        }
20057        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20058    }
20059
20060    @Override
20061    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20062        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20063        synchronized (mPackages) {
20064            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20065            if (pkgSetting != null) {
20066                pkgSetting.setUpdateAvailable(updateAvailable);
20067            }
20068        }
20069    }
20070
20071    @Override
20072    public void setComponentEnabledSetting(ComponentName componentName,
20073            int newState, int flags, int userId) {
20074        if (!sUserManager.exists(userId)) return;
20075        setEnabledSetting(componentName.getPackageName(),
20076                componentName.getClassName(), newState, flags, userId, null);
20077    }
20078
20079    private void setEnabledSetting(final String packageName, String className, int newState,
20080            final int flags, int userId, String callingPackage) {
20081        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20082              || newState == COMPONENT_ENABLED_STATE_ENABLED
20083              || newState == COMPONENT_ENABLED_STATE_DISABLED
20084              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20085              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20086            throw new IllegalArgumentException("Invalid new component state: "
20087                    + newState);
20088        }
20089        PackageSetting pkgSetting;
20090        final int uid = Binder.getCallingUid();
20091        final int permission;
20092        if (uid == Process.SYSTEM_UID) {
20093            permission = PackageManager.PERMISSION_GRANTED;
20094        } else {
20095            permission = mContext.checkCallingOrSelfPermission(
20096                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20097        }
20098        enforceCrossUserPermission(uid, userId,
20099                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20100        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20101        boolean sendNow = false;
20102        boolean isApp = (className == null);
20103        String componentName = isApp ? packageName : className;
20104        int packageUid = -1;
20105        ArrayList<String> components;
20106
20107        // writer
20108        synchronized (mPackages) {
20109            pkgSetting = mSettings.mPackages.get(packageName);
20110            if (pkgSetting == null) {
20111                if (className == null) {
20112                    throw new IllegalArgumentException("Unknown package: " + packageName);
20113                }
20114                throw new IllegalArgumentException(
20115                        "Unknown component: " + packageName + "/" + className);
20116            }
20117        }
20118
20119        // Limit who can change which apps
20120        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20121            // Don't allow apps that don't have permission to modify other apps
20122            if (!allowedByPermission) {
20123                throw new SecurityException(
20124                        "Permission Denial: attempt to change component state from pid="
20125                        + Binder.getCallingPid()
20126                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20127            }
20128            // Don't allow changing protected packages.
20129            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20130                throw new SecurityException("Cannot disable a protected package: " + packageName);
20131            }
20132        }
20133
20134        synchronized (mPackages) {
20135            if (uid == Process.SHELL_UID
20136                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20137                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20138                // unless it is a test package.
20139                int oldState = pkgSetting.getEnabled(userId);
20140                if (className == null
20141                    &&
20142                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20143                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20144                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20145                    &&
20146                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20147                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20148                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20149                    // ok
20150                } else {
20151                    throw new SecurityException(
20152                            "Shell cannot change component state for " + packageName + "/"
20153                            + className + " to " + newState);
20154                }
20155            }
20156            if (className == null) {
20157                // We're dealing with an application/package level state change
20158                if (pkgSetting.getEnabled(userId) == newState) {
20159                    // Nothing to do
20160                    return;
20161                }
20162                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20163                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20164                    // Don't care about who enables an app.
20165                    callingPackage = null;
20166                }
20167                pkgSetting.setEnabled(newState, userId, callingPackage);
20168                // pkgSetting.pkg.mSetEnabled = newState;
20169            } else {
20170                // We're dealing with a component level state change
20171                // First, verify that this is a valid class name.
20172                PackageParser.Package pkg = pkgSetting.pkg;
20173                if (pkg == null || !pkg.hasComponentClassName(className)) {
20174                    if (pkg != null &&
20175                            pkg.applicationInfo.targetSdkVersion >=
20176                                    Build.VERSION_CODES.JELLY_BEAN) {
20177                        throw new IllegalArgumentException("Component class " + className
20178                                + " does not exist in " + packageName);
20179                    } else {
20180                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20181                                + className + " does not exist in " + packageName);
20182                    }
20183                }
20184                switch (newState) {
20185                case COMPONENT_ENABLED_STATE_ENABLED:
20186                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20187                        return;
20188                    }
20189                    break;
20190                case COMPONENT_ENABLED_STATE_DISABLED:
20191                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20192                        return;
20193                    }
20194                    break;
20195                case COMPONENT_ENABLED_STATE_DEFAULT:
20196                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20197                        return;
20198                    }
20199                    break;
20200                default:
20201                    Slog.e(TAG, "Invalid new component state: " + newState);
20202                    return;
20203                }
20204            }
20205            scheduleWritePackageRestrictionsLocked(userId);
20206            updateSequenceNumberLP(packageName, new int[] { userId });
20207            final long callingId = Binder.clearCallingIdentity();
20208            try {
20209                updateInstantAppInstallerLocked(packageName);
20210            } finally {
20211                Binder.restoreCallingIdentity(callingId);
20212            }
20213            components = mPendingBroadcasts.get(userId, packageName);
20214            final boolean newPackage = components == null;
20215            if (newPackage) {
20216                components = new ArrayList<String>();
20217            }
20218            if (!components.contains(componentName)) {
20219                components.add(componentName);
20220            }
20221            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20222                sendNow = true;
20223                // Purge entry from pending broadcast list if another one exists already
20224                // since we are sending one right away.
20225                mPendingBroadcasts.remove(userId, packageName);
20226            } else {
20227                if (newPackage) {
20228                    mPendingBroadcasts.put(userId, packageName, components);
20229                }
20230                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20231                    // Schedule a message
20232                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20233                }
20234            }
20235        }
20236
20237        long callingId = Binder.clearCallingIdentity();
20238        try {
20239            if (sendNow) {
20240                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20241                sendPackageChangedBroadcast(packageName,
20242                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20243            }
20244        } finally {
20245            Binder.restoreCallingIdentity(callingId);
20246        }
20247    }
20248
20249    @Override
20250    public void flushPackageRestrictionsAsUser(int userId) {
20251        if (!sUserManager.exists(userId)) {
20252            return;
20253        }
20254        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20255                false /* checkShell */, "flushPackageRestrictions");
20256        synchronized (mPackages) {
20257            mSettings.writePackageRestrictionsLPr(userId);
20258            mDirtyUsers.remove(userId);
20259            if (mDirtyUsers.isEmpty()) {
20260                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20261            }
20262        }
20263    }
20264
20265    private void sendPackageChangedBroadcast(String packageName,
20266            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20267        if (DEBUG_INSTALL)
20268            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20269                    + componentNames);
20270        Bundle extras = new Bundle(4);
20271        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20272        String nameList[] = new String[componentNames.size()];
20273        componentNames.toArray(nameList);
20274        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20275        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20276        extras.putInt(Intent.EXTRA_UID, packageUid);
20277        // If this is not reporting a change of the overall package, then only send it
20278        // to registered receivers.  We don't want to launch a swath of apps for every
20279        // little component state change.
20280        final int flags = !componentNames.contains(packageName)
20281                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20282        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20283                new int[] {UserHandle.getUserId(packageUid)});
20284    }
20285
20286    @Override
20287    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20288        if (!sUserManager.exists(userId)) return;
20289        final int uid = Binder.getCallingUid();
20290        final int permission = mContext.checkCallingOrSelfPermission(
20291                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20292        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20293        enforceCrossUserPermission(uid, userId,
20294                true /* requireFullPermission */, true /* checkShell */, "stop package");
20295        // writer
20296        synchronized (mPackages) {
20297            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20298                    allowedByPermission, uid, userId)) {
20299                scheduleWritePackageRestrictionsLocked(userId);
20300            }
20301        }
20302    }
20303
20304    @Override
20305    public String getInstallerPackageName(String packageName) {
20306        // reader
20307        synchronized (mPackages) {
20308            return mSettings.getInstallerPackageNameLPr(packageName);
20309        }
20310    }
20311
20312    public boolean isOrphaned(String packageName) {
20313        // reader
20314        synchronized (mPackages) {
20315            return mSettings.isOrphaned(packageName);
20316        }
20317    }
20318
20319    @Override
20320    public int getApplicationEnabledSetting(String packageName, int userId) {
20321        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20322        int uid = Binder.getCallingUid();
20323        enforceCrossUserPermission(uid, userId,
20324                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20325        // reader
20326        synchronized (mPackages) {
20327            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20328        }
20329    }
20330
20331    @Override
20332    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20333        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20334        int uid = Binder.getCallingUid();
20335        enforceCrossUserPermission(uid, userId,
20336                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20337        // reader
20338        synchronized (mPackages) {
20339            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20340        }
20341    }
20342
20343    @Override
20344    public void enterSafeMode() {
20345        enforceSystemOrRoot("Only the system can request entering safe mode");
20346
20347        if (!mSystemReady) {
20348            mSafeMode = true;
20349        }
20350    }
20351
20352    @Override
20353    public void systemReady() {
20354        mSystemReady = true;
20355        final ContentResolver resolver = mContext.getContentResolver();
20356        ContentObserver co = new ContentObserver(mHandler) {
20357            @Override
20358            public void onChange(boolean selfChange) {
20359                mEphemeralAppsDisabled =
20360                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20361                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20362            }
20363        };
20364        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20365                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20366                false, co, UserHandle.USER_SYSTEM);
20367        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20368                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20369        co.onChange(true);
20370
20371        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20372        // disabled after already being started.
20373        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20374                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20375
20376        // Read the compatibilty setting when the system is ready.
20377        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20378                mContext.getContentResolver(),
20379                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20380        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20381        if (DEBUG_SETTINGS) {
20382            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20383        }
20384
20385        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20386
20387        synchronized (mPackages) {
20388            // Verify that all of the preferred activity components actually
20389            // exist.  It is possible for applications to be updated and at
20390            // that point remove a previously declared activity component that
20391            // had been set as a preferred activity.  We try to clean this up
20392            // the next time we encounter that preferred activity, but it is
20393            // possible for the user flow to never be able to return to that
20394            // situation so here we do a sanity check to make sure we haven't
20395            // left any junk around.
20396            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20397            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20398                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20399                removed.clear();
20400                for (PreferredActivity pa : pir.filterSet()) {
20401                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20402                        removed.add(pa);
20403                    }
20404                }
20405                if (removed.size() > 0) {
20406                    for (int r=0; r<removed.size(); r++) {
20407                        PreferredActivity pa = removed.get(r);
20408                        Slog.w(TAG, "Removing dangling preferred activity: "
20409                                + pa.mPref.mComponent);
20410                        pir.removeFilter(pa);
20411                    }
20412                    mSettings.writePackageRestrictionsLPr(
20413                            mSettings.mPreferredActivities.keyAt(i));
20414                }
20415            }
20416
20417            for (int userId : UserManagerService.getInstance().getUserIds()) {
20418                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20419                    grantPermissionsUserIds = ArrayUtils.appendInt(
20420                            grantPermissionsUserIds, userId);
20421                }
20422            }
20423        }
20424        sUserManager.systemReady();
20425
20426        // If we upgraded grant all default permissions before kicking off.
20427        for (int userId : grantPermissionsUserIds) {
20428            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20429        }
20430
20431        // If we did not grant default permissions, we preload from this the
20432        // default permission exceptions lazily to ensure we don't hit the
20433        // disk on a new user creation.
20434        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20435            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20436        }
20437
20438        // Kick off any messages waiting for system ready
20439        if (mPostSystemReadyMessages != null) {
20440            for (Message msg : mPostSystemReadyMessages) {
20441                msg.sendToTarget();
20442            }
20443            mPostSystemReadyMessages = null;
20444        }
20445
20446        // Watch for external volumes that come and go over time
20447        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20448        storage.registerListener(mStorageListener);
20449
20450        mInstallerService.systemReady();
20451        mPackageDexOptimizer.systemReady();
20452
20453        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20454                StorageManagerInternal.class);
20455        StorageManagerInternal.addExternalStoragePolicy(
20456                new StorageManagerInternal.ExternalStorageMountPolicy() {
20457            @Override
20458            public int getMountMode(int uid, String packageName) {
20459                if (Process.isIsolated(uid)) {
20460                    return Zygote.MOUNT_EXTERNAL_NONE;
20461                }
20462                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20463                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20464                }
20465                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20466                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20467                }
20468                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20469                    return Zygote.MOUNT_EXTERNAL_READ;
20470                }
20471                return Zygote.MOUNT_EXTERNAL_WRITE;
20472            }
20473
20474            @Override
20475            public boolean hasExternalStorage(int uid, String packageName) {
20476                return true;
20477            }
20478        });
20479
20480        // Now that we're mostly running, clean up stale users and apps
20481        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20482        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20483
20484        if (mPrivappPermissionsViolations != null) {
20485            Slog.wtf(TAG,"Signature|privileged permissions not in "
20486                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20487            mPrivappPermissionsViolations = null;
20488        }
20489    }
20490
20491    public void waitForAppDataPrepared() {
20492        if (mPrepareAppDataFuture == null) {
20493            return;
20494        }
20495        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20496        mPrepareAppDataFuture = null;
20497    }
20498
20499    @Override
20500    public boolean isSafeMode() {
20501        return mSafeMode;
20502    }
20503
20504    @Override
20505    public boolean hasSystemUidErrors() {
20506        return mHasSystemUidErrors;
20507    }
20508
20509    static String arrayToString(int[] array) {
20510        StringBuffer buf = new StringBuffer(128);
20511        buf.append('[');
20512        if (array != null) {
20513            for (int i=0; i<array.length; i++) {
20514                if (i > 0) buf.append(", ");
20515                buf.append(array[i]);
20516            }
20517        }
20518        buf.append(']');
20519        return buf.toString();
20520    }
20521
20522    static class DumpState {
20523        public static final int DUMP_LIBS = 1 << 0;
20524        public static final int DUMP_FEATURES = 1 << 1;
20525        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20526        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20527        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20528        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20529        public static final int DUMP_PERMISSIONS = 1 << 6;
20530        public static final int DUMP_PACKAGES = 1 << 7;
20531        public static final int DUMP_SHARED_USERS = 1 << 8;
20532        public static final int DUMP_MESSAGES = 1 << 9;
20533        public static final int DUMP_PROVIDERS = 1 << 10;
20534        public static final int DUMP_VERIFIERS = 1 << 11;
20535        public static final int DUMP_PREFERRED = 1 << 12;
20536        public static final int DUMP_PREFERRED_XML = 1 << 13;
20537        public static final int DUMP_KEYSETS = 1 << 14;
20538        public static final int DUMP_VERSION = 1 << 15;
20539        public static final int DUMP_INSTALLS = 1 << 16;
20540        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20541        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20542        public static final int DUMP_FROZEN = 1 << 19;
20543        public static final int DUMP_DEXOPT = 1 << 20;
20544        public static final int DUMP_COMPILER_STATS = 1 << 21;
20545        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20546
20547        public static final int OPTION_SHOW_FILTERS = 1 << 0;
20548
20549        private int mTypes;
20550
20551        private int mOptions;
20552
20553        private boolean mTitlePrinted;
20554
20555        private SharedUserSetting mSharedUser;
20556
20557        public boolean isDumping(int type) {
20558            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20559                return true;
20560            }
20561
20562            return (mTypes & type) != 0;
20563        }
20564
20565        public void setDump(int type) {
20566            mTypes |= type;
20567        }
20568
20569        public boolean isOptionEnabled(int option) {
20570            return (mOptions & option) != 0;
20571        }
20572
20573        public void setOptionEnabled(int option) {
20574            mOptions |= option;
20575        }
20576
20577        public boolean onTitlePrinted() {
20578            final boolean printed = mTitlePrinted;
20579            mTitlePrinted = true;
20580            return printed;
20581        }
20582
20583        public boolean getTitlePrinted() {
20584            return mTitlePrinted;
20585        }
20586
20587        public void setTitlePrinted(boolean enabled) {
20588            mTitlePrinted = enabled;
20589        }
20590
20591        public SharedUserSetting getSharedUser() {
20592            return mSharedUser;
20593        }
20594
20595        public void setSharedUser(SharedUserSetting user) {
20596            mSharedUser = user;
20597        }
20598    }
20599
20600    @Override
20601    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20602            FileDescriptor err, String[] args, ShellCallback callback,
20603            ResultReceiver resultReceiver) {
20604        (new PackageManagerShellCommand(this)).exec(
20605                this, in, out, err, args, callback, resultReceiver);
20606    }
20607
20608    @Override
20609    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20610        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20611
20612        DumpState dumpState = new DumpState();
20613        boolean fullPreferred = false;
20614        boolean checkin = false;
20615
20616        String packageName = null;
20617        ArraySet<String> permissionNames = null;
20618
20619        int opti = 0;
20620        while (opti < args.length) {
20621            String opt = args[opti];
20622            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20623                break;
20624            }
20625            opti++;
20626
20627            if ("-a".equals(opt)) {
20628                // Right now we only know how to print all.
20629            } else if ("-h".equals(opt)) {
20630                pw.println("Package manager dump options:");
20631                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20632                pw.println("    --checkin: dump for a checkin");
20633                pw.println("    -f: print details of intent filters");
20634                pw.println("    -h: print this help");
20635                pw.println("  cmd may be one of:");
20636                pw.println("    l[ibraries]: list known shared libraries");
20637                pw.println("    f[eatures]: list device features");
20638                pw.println("    k[eysets]: print known keysets");
20639                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20640                pw.println("    perm[issions]: dump permissions");
20641                pw.println("    permission [name ...]: dump declaration and use of given permission");
20642                pw.println("    pref[erred]: print preferred package settings");
20643                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20644                pw.println("    prov[iders]: dump content providers");
20645                pw.println("    p[ackages]: dump installed packages");
20646                pw.println("    s[hared-users]: dump shared user IDs");
20647                pw.println("    m[essages]: print collected runtime messages");
20648                pw.println("    v[erifiers]: print package verifier info");
20649                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20650                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20651                pw.println("    version: print database version info");
20652                pw.println("    write: write current settings now");
20653                pw.println("    installs: details about install sessions");
20654                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20655                pw.println("    dexopt: dump dexopt state");
20656                pw.println("    compiler-stats: dump compiler statistics");
20657                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20658                pw.println("    <package.name>: info about given package");
20659                return;
20660            } else if ("--checkin".equals(opt)) {
20661                checkin = true;
20662            } else if ("-f".equals(opt)) {
20663                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20664            } else if ("--proto".equals(opt)) {
20665                dumpProto(fd);
20666                return;
20667            } else {
20668                pw.println("Unknown argument: " + opt + "; use -h for help");
20669            }
20670        }
20671
20672        // Is the caller requesting to dump a particular piece of data?
20673        if (opti < args.length) {
20674            String cmd = args[opti];
20675            opti++;
20676            // Is this a package name?
20677            if ("android".equals(cmd) || cmd.contains(".")) {
20678                packageName = cmd;
20679                // When dumping a single package, we always dump all of its
20680                // filter information since the amount of data will be reasonable.
20681                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20682            } else if ("check-permission".equals(cmd)) {
20683                if (opti >= args.length) {
20684                    pw.println("Error: check-permission missing permission argument");
20685                    return;
20686                }
20687                String perm = args[opti];
20688                opti++;
20689                if (opti >= args.length) {
20690                    pw.println("Error: check-permission missing package argument");
20691                    return;
20692                }
20693
20694                String pkg = args[opti];
20695                opti++;
20696                int user = UserHandle.getUserId(Binder.getCallingUid());
20697                if (opti < args.length) {
20698                    try {
20699                        user = Integer.parseInt(args[opti]);
20700                    } catch (NumberFormatException e) {
20701                        pw.println("Error: check-permission user argument is not a number: "
20702                                + args[opti]);
20703                        return;
20704                    }
20705                }
20706
20707                // Normalize package name to handle renamed packages and static libs
20708                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20709
20710                pw.println(checkPermission(perm, pkg, user));
20711                return;
20712            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20713                dumpState.setDump(DumpState.DUMP_LIBS);
20714            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20715                dumpState.setDump(DumpState.DUMP_FEATURES);
20716            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20717                if (opti >= args.length) {
20718                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20719                            | DumpState.DUMP_SERVICE_RESOLVERS
20720                            | DumpState.DUMP_RECEIVER_RESOLVERS
20721                            | DumpState.DUMP_CONTENT_RESOLVERS);
20722                } else {
20723                    while (opti < args.length) {
20724                        String name = args[opti];
20725                        if ("a".equals(name) || "activity".equals(name)) {
20726                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20727                        } else if ("s".equals(name) || "service".equals(name)) {
20728                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20729                        } else if ("r".equals(name) || "receiver".equals(name)) {
20730                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20731                        } else if ("c".equals(name) || "content".equals(name)) {
20732                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20733                        } else {
20734                            pw.println("Error: unknown resolver table type: " + name);
20735                            return;
20736                        }
20737                        opti++;
20738                    }
20739                }
20740            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20741                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20742            } else if ("permission".equals(cmd)) {
20743                if (opti >= args.length) {
20744                    pw.println("Error: permission requires permission name");
20745                    return;
20746                }
20747                permissionNames = new ArraySet<>();
20748                while (opti < args.length) {
20749                    permissionNames.add(args[opti]);
20750                    opti++;
20751                }
20752                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20753                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20754            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20755                dumpState.setDump(DumpState.DUMP_PREFERRED);
20756            } else if ("preferred-xml".equals(cmd)) {
20757                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20758                if (opti < args.length && "--full".equals(args[opti])) {
20759                    fullPreferred = true;
20760                    opti++;
20761                }
20762            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20763                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20764            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20765                dumpState.setDump(DumpState.DUMP_PACKAGES);
20766            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20767                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20768            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20769                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20770            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20771                dumpState.setDump(DumpState.DUMP_MESSAGES);
20772            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20773                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20774            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20775                    || "intent-filter-verifiers".equals(cmd)) {
20776                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20777            } else if ("version".equals(cmd)) {
20778                dumpState.setDump(DumpState.DUMP_VERSION);
20779            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20780                dumpState.setDump(DumpState.DUMP_KEYSETS);
20781            } else if ("installs".equals(cmd)) {
20782                dumpState.setDump(DumpState.DUMP_INSTALLS);
20783            } else if ("frozen".equals(cmd)) {
20784                dumpState.setDump(DumpState.DUMP_FROZEN);
20785            } else if ("dexopt".equals(cmd)) {
20786                dumpState.setDump(DumpState.DUMP_DEXOPT);
20787            } else if ("compiler-stats".equals(cmd)) {
20788                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20789            } else if ("enabled-overlays".equals(cmd)) {
20790                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
20791            } else if ("write".equals(cmd)) {
20792                synchronized (mPackages) {
20793                    mSettings.writeLPr();
20794                    pw.println("Settings written.");
20795                    return;
20796                }
20797            }
20798        }
20799
20800        if (checkin) {
20801            pw.println("vers,1");
20802        }
20803
20804        // reader
20805        synchronized (mPackages) {
20806            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20807                if (!checkin) {
20808                    if (dumpState.onTitlePrinted())
20809                        pw.println();
20810                    pw.println("Database versions:");
20811                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20812                }
20813            }
20814
20815            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20816                if (!checkin) {
20817                    if (dumpState.onTitlePrinted())
20818                        pw.println();
20819                    pw.println("Verifiers:");
20820                    pw.print("  Required: ");
20821                    pw.print(mRequiredVerifierPackage);
20822                    pw.print(" (uid=");
20823                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20824                            UserHandle.USER_SYSTEM));
20825                    pw.println(")");
20826                } else if (mRequiredVerifierPackage != null) {
20827                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20828                    pw.print(",");
20829                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20830                            UserHandle.USER_SYSTEM));
20831                }
20832            }
20833
20834            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20835                    packageName == null) {
20836                if (mIntentFilterVerifierComponent != null) {
20837                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20838                    if (!checkin) {
20839                        if (dumpState.onTitlePrinted())
20840                            pw.println();
20841                        pw.println("Intent Filter Verifier:");
20842                        pw.print("  Using: ");
20843                        pw.print(verifierPackageName);
20844                        pw.print(" (uid=");
20845                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20846                                UserHandle.USER_SYSTEM));
20847                        pw.println(")");
20848                    } else if (verifierPackageName != null) {
20849                        pw.print("ifv,"); pw.print(verifierPackageName);
20850                        pw.print(",");
20851                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20852                                UserHandle.USER_SYSTEM));
20853                    }
20854                } else {
20855                    pw.println();
20856                    pw.println("No Intent Filter Verifier available!");
20857                }
20858            }
20859
20860            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20861                boolean printedHeader = false;
20862                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20863                while (it.hasNext()) {
20864                    String libName = it.next();
20865                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20866                    if (versionedLib == null) {
20867                        continue;
20868                    }
20869                    final int versionCount = versionedLib.size();
20870                    for (int i = 0; i < versionCount; i++) {
20871                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20872                        if (!checkin) {
20873                            if (!printedHeader) {
20874                                if (dumpState.onTitlePrinted())
20875                                    pw.println();
20876                                pw.println("Libraries:");
20877                                printedHeader = true;
20878                            }
20879                            pw.print("  ");
20880                        } else {
20881                            pw.print("lib,");
20882                        }
20883                        pw.print(libEntry.info.getName());
20884                        if (libEntry.info.isStatic()) {
20885                            pw.print(" version=" + libEntry.info.getVersion());
20886                        }
20887                        if (!checkin) {
20888                            pw.print(" -> ");
20889                        }
20890                        if (libEntry.path != null) {
20891                            pw.print(" (jar) ");
20892                            pw.print(libEntry.path);
20893                        } else {
20894                            pw.print(" (apk) ");
20895                            pw.print(libEntry.apk);
20896                        }
20897                        pw.println();
20898                    }
20899                }
20900            }
20901
20902            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20903                if (dumpState.onTitlePrinted())
20904                    pw.println();
20905                if (!checkin) {
20906                    pw.println("Features:");
20907                }
20908
20909                synchronized (mAvailableFeatures) {
20910                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20911                        if (checkin) {
20912                            pw.print("feat,");
20913                            pw.print(feat.name);
20914                            pw.print(",");
20915                            pw.println(feat.version);
20916                        } else {
20917                            pw.print("  ");
20918                            pw.print(feat.name);
20919                            if (feat.version > 0) {
20920                                pw.print(" version=");
20921                                pw.print(feat.version);
20922                            }
20923                            pw.println();
20924                        }
20925                    }
20926                }
20927            }
20928
20929            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20930                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20931                        : "Activity Resolver Table:", "  ", packageName,
20932                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20933                    dumpState.setTitlePrinted(true);
20934                }
20935            }
20936            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20937                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20938                        : "Receiver Resolver Table:", "  ", packageName,
20939                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20940                    dumpState.setTitlePrinted(true);
20941                }
20942            }
20943            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20944                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20945                        : "Service Resolver Table:", "  ", packageName,
20946                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20947                    dumpState.setTitlePrinted(true);
20948                }
20949            }
20950            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20951                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20952                        : "Provider Resolver Table:", "  ", packageName,
20953                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20954                    dumpState.setTitlePrinted(true);
20955                }
20956            }
20957
20958            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20959                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20960                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20961                    int user = mSettings.mPreferredActivities.keyAt(i);
20962                    if (pir.dump(pw,
20963                            dumpState.getTitlePrinted()
20964                                ? "\nPreferred Activities User " + user + ":"
20965                                : "Preferred Activities User " + user + ":", "  ",
20966                            packageName, true, false)) {
20967                        dumpState.setTitlePrinted(true);
20968                    }
20969                }
20970            }
20971
20972            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20973                pw.flush();
20974                FileOutputStream fout = new FileOutputStream(fd);
20975                BufferedOutputStream str = new BufferedOutputStream(fout);
20976                XmlSerializer serializer = new FastXmlSerializer();
20977                try {
20978                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20979                    serializer.startDocument(null, true);
20980                    serializer.setFeature(
20981                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20982                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20983                    serializer.endDocument();
20984                    serializer.flush();
20985                } catch (IllegalArgumentException e) {
20986                    pw.println("Failed writing: " + e);
20987                } catch (IllegalStateException e) {
20988                    pw.println("Failed writing: " + e);
20989                } catch (IOException e) {
20990                    pw.println("Failed writing: " + e);
20991                }
20992            }
20993
20994            if (!checkin
20995                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20996                    && packageName == null) {
20997                pw.println();
20998                int count = mSettings.mPackages.size();
20999                if (count == 0) {
21000                    pw.println("No applications!");
21001                    pw.println();
21002                } else {
21003                    final String prefix = "  ";
21004                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21005                    if (allPackageSettings.size() == 0) {
21006                        pw.println("No domain preferred apps!");
21007                        pw.println();
21008                    } else {
21009                        pw.println("App verification status:");
21010                        pw.println();
21011                        count = 0;
21012                        for (PackageSetting ps : allPackageSettings) {
21013                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21014                            if (ivi == null || ivi.getPackageName() == null) continue;
21015                            pw.println(prefix + "Package: " + ivi.getPackageName());
21016                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21017                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21018                            pw.println();
21019                            count++;
21020                        }
21021                        if (count == 0) {
21022                            pw.println(prefix + "No app verification established.");
21023                            pw.println();
21024                        }
21025                        for (int userId : sUserManager.getUserIds()) {
21026                            pw.println("App linkages for user " + userId + ":");
21027                            pw.println();
21028                            count = 0;
21029                            for (PackageSetting ps : allPackageSettings) {
21030                                final long status = ps.getDomainVerificationStatusForUser(userId);
21031                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21032                                        && !DEBUG_DOMAIN_VERIFICATION) {
21033                                    continue;
21034                                }
21035                                pw.println(prefix + "Package: " + ps.name);
21036                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21037                                String statusStr = IntentFilterVerificationInfo.
21038                                        getStatusStringFromValue(status);
21039                                pw.println(prefix + "Status:  " + statusStr);
21040                                pw.println();
21041                                count++;
21042                            }
21043                            if (count == 0) {
21044                                pw.println(prefix + "No configured app linkages.");
21045                                pw.println();
21046                            }
21047                        }
21048                    }
21049                }
21050            }
21051
21052            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21053                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21054                if (packageName == null && permissionNames == null) {
21055                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21056                        if (iperm == 0) {
21057                            if (dumpState.onTitlePrinted())
21058                                pw.println();
21059                            pw.println("AppOp Permissions:");
21060                        }
21061                        pw.print("  AppOp Permission ");
21062                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21063                        pw.println(":");
21064                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21065                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21066                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21067                        }
21068                    }
21069                }
21070            }
21071
21072            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21073                boolean printedSomething = false;
21074                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21075                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21076                        continue;
21077                    }
21078                    if (!printedSomething) {
21079                        if (dumpState.onTitlePrinted())
21080                            pw.println();
21081                        pw.println("Registered ContentProviders:");
21082                        printedSomething = true;
21083                    }
21084                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21085                    pw.print("    "); pw.println(p.toString());
21086                }
21087                printedSomething = false;
21088                for (Map.Entry<String, PackageParser.Provider> entry :
21089                        mProvidersByAuthority.entrySet()) {
21090                    PackageParser.Provider p = entry.getValue();
21091                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21092                        continue;
21093                    }
21094                    if (!printedSomething) {
21095                        if (dumpState.onTitlePrinted())
21096                            pw.println();
21097                        pw.println("ContentProvider Authorities:");
21098                        printedSomething = true;
21099                    }
21100                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21101                    pw.print("    "); pw.println(p.toString());
21102                    if (p.info != null && p.info.applicationInfo != null) {
21103                        final String appInfo = p.info.applicationInfo.toString();
21104                        pw.print("      applicationInfo="); pw.println(appInfo);
21105                    }
21106                }
21107            }
21108
21109            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21110                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21111            }
21112
21113            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21114                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21115            }
21116
21117            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21118                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21119            }
21120
21121            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21122                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21123            }
21124
21125            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21126                // XXX should handle packageName != null by dumping only install data that
21127                // the given package is involved with.
21128                if (dumpState.onTitlePrinted()) pw.println();
21129
21130                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21131                ipw.println();
21132                ipw.println("Frozen packages:");
21133                ipw.increaseIndent();
21134                if (mFrozenPackages.size() == 0) {
21135                    ipw.println("(none)");
21136                } else {
21137                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21138                        ipw.println(mFrozenPackages.valueAt(i));
21139                    }
21140                }
21141                ipw.decreaseIndent();
21142            }
21143
21144            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21145                if (dumpState.onTitlePrinted()) pw.println();
21146                dumpDexoptStateLPr(pw, packageName);
21147            }
21148
21149            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21150                if (dumpState.onTitlePrinted()) pw.println();
21151                dumpCompilerStatsLPr(pw, packageName);
21152            }
21153
21154            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21155                if (dumpState.onTitlePrinted()) pw.println();
21156                dumpEnabledOverlaysLPr(pw);
21157            }
21158
21159            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21160                if (dumpState.onTitlePrinted()) pw.println();
21161                mSettings.dumpReadMessagesLPr(pw, dumpState);
21162
21163                pw.println();
21164                pw.println("Package warning messages:");
21165                BufferedReader in = null;
21166                String line = null;
21167                try {
21168                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21169                    while ((line = in.readLine()) != null) {
21170                        if (line.contains("ignored: updated version")) continue;
21171                        pw.println(line);
21172                    }
21173                } catch (IOException ignored) {
21174                } finally {
21175                    IoUtils.closeQuietly(in);
21176                }
21177            }
21178
21179            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21180                BufferedReader in = null;
21181                String line = null;
21182                try {
21183                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21184                    while ((line = in.readLine()) != null) {
21185                        if (line.contains("ignored: updated version")) continue;
21186                        pw.print("msg,");
21187                        pw.println(line);
21188                    }
21189                } catch (IOException ignored) {
21190                } finally {
21191                    IoUtils.closeQuietly(in);
21192                }
21193            }
21194        }
21195
21196        // PackageInstaller should be called outside of mPackages lock
21197        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21198            // XXX should handle packageName != null by dumping only install data that
21199            // the given package is involved with.
21200            if (dumpState.onTitlePrinted()) pw.println();
21201            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21202        }
21203    }
21204
21205    private void dumpProto(FileDescriptor fd) {
21206        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21207
21208        synchronized (mPackages) {
21209            final long requiredVerifierPackageToken =
21210                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21211            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21212            proto.write(
21213                    PackageServiceDumpProto.PackageShortProto.UID,
21214                    getPackageUid(
21215                            mRequiredVerifierPackage,
21216                            MATCH_DEBUG_TRIAGED_MISSING,
21217                            UserHandle.USER_SYSTEM));
21218            proto.end(requiredVerifierPackageToken);
21219
21220            if (mIntentFilterVerifierComponent != null) {
21221                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21222                final long verifierPackageToken =
21223                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21224                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21225                proto.write(
21226                        PackageServiceDumpProto.PackageShortProto.UID,
21227                        getPackageUid(
21228                                verifierPackageName,
21229                                MATCH_DEBUG_TRIAGED_MISSING,
21230                                UserHandle.USER_SYSTEM));
21231                proto.end(verifierPackageToken);
21232            }
21233
21234            dumpSharedLibrariesProto(proto);
21235            dumpFeaturesProto(proto);
21236            mSettings.dumpPackagesProto(proto);
21237            mSettings.dumpSharedUsersProto(proto);
21238            dumpMessagesProto(proto);
21239        }
21240        proto.flush();
21241    }
21242
21243    private void dumpMessagesProto(ProtoOutputStream proto) {
21244        BufferedReader in = null;
21245        String line = null;
21246        try {
21247            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21248            while ((line = in.readLine()) != null) {
21249                if (line.contains("ignored: updated version")) continue;
21250                proto.write(PackageServiceDumpProto.MESSAGES, line);
21251            }
21252        } catch (IOException ignored) {
21253        } finally {
21254            IoUtils.closeQuietly(in);
21255        }
21256    }
21257
21258    private void dumpFeaturesProto(ProtoOutputStream proto) {
21259        synchronized (mAvailableFeatures) {
21260            final int count = mAvailableFeatures.size();
21261            for (int i = 0; i < count; i++) {
21262                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21263                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21264                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21265                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21266                proto.end(featureToken);
21267            }
21268        }
21269    }
21270
21271    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21272        final int count = mSharedLibraries.size();
21273        for (int i = 0; i < count; i++) {
21274            final String libName = mSharedLibraries.keyAt(i);
21275            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21276            if (versionedLib == null) {
21277                continue;
21278            }
21279            final int versionCount = versionedLib.size();
21280            for (int j = 0; j < versionCount; j++) {
21281                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21282                final long sharedLibraryToken =
21283                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21284                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21285                final boolean isJar = (libEntry.path != null);
21286                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21287                if (isJar) {
21288                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21289                } else {
21290                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21291                }
21292                proto.end(sharedLibraryToken);
21293            }
21294        }
21295    }
21296
21297    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21298        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21299        ipw.println();
21300        ipw.println("Dexopt state:");
21301        ipw.increaseIndent();
21302        Collection<PackageParser.Package> packages = null;
21303        if (packageName != null) {
21304            PackageParser.Package targetPackage = mPackages.get(packageName);
21305            if (targetPackage != null) {
21306                packages = Collections.singletonList(targetPackage);
21307            } else {
21308                ipw.println("Unable to find package: " + packageName);
21309                return;
21310            }
21311        } else {
21312            packages = mPackages.values();
21313        }
21314
21315        for (PackageParser.Package pkg : packages) {
21316            ipw.println("[" + pkg.packageName + "]");
21317            ipw.increaseIndent();
21318            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21319            ipw.decreaseIndent();
21320        }
21321    }
21322
21323    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21324        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21325        ipw.println();
21326        ipw.println("Compiler stats:");
21327        ipw.increaseIndent();
21328        Collection<PackageParser.Package> packages = null;
21329        if (packageName != null) {
21330            PackageParser.Package targetPackage = mPackages.get(packageName);
21331            if (targetPackage != null) {
21332                packages = Collections.singletonList(targetPackage);
21333            } else {
21334                ipw.println("Unable to find package: " + packageName);
21335                return;
21336            }
21337        } else {
21338            packages = mPackages.values();
21339        }
21340
21341        for (PackageParser.Package pkg : packages) {
21342            ipw.println("[" + pkg.packageName + "]");
21343            ipw.increaseIndent();
21344
21345            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21346            if (stats == null) {
21347                ipw.println("(No recorded stats)");
21348            } else {
21349                stats.dump(ipw);
21350            }
21351            ipw.decreaseIndent();
21352        }
21353    }
21354
21355    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21356        pw.println("Enabled overlay paths:");
21357        final int N = mEnabledOverlayPaths.size();
21358        for (int i = 0; i < N; i++) {
21359            final int userId = mEnabledOverlayPaths.keyAt(i);
21360            pw.println(String.format("    User %d:", userId));
21361            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21362                mEnabledOverlayPaths.valueAt(i);
21363            final int M = userSpecificOverlays.size();
21364            for (int j = 0; j < M; j++) {
21365                final String targetPackageName = userSpecificOverlays.keyAt(j);
21366                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21367                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21368            }
21369        }
21370    }
21371
21372    private String dumpDomainString(String packageName) {
21373        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21374                .getList();
21375        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21376
21377        ArraySet<String> result = new ArraySet<>();
21378        if (iviList.size() > 0) {
21379            for (IntentFilterVerificationInfo ivi : iviList) {
21380                for (String host : ivi.getDomains()) {
21381                    result.add(host);
21382                }
21383            }
21384        }
21385        if (filters != null && filters.size() > 0) {
21386            for (IntentFilter filter : filters) {
21387                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21388                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21389                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21390                    result.addAll(filter.getHostsList());
21391                }
21392            }
21393        }
21394
21395        StringBuilder sb = new StringBuilder(result.size() * 16);
21396        for (String domain : result) {
21397            if (sb.length() > 0) sb.append(" ");
21398            sb.append(domain);
21399        }
21400        return sb.toString();
21401    }
21402
21403    // ------- apps on sdcard specific code -------
21404    static final boolean DEBUG_SD_INSTALL = false;
21405
21406    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21407
21408    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21409
21410    private boolean mMediaMounted = false;
21411
21412    static String getEncryptKey() {
21413        try {
21414            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21415                    SD_ENCRYPTION_KEYSTORE_NAME);
21416            if (sdEncKey == null) {
21417                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21418                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21419                if (sdEncKey == null) {
21420                    Slog.e(TAG, "Failed to create encryption keys");
21421                    return null;
21422                }
21423            }
21424            return sdEncKey;
21425        } catch (NoSuchAlgorithmException nsae) {
21426            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21427            return null;
21428        } catch (IOException ioe) {
21429            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21430            return null;
21431        }
21432    }
21433
21434    /*
21435     * Update media status on PackageManager.
21436     */
21437    @Override
21438    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21439        int callingUid = Binder.getCallingUid();
21440        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21441            throw new SecurityException("Media status can only be updated by the system");
21442        }
21443        // reader; this apparently protects mMediaMounted, but should probably
21444        // be a different lock in that case.
21445        synchronized (mPackages) {
21446            Log.i(TAG, "Updating external media status from "
21447                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
21448                    + (mediaStatus ? "mounted" : "unmounted"));
21449            if (DEBUG_SD_INSTALL)
21450                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21451                        + ", mMediaMounted=" + mMediaMounted);
21452            if (mediaStatus == mMediaMounted) {
21453                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21454                        : 0, -1);
21455                mHandler.sendMessage(msg);
21456                return;
21457            }
21458            mMediaMounted = mediaStatus;
21459        }
21460        // Queue up an async operation since the package installation may take a
21461        // little while.
21462        mHandler.post(new Runnable() {
21463            public void run() {
21464                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21465            }
21466        });
21467    }
21468
21469    /**
21470     * Called by StorageManagerService when the initial ASECs to scan are available.
21471     * Should block until all the ASEC containers are finished being scanned.
21472     */
21473    public void scanAvailableAsecs() {
21474        updateExternalMediaStatusInner(true, false, false);
21475    }
21476
21477    /*
21478     * Collect information of applications on external media, map them against
21479     * existing containers and update information based on current mount status.
21480     * Please note that we always have to report status if reportStatus has been
21481     * set to true especially when unloading packages.
21482     */
21483    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21484            boolean externalStorage) {
21485        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21486        int[] uidArr = EmptyArray.INT;
21487
21488        final String[] list = PackageHelper.getSecureContainerList();
21489        if (ArrayUtils.isEmpty(list)) {
21490            Log.i(TAG, "No secure containers found");
21491        } else {
21492            // Process list of secure containers and categorize them
21493            // as active or stale based on their package internal state.
21494
21495            // reader
21496            synchronized (mPackages) {
21497                for (String cid : list) {
21498                    // Leave stages untouched for now; installer service owns them
21499                    if (PackageInstallerService.isStageName(cid)) continue;
21500
21501                    if (DEBUG_SD_INSTALL)
21502                        Log.i(TAG, "Processing container " + cid);
21503                    String pkgName = getAsecPackageName(cid);
21504                    if (pkgName == null) {
21505                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
21506                        continue;
21507                    }
21508                    if (DEBUG_SD_INSTALL)
21509                        Log.i(TAG, "Looking for pkg : " + pkgName);
21510
21511                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
21512                    if (ps == null) {
21513                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21514                        continue;
21515                    }
21516
21517                    /*
21518                     * Skip packages that are not external if we're unmounting
21519                     * external storage.
21520                     */
21521                    if (externalStorage && !isMounted && !isExternal(ps)) {
21522                        continue;
21523                    }
21524
21525                    final AsecInstallArgs args = new AsecInstallArgs(cid,
21526                            getAppDexInstructionSets(ps), ps.isForwardLocked());
21527                    // The package status is changed only if the code path
21528                    // matches between settings and the container id.
21529                    if (ps.codePathString != null
21530                            && ps.codePathString.startsWith(args.getCodePath())) {
21531                        if (DEBUG_SD_INSTALL) {
21532                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21533                                    + " at code path: " + ps.codePathString);
21534                        }
21535
21536                        // We do have a valid package installed on sdcard
21537                        processCids.put(args, ps.codePathString);
21538                        final int uid = ps.appId;
21539                        if (uid != -1) {
21540                            uidArr = ArrayUtils.appendInt(uidArr, uid);
21541                        }
21542                    } else {
21543                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21544                                + ps.codePathString);
21545                    }
21546                }
21547            }
21548
21549            Arrays.sort(uidArr);
21550        }
21551
21552        // Process packages with valid entries.
21553        if (isMounted) {
21554            if (DEBUG_SD_INSTALL)
21555                Log.i(TAG, "Loading packages");
21556            loadMediaPackages(processCids, uidArr, externalStorage);
21557            startCleaningPackages();
21558            mInstallerService.onSecureContainersAvailable();
21559        } else {
21560            if (DEBUG_SD_INSTALL)
21561                Log.i(TAG, "Unloading packages");
21562            unloadMediaPackages(processCids, uidArr, reportStatus);
21563        }
21564    }
21565
21566    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21567            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21568        final int size = infos.size();
21569        final String[] packageNames = new String[size];
21570        final int[] packageUids = new int[size];
21571        for (int i = 0; i < size; i++) {
21572            final ApplicationInfo info = infos.get(i);
21573            packageNames[i] = info.packageName;
21574            packageUids[i] = info.uid;
21575        }
21576        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21577                finishedReceiver);
21578    }
21579
21580    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21581            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21582        sendResourcesChangedBroadcast(mediaStatus, replacing,
21583                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21584    }
21585
21586    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21587            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21588        int size = pkgList.length;
21589        if (size > 0) {
21590            // Send broadcasts here
21591            Bundle extras = new Bundle();
21592            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21593            if (uidArr != null) {
21594                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21595            }
21596            if (replacing) {
21597                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21598            }
21599            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21600                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21601            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21602        }
21603    }
21604
21605   /*
21606     * Look at potentially valid container ids from processCids If package
21607     * information doesn't match the one on record or package scanning fails,
21608     * the cid is added to list of removeCids. We currently don't delete stale
21609     * containers.
21610     */
21611    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
21612            boolean externalStorage) {
21613        ArrayList<String> pkgList = new ArrayList<String>();
21614        Set<AsecInstallArgs> keys = processCids.keySet();
21615
21616        for (AsecInstallArgs args : keys) {
21617            String codePath = processCids.get(args);
21618            if (DEBUG_SD_INSTALL)
21619                Log.i(TAG, "Loading container : " + args.cid);
21620            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
21621            try {
21622                // Make sure there are no container errors first.
21623                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
21624                    Slog.e(TAG, "Failed to mount cid : " + args.cid
21625                            + " when installing from sdcard");
21626                    continue;
21627                }
21628                // Check code path here.
21629                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
21630                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
21631                            + " does not match one in settings " + codePath);
21632                    continue;
21633                }
21634                // Parse package
21635                int parseFlags = mDefParseFlags;
21636                if (args.isExternalAsec()) {
21637                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
21638                }
21639                if (args.isFwdLocked()) {
21640                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
21641                }
21642
21643                synchronized (mInstallLock) {
21644                    PackageParser.Package pkg = null;
21645                    try {
21646                        // Sadly we don't know the package name yet to freeze it
21647                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
21648                                SCAN_IGNORE_FROZEN, 0, null);
21649                    } catch (PackageManagerException e) {
21650                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
21651                    }
21652                    // Scan the package
21653                    if (pkg != null) {
21654                        /*
21655                         * TODO why is the lock being held? doPostInstall is
21656                         * called in other places without the lock. This needs
21657                         * to be straightened out.
21658                         */
21659                        // writer
21660                        synchronized (mPackages) {
21661                            retCode = PackageManager.INSTALL_SUCCEEDED;
21662                            pkgList.add(pkg.packageName);
21663                            // Post process args
21664                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
21665                                    pkg.applicationInfo.uid);
21666                        }
21667                    } else {
21668                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
21669                    }
21670                }
21671
21672            } finally {
21673                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
21674                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
21675                }
21676            }
21677        }
21678        // writer
21679        synchronized (mPackages) {
21680            // If the platform SDK has changed since the last time we booted,
21681            // we need to re-grant app permission to catch any new ones that
21682            // appear. This is really a hack, and means that apps can in some
21683            // cases get permissions that the user didn't initially explicitly
21684            // allow... it would be nice to have some better way to handle
21685            // this situation.
21686            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
21687                    : mSettings.getInternalVersion();
21688            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
21689                    : StorageManager.UUID_PRIVATE_INTERNAL;
21690
21691            int updateFlags = UPDATE_PERMISSIONS_ALL;
21692            if (ver.sdkVersion != mSdkVersion) {
21693                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21694                        + mSdkVersion + "; regranting permissions for external");
21695                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21696            }
21697            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21698
21699            // Yay, everything is now upgraded
21700            ver.forceCurrent();
21701
21702            // can downgrade to reader
21703            // Persist settings
21704            mSettings.writeLPr();
21705        }
21706        // Send a broadcast to let everyone know we are done processing
21707        if (pkgList.size() > 0) {
21708            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
21709        }
21710    }
21711
21712   /*
21713     * Utility method to unload a list of specified containers
21714     */
21715    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
21716        // Just unmount all valid containers.
21717        for (AsecInstallArgs arg : cidArgs) {
21718            synchronized (mInstallLock) {
21719                arg.doPostDeleteLI(false);
21720           }
21721       }
21722   }
21723
21724    /*
21725     * Unload packages mounted on external media. This involves deleting package
21726     * data from internal structures, sending broadcasts about disabled packages,
21727     * gc'ing to free up references, unmounting all secure containers
21728     * corresponding to packages on external media, and posting a
21729     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
21730     * that we always have to post this message if status has been requested no
21731     * matter what.
21732     */
21733    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
21734            final boolean reportStatus) {
21735        if (DEBUG_SD_INSTALL)
21736            Log.i(TAG, "unloading media packages");
21737        ArrayList<String> pkgList = new ArrayList<String>();
21738        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
21739        final Set<AsecInstallArgs> keys = processCids.keySet();
21740        for (AsecInstallArgs args : keys) {
21741            String pkgName = args.getPackageName();
21742            if (DEBUG_SD_INSTALL)
21743                Log.i(TAG, "Trying to unload pkg : " + pkgName);
21744            // Delete package internally
21745            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21746            synchronized (mInstallLock) {
21747                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21748                final boolean res;
21749                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
21750                        "unloadMediaPackages")) {
21751                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
21752                            null);
21753                }
21754                if (res) {
21755                    pkgList.add(pkgName);
21756                } else {
21757                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
21758                    failedList.add(args);
21759                }
21760            }
21761        }
21762
21763        // reader
21764        synchronized (mPackages) {
21765            // We didn't update the settings after removing each package;
21766            // write them now for all packages.
21767            mSettings.writeLPr();
21768        }
21769
21770        // We have to absolutely send UPDATED_MEDIA_STATUS only
21771        // after confirming that all the receivers processed the ordered
21772        // broadcast when packages get disabled, force a gc to clean things up.
21773        // and unload all the containers.
21774        if (pkgList.size() > 0) {
21775            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
21776                    new IIntentReceiver.Stub() {
21777                public void performReceive(Intent intent, int resultCode, String data,
21778                        Bundle extras, boolean ordered, boolean sticky,
21779                        int sendingUser) throws RemoteException {
21780                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
21781                            reportStatus ? 1 : 0, 1, keys);
21782                    mHandler.sendMessage(msg);
21783                }
21784            });
21785        } else {
21786            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
21787                    keys);
21788            mHandler.sendMessage(msg);
21789        }
21790    }
21791
21792    private void loadPrivatePackages(final VolumeInfo vol) {
21793        mHandler.post(new Runnable() {
21794            @Override
21795            public void run() {
21796                loadPrivatePackagesInner(vol);
21797            }
21798        });
21799    }
21800
21801    private void loadPrivatePackagesInner(VolumeInfo vol) {
21802        final String volumeUuid = vol.fsUuid;
21803        if (TextUtils.isEmpty(volumeUuid)) {
21804            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21805            return;
21806        }
21807
21808        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21809        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21810        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21811
21812        final VersionInfo ver;
21813        final List<PackageSetting> packages;
21814        synchronized (mPackages) {
21815            ver = mSettings.findOrCreateVersion(volumeUuid);
21816            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21817        }
21818
21819        for (PackageSetting ps : packages) {
21820            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21821            synchronized (mInstallLock) {
21822                final PackageParser.Package pkg;
21823                try {
21824                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21825                    loaded.add(pkg.applicationInfo);
21826
21827                } catch (PackageManagerException e) {
21828                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21829                }
21830
21831                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21832                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21833                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21834                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21835                }
21836            }
21837        }
21838
21839        // Reconcile app data for all started/unlocked users
21840        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21841        final UserManager um = mContext.getSystemService(UserManager.class);
21842        UserManagerInternal umInternal = getUserManagerInternal();
21843        for (UserInfo user : um.getUsers()) {
21844            final int flags;
21845            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21846                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21847            } else if (umInternal.isUserRunning(user.id)) {
21848                flags = StorageManager.FLAG_STORAGE_DE;
21849            } else {
21850                continue;
21851            }
21852
21853            try {
21854                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21855                synchronized (mInstallLock) {
21856                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21857                }
21858            } catch (IllegalStateException e) {
21859                // Device was probably ejected, and we'll process that event momentarily
21860                Slog.w(TAG, "Failed to prepare storage: " + e);
21861            }
21862        }
21863
21864        synchronized (mPackages) {
21865            int updateFlags = UPDATE_PERMISSIONS_ALL;
21866            if (ver.sdkVersion != mSdkVersion) {
21867                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21868                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21869                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
21870            }
21871            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
21872
21873            // Yay, everything is now upgraded
21874            ver.forceCurrent();
21875
21876            mSettings.writeLPr();
21877        }
21878
21879        for (PackageFreezer freezer : freezers) {
21880            freezer.close();
21881        }
21882
21883        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21884        sendResourcesChangedBroadcast(true, false, loaded, null);
21885    }
21886
21887    private void unloadPrivatePackages(final VolumeInfo vol) {
21888        mHandler.post(new Runnable() {
21889            @Override
21890            public void run() {
21891                unloadPrivatePackagesInner(vol);
21892            }
21893        });
21894    }
21895
21896    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21897        final String volumeUuid = vol.fsUuid;
21898        if (TextUtils.isEmpty(volumeUuid)) {
21899            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21900            return;
21901        }
21902
21903        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21904        synchronized (mInstallLock) {
21905        synchronized (mPackages) {
21906            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21907            for (PackageSetting ps : packages) {
21908                if (ps.pkg == null) continue;
21909
21910                final ApplicationInfo info = ps.pkg.applicationInfo;
21911                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21912                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21913
21914                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21915                        "unloadPrivatePackagesInner")) {
21916                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21917                            false, null)) {
21918                        unloaded.add(info);
21919                    } else {
21920                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21921                    }
21922                }
21923
21924                // Try very hard to release any references to this package
21925                // so we don't risk the system server being killed due to
21926                // open FDs
21927                AttributeCache.instance().removePackage(ps.name);
21928            }
21929
21930            mSettings.writeLPr();
21931        }
21932        }
21933
21934        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21935        sendResourcesChangedBroadcast(false, false, unloaded, null);
21936
21937        // Try very hard to release any references to this path so we don't risk
21938        // the system server being killed due to open FDs
21939        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21940
21941        for (int i = 0; i < 3; i++) {
21942            System.gc();
21943            System.runFinalization();
21944        }
21945    }
21946
21947    private void assertPackageKnown(String volumeUuid, String packageName)
21948            throws PackageManagerException {
21949        synchronized (mPackages) {
21950            // Normalize package name to handle renamed packages
21951            packageName = normalizePackageNameLPr(packageName);
21952
21953            final PackageSetting ps = mSettings.mPackages.get(packageName);
21954            if (ps == null) {
21955                throw new PackageManagerException("Package " + packageName + " is unknown");
21956            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21957                throw new PackageManagerException(
21958                        "Package " + packageName + " found on unknown volume " + volumeUuid
21959                                + "; expected volume " + ps.volumeUuid);
21960            }
21961        }
21962    }
21963
21964    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21965            throws PackageManagerException {
21966        synchronized (mPackages) {
21967            // Normalize package name to handle renamed packages
21968            packageName = normalizePackageNameLPr(packageName);
21969
21970            final PackageSetting ps = mSettings.mPackages.get(packageName);
21971            if (ps == null) {
21972                throw new PackageManagerException("Package " + packageName + " is unknown");
21973            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21974                throw new PackageManagerException(
21975                        "Package " + packageName + " found on unknown volume " + volumeUuid
21976                                + "; expected volume " + ps.volumeUuid);
21977            } else if (!ps.getInstalled(userId)) {
21978                throw new PackageManagerException(
21979                        "Package " + packageName + " not installed for user " + userId);
21980            }
21981        }
21982    }
21983
21984    private List<String> collectAbsoluteCodePaths() {
21985        synchronized (mPackages) {
21986            List<String> codePaths = new ArrayList<>();
21987            final int packageCount = mSettings.mPackages.size();
21988            for (int i = 0; i < packageCount; i++) {
21989                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21990                codePaths.add(ps.codePath.getAbsolutePath());
21991            }
21992            return codePaths;
21993        }
21994    }
21995
21996    /**
21997     * Examine all apps present on given mounted volume, and destroy apps that
21998     * aren't expected, either due to uninstallation or reinstallation on
21999     * another volume.
22000     */
22001    private void reconcileApps(String volumeUuid) {
22002        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22003        List<File> filesToDelete = null;
22004
22005        final File[] files = FileUtils.listFilesOrEmpty(
22006                Environment.getDataAppDirectory(volumeUuid));
22007        for (File file : files) {
22008            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22009                    && !PackageInstallerService.isStageName(file.getName());
22010            if (!isPackage) {
22011                // Ignore entries which are not packages
22012                continue;
22013            }
22014
22015            String absolutePath = file.getAbsolutePath();
22016
22017            boolean pathValid = false;
22018            final int absoluteCodePathCount = absoluteCodePaths.size();
22019            for (int i = 0; i < absoluteCodePathCount; i++) {
22020                String absoluteCodePath = absoluteCodePaths.get(i);
22021                if (absolutePath.startsWith(absoluteCodePath)) {
22022                    pathValid = true;
22023                    break;
22024                }
22025            }
22026
22027            if (!pathValid) {
22028                if (filesToDelete == null) {
22029                    filesToDelete = new ArrayList<>();
22030                }
22031                filesToDelete.add(file);
22032            }
22033        }
22034
22035        if (filesToDelete != null) {
22036            final int fileToDeleteCount = filesToDelete.size();
22037            for (int i = 0; i < fileToDeleteCount; i++) {
22038                File fileToDelete = filesToDelete.get(i);
22039                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22040                synchronized (mInstallLock) {
22041                    removeCodePathLI(fileToDelete);
22042                }
22043            }
22044        }
22045    }
22046
22047    /**
22048     * Reconcile all app data for the given user.
22049     * <p>
22050     * Verifies that directories exist and that ownership and labeling is
22051     * correct for all installed apps on all mounted volumes.
22052     */
22053    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22054        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22055        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22056            final String volumeUuid = vol.getFsUuid();
22057            synchronized (mInstallLock) {
22058                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22059            }
22060        }
22061    }
22062
22063    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22064            boolean migrateAppData) {
22065        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22066    }
22067
22068    /**
22069     * Reconcile all app data on given mounted volume.
22070     * <p>
22071     * Destroys app data that isn't expected, either due to uninstallation or
22072     * reinstallation on another volume.
22073     * <p>
22074     * Verifies that directories exist and that ownership and labeling is
22075     * correct for all installed apps.
22076     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22077     */
22078    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22079            boolean migrateAppData, boolean onlyCoreApps) {
22080        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22081                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22082        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22083
22084        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22085        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22086
22087        // First look for stale data that doesn't belong, and check if things
22088        // have changed since we did our last restorecon
22089        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22090            if (StorageManager.isFileEncryptedNativeOrEmulated()
22091                    && !StorageManager.isUserKeyUnlocked(userId)) {
22092                throw new RuntimeException(
22093                        "Yikes, someone asked us to reconcile CE storage while " + userId
22094                                + " was still locked; this would have caused massive data loss!");
22095            }
22096
22097            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22098            for (File file : files) {
22099                final String packageName = file.getName();
22100                try {
22101                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22102                } catch (PackageManagerException e) {
22103                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22104                    try {
22105                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22106                                StorageManager.FLAG_STORAGE_CE, 0);
22107                    } catch (InstallerException e2) {
22108                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22109                    }
22110                }
22111            }
22112        }
22113        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22114            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22115            for (File file : files) {
22116                final String packageName = file.getName();
22117                try {
22118                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22119                } catch (PackageManagerException e) {
22120                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22121                    try {
22122                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22123                                StorageManager.FLAG_STORAGE_DE, 0);
22124                    } catch (InstallerException e2) {
22125                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22126                    }
22127                }
22128            }
22129        }
22130
22131        // Ensure that data directories are ready to roll for all packages
22132        // installed for this volume and user
22133        final List<PackageSetting> packages;
22134        synchronized (mPackages) {
22135            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22136        }
22137        int preparedCount = 0;
22138        for (PackageSetting ps : packages) {
22139            final String packageName = ps.name;
22140            if (ps.pkg == null) {
22141                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22142                // TODO: might be due to legacy ASEC apps; we should circle back
22143                // and reconcile again once they're scanned
22144                continue;
22145            }
22146            // Skip non-core apps if requested
22147            if (onlyCoreApps && !ps.pkg.coreApp) {
22148                result.add(packageName);
22149                continue;
22150            }
22151
22152            if (ps.getInstalled(userId)) {
22153                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22154                preparedCount++;
22155            }
22156        }
22157
22158        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22159        return result;
22160    }
22161
22162    /**
22163     * Prepare app data for the given app just after it was installed or
22164     * upgraded. This method carefully only touches users that it's installed
22165     * for, and it forces a restorecon to handle any seinfo changes.
22166     * <p>
22167     * Verifies that directories exist and that ownership and labeling is
22168     * correct for all installed apps. If there is an ownership mismatch, it
22169     * will try recovering system apps by wiping data; third-party app data is
22170     * left intact.
22171     * <p>
22172     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22173     */
22174    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22175        final PackageSetting ps;
22176        synchronized (mPackages) {
22177            ps = mSettings.mPackages.get(pkg.packageName);
22178            mSettings.writeKernelMappingLPr(ps);
22179        }
22180
22181        final UserManager um = mContext.getSystemService(UserManager.class);
22182        UserManagerInternal umInternal = getUserManagerInternal();
22183        for (UserInfo user : um.getUsers()) {
22184            final int flags;
22185            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22186                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22187            } else if (umInternal.isUserRunning(user.id)) {
22188                flags = StorageManager.FLAG_STORAGE_DE;
22189            } else {
22190                continue;
22191            }
22192
22193            if (ps.getInstalled(user.id)) {
22194                // TODO: when user data is locked, mark that we're still dirty
22195                prepareAppDataLIF(pkg, user.id, flags);
22196            }
22197        }
22198    }
22199
22200    /**
22201     * Prepare app data for the given app.
22202     * <p>
22203     * Verifies that directories exist and that ownership and labeling is
22204     * correct for all installed apps. If there is an ownership mismatch, this
22205     * will try recovering system apps by wiping data; third-party app data is
22206     * left intact.
22207     */
22208    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22209        if (pkg == null) {
22210            Slog.wtf(TAG, "Package was null!", new Throwable());
22211            return;
22212        }
22213        prepareAppDataLeafLIF(pkg, userId, flags);
22214        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22215        for (int i = 0; i < childCount; i++) {
22216            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22217        }
22218    }
22219
22220    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22221            boolean maybeMigrateAppData) {
22222        prepareAppDataLIF(pkg, userId, flags);
22223
22224        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22225            // We may have just shuffled around app data directories, so
22226            // prepare them one more time
22227            prepareAppDataLIF(pkg, userId, flags);
22228        }
22229    }
22230
22231    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22232        if (DEBUG_APP_DATA) {
22233            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22234                    + Integer.toHexString(flags));
22235        }
22236
22237        final String volumeUuid = pkg.volumeUuid;
22238        final String packageName = pkg.packageName;
22239        final ApplicationInfo app = pkg.applicationInfo;
22240        final int appId = UserHandle.getAppId(app.uid);
22241
22242        Preconditions.checkNotNull(app.seInfo);
22243
22244        long ceDataInode = -1;
22245        try {
22246            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22247                    appId, app.seInfo, app.targetSdkVersion);
22248        } catch (InstallerException e) {
22249            if (app.isSystemApp()) {
22250                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22251                        + ", but trying to recover: " + e);
22252                destroyAppDataLeafLIF(pkg, userId, flags);
22253                try {
22254                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22255                            appId, app.seInfo, app.targetSdkVersion);
22256                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22257                } catch (InstallerException e2) {
22258                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22259                }
22260            } else {
22261                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22262            }
22263        }
22264
22265        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22266            // TODO: mark this structure as dirty so we persist it!
22267            synchronized (mPackages) {
22268                final PackageSetting ps = mSettings.mPackages.get(packageName);
22269                if (ps != null) {
22270                    ps.setCeDataInode(ceDataInode, userId);
22271                }
22272            }
22273        }
22274
22275        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22276    }
22277
22278    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22279        if (pkg == null) {
22280            Slog.wtf(TAG, "Package was null!", new Throwable());
22281            return;
22282        }
22283        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22284        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22285        for (int i = 0; i < childCount; i++) {
22286            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22287        }
22288    }
22289
22290    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22291        final String volumeUuid = pkg.volumeUuid;
22292        final String packageName = pkg.packageName;
22293        final ApplicationInfo app = pkg.applicationInfo;
22294
22295        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22296            // Create a native library symlink only if we have native libraries
22297            // and if the native libraries are 32 bit libraries. We do not provide
22298            // this symlink for 64 bit libraries.
22299            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22300                final String nativeLibPath = app.nativeLibraryDir;
22301                try {
22302                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22303                            nativeLibPath, userId);
22304                } catch (InstallerException e) {
22305                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22306                }
22307            }
22308        }
22309    }
22310
22311    /**
22312     * For system apps on non-FBE devices, this method migrates any existing
22313     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22314     * requested by the app.
22315     */
22316    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22317        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22318                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22319            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22320                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22321            try {
22322                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22323                        storageTarget);
22324            } catch (InstallerException e) {
22325                logCriticalInfo(Log.WARN,
22326                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22327            }
22328            return true;
22329        } else {
22330            return false;
22331        }
22332    }
22333
22334    public PackageFreezer freezePackage(String packageName, String killReason) {
22335        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22336    }
22337
22338    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22339        return new PackageFreezer(packageName, userId, killReason);
22340    }
22341
22342    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22343            String killReason) {
22344        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22345    }
22346
22347    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22348            String killReason) {
22349        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22350            return new PackageFreezer();
22351        } else {
22352            return freezePackage(packageName, userId, killReason);
22353        }
22354    }
22355
22356    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22357            String killReason) {
22358        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22359    }
22360
22361    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22362            String killReason) {
22363        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22364            return new PackageFreezer();
22365        } else {
22366            return freezePackage(packageName, userId, killReason);
22367        }
22368    }
22369
22370    /**
22371     * Class that freezes and kills the given package upon creation, and
22372     * unfreezes it upon closing. This is typically used when doing surgery on
22373     * app code/data to prevent the app from running while you're working.
22374     */
22375    private class PackageFreezer implements AutoCloseable {
22376        private final String mPackageName;
22377        private final PackageFreezer[] mChildren;
22378
22379        private final boolean mWeFroze;
22380
22381        private final AtomicBoolean mClosed = new AtomicBoolean();
22382        private final CloseGuard mCloseGuard = CloseGuard.get();
22383
22384        /**
22385         * Create and return a stub freezer that doesn't actually do anything,
22386         * typically used when someone requested
22387         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22388         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22389         */
22390        public PackageFreezer() {
22391            mPackageName = null;
22392            mChildren = null;
22393            mWeFroze = false;
22394            mCloseGuard.open("close");
22395        }
22396
22397        public PackageFreezer(String packageName, int userId, String killReason) {
22398            synchronized (mPackages) {
22399                mPackageName = packageName;
22400                mWeFroze = mFrozenPackages.add(mPackageName);
22401
22402                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22403                if (ps != null) {
22404                    killApplication(ps.name, ps.appId, userId, killReason);
22405                }
22406
22407                final PackageParser.Package p = mPackages.get(packageName);
22408                if (p != null && p.childPackages != null) {
22409                    final int N = p.childPackages.size();
22410                    mChildren = new PackageFreezer[N];
22411                    for (int i = 0; i < N; i++) {
22412                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22413                                userId, killReason);
22414                    }
22415                } else {
22416                    mChildren = null;
22417                }
22418            }
22419            mCloseGuard.open("close");
22420        }
22421
22422        @Override
22423        protected void finalize() throws Throwable {
22424            try {
22425                mCloseGuard.warnIfOpen();
22426                close();
22427            } finally {
22428                super.finalize();
22429            }
22430        }
22431
22432        @Override
22433        public void close() {
22434            mCloseGuard.close();
22435            if (mClosed.compareAndSet(false, true)) {
22436                synchronized (mPackages) {
22437                    if (mWeFroze) {
22438                        mFrozenPackages.remove(mPackageName);
22439                    }
22440
22441                    if (mChildren != null) {
22442                        for (PackageFreezer freezer : mChildren) {
22443                            freezer.close();
22444                        }
22445                    }
22446                }
22447            }
22448        }
22449    }
22450
22451    /**
22452     * Verify that given package is currently frozen.
22453     */
22454    private void checkPackageFrozen(String packageName) {
22455        synchronized (mPackages) {
22456            if (!mFrozenPackages.contains(packageName)) {
22457                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22458            }
22459        }
22460    }
22461
22462    @Override
22463    public int movePackage(final String packageName, final String volumeUuid) {
22464        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22465
22466        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22467        final int moveId = mNextMoveId.getAndIncrement();
22468        mHandler.post(new Runnable() {
22469            @Override
22470            public void run() {
22471                try {
22472                    movePackageInternal(packageName, volumeUuid, moveId, user);
22473                } catch (PackageManagerException e) {
22474                    Slog.w(TAG, "Failed to move " + packageName, e);
22475                    mMoveCallbacks.notifyStatusChanged(moveId,
22476                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22477                }
22478            }
22479        });
22480        return moveId;
22481    }
22482
22483    private void movePackageInternal(final String packageName, final String volumeUuid,
22484            final int moveId, UserHandle user) throws PackageManagerException {
22485        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22486        final PackageManager pm = mContext.getPackageManager();
22487
22488        final boolean currentAsec;
22489        final String currentVolumeUuid;
22490        final File codeFile;
22491        final String installerPackageName;
22492        final String packageAbiOverride;
22493        final int appId;
22494        final String seinfo;
22495        final String label;
22496        final int targetSdkVersion;
22497        final PackageFreezer freezer;
22498        final int[] installedUserIds;
22499
22500        // reader
22501        synchronized (mPackages) {
22502            final PackageParser.Package pkg = mPackages.get(packageName);
22503            final PackageSetting ps = mSettings.mPackages.get(packageName);
22504            if (pkg == null || ps == null) {
22505                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22506            }
22507
22508            if (pkg.applicationInfo.isSystemApp()) {
22509                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22510                        "Cannot move system application");
22511            }
22512
22513            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22514            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22515                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22516            if (isInternalStorage && !allow3rdPartyOnInternal) {
22517                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22518                        "3rd party apps are not allowed on internal storage");
22519            }
22520
22521            if (pkg.applicationInfo.isExternalAsec()) {
22522                currentAsec = true;
22523                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22524            } else if (pkg.applicationInfo.isForwardLocked()) {
22525                currentAsec = true;
22526                currentVolumeUuid = "forward_locked";
22527            } else {
22528                currentAsec = false;
22529                currentVolumeUuid = ps.volumeUuid;
22530
22531                final File probe = new File(pkg.codePath);
22532                final File probeOat = new File(probe, "oat");
22533                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22534                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22535                            "Move only supported for modern cluster style installs");
22536                }
22537            }
22538
22539            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22540                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22541                        "Package already moved to " + volumeUuid);
22542            }
22543            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22544                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22545                        "Device admin cannot be moved");
22546            }
22547
22548            if (mFrozenPackages.contains(packageName)) {
22549                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22550                        "Failed to move already frozen package");
22551            }
22552
22553            codeFile = new File(pkg.codePath);
22554            installerPackageName = ps.installerPackageName;
22555            packageAbiOverride = ps.cpuAbiOverrideString;
22556            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22557            seinfo = pkg.applicationInfo.seInfo;
22558            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22559            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22560            freezer = freezePackage(packageName, "movePackageInternal");
22561            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22562        }
22563
22564        final Bundle extras = new Bundle();
22565        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22566        extras.putString(Intent.EXTRA_TITLE, label);
22567        mMoveCallbacks.notifyCreated(moveId, extras);
22568
22569        int installFlags;
22570        final boolean moveCompleteApp;
22571        final File measurePath;
22572
22573        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22574            installFlags = INSTALL_INTERNAL;
22575            moveCompleteApp = !currentAsec;
22576            measurePath = Environment.getDataAppDirectory(volumeUuid);
22577        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22578            installFlags = INSTALL_EXTERNAL;
22579            moveCompleteApp = false;
22580            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22581        } else {
22582            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22583            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22584                    || !volume.isMountedWritable()) {
22585                freezer.close();
22586                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22587                        "Move location not mounted private volume");
22588            }
22589
22590            Preconditions.checkState(!currentAsec);
22591
22592            installFlags = INSTALL_INTERNAL;
22593            moveCompleteApp = true;
22594            measurePath = Environment.getDataAppDirectory(volumeUuid);
22595        }
22596
22597        final PackageStats stats = new PackageStats(null, -1);
22598        synchronized (mInstaller) {
22599            for (int userId : installedUserIds) {
22600                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22601                    freezer.close();
22602                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22603                            "Failed to measure package size");
22604                }
22605            }
22606        }
22607
22608        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22609                + stats.dataSize);
22610
22611        final long startFreeBytes = measurePath.getUsableSpace();
22612        final long sizeBytes;
22613        if (moveCompleteApp) {
22614            sizeBytes = stats.codeSize + stats.dataSize;
22615        } else {
22616            sizeBytes = stats.codeSize;
22617        }
22618
22619        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22620            freezer.close();
22621            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22622                    "Not enough free space to move");
22623        }
22624
22625        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22626
22627        final CountDownLatch installedLatch = new CountDownLatch(1);
22628        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22629            @Override
22630            public void onUserActionRequired(Intent intent) throws RemoteException {
22631                throw new IllegalStateException();
22632            }
22633
22634            @Override
22635            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22636                    Bundle extras) throws RemoteException {
22637                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22638                        + PackageManager.installStatusToString(returnCode, msg));
22639
22640                installedLatch.countDown();
22641                freezer.close();
22642
22643                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22644                switch (status) {
22645                    case PackageInstaller.STATUS_SUCCESS:
22646                        mMoveCallbacks.notifyStatusChanged(moveId,
22647                                PackageManager.MOVE_SUCCEEDED);
22648                        break;
22649                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22650                        mMoveCallbacks.notifyStatusChanged(moveId,
22651                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22652                        break;
22653                    default:
22654                        mMoveCallbacks.notifyStatusChanged(moveId,
22655                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22656                        break;
22657                }
22658            }
22659        };
22660
22661        final MoveInfo move;
22662        if (moveCompleteApp) {
22663            // Kick off a thread to report progress estimates
22664            new Thread() {
22665                @Override
22666                public void run() {
22667                    while (true) {
22668                        try {
22669                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22670                                break;
22671                            }
22672                        } catch (InterruptedException ignored) {
22673                        }
22674
22675                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22676                        final int progress = 10 + (int) MathUtils.constrain(
22677                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22678                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22679                    }
22680                }
22681            }.start();
22682
22683            final String dataAppName = codeFile.getName();
22684            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22685                    dataAppName, appId, seinfo, targetSdkVersion);
22686        } else {
22687            move = null;
22688        }
22689
22690        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22691
22692        final Message msg = mHandler.obtainMessage(INIT_COPY);
22693        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22694        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22695                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22696                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22697                PackageManager.INSTALL_REASON_UNKNOWN);
22698        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22699        msg.obj = params;
22700
22701        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22702                System.identityHashCode(msg.obj));
22703        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22704                System.identityHashCode(msg.obj));
22705
22706        mHandler.sendMessage(msg);
22707    }
22708
22709    @Override
22710    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22711        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22712
22713        final int realMoveId = mNextMoveId.getAndIncrement();
22714        final Bundle extras = new Bundle();
22715        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22716        mMoveCallbacks.notifyCreated(realMoveId, extras);
22717
22718        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22719            @Override
22720            public void onCreated(int moveId, Bundle extras) {
22721                // Ignored
22722            }
22723
22724            @Override
22725            public void onStatusChanged(int moveId, int status, long estMillis) {
22726                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22727            }
22728        };
22729
22730        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22731        storage.setPrimaryStorageUuid(volumeUuid, callback);
22732        return realMoveId;
22733    }
22734
22735    @Override
22736    public int getMoveStatus(int moveId) {
22737        mContext.enforceCallingOrSelfPermission(
22738                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22739        return mMoveCallbacks.mLastStatus.get(moveId);
22740    }
22741
22742    @Override
22743    public void registerMoveCallback(IPackageMoveObserver callback) {
22744        mContext.enforceCallingOrSelfPermission(
22745                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22746        mMoveCallbacks.register(callback);
22747    }
22748
22749    @Override
22750    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22751        mContext.enforceCallingOrSelfPermission(
22752                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22753        mMoveCallbacks.unregister(callback);
22754    }
22755
22756    @Override
22757    public boolean setInstallLocation(int loc) {
22758        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22759                null);
22760        if (getInstallLocation() == loc) {
22761            return true;
22762        }
22763        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22764                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22765            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22766                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22767            return true;
22768        }
22769        return false;
22770   }
22771
22772    @Override
22773    public int getInstallLocation() {
22774        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22775                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22776                PackageHelper.APP_INSTALL_AUTO);
22777    }
22778
22779    /** Called by UserManagerService */
22780    void cleanUpUser(UserManagerService userManager, int userHandle) {
22781        synchronized (mPackages) {
22782            mDirtyUsers.remove(userHandle);
22783            mUserNeedsBadging.delete(userHandle);
22784            mSettings.removeUserLPw(userHandle);
22785            mPendingBroadcasts.remove(userHandle);
22786            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22787            removeUnusedPackagesLPw(userManager, userHandle);
22788        }
22789    }
22790
22791    /**
22792     * We're removing userHandle and would like to remove any downloaded packages
22793     * that are no longer in use by any other user.
22794     * @param userHandle the user being removed
22795     */
22796    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22797        final boolean DEBUG_CLEAN_APKS = false;
22798        int [] users = userManager.getUserIds();
22799        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22800        while (psit.hasNext()) {
22801            PackageSetting ps = psit.next();
22802            if (ps.pkg == null) {
22803                continue;
22804            }
22805            final String packageName = ps.pkg.packageName;
22806            // Skip over if system app
22807            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22808                continue;
22809            }
22810            if (DEBUG_CLEAN_APKS) {
22811                Slog.i(TAG, "Checking package " + packageName);
22812            }
22813            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22814            if (keep) {
22815                if (DEBUG_CLEAN_APKS) {
22816                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22817                }
22818            } else {
22819                for (int i = 0; i < users.length; i++) {
22820                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22821                        keep = true;
22822                        if (DEBUG_CLEAN_APKS) {
22823                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22824                                    + users[i]);
22825                        }
22826                        break;
22827                    }
22828                }
22829            }
22830            if (!keep) {
22831                if (DEBUG_CLEAN_APKS) {
22832                    Slog.i(TAG, "  Removing package " + packageName);
22833                }
22834                mHandler.post(new Runnable() {
22835                    public void run() {
22836                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22837                                userHandle, 0);
22838                    } //end run
22839                });
22840            }
22841        }
22842    }
22843
22844    /** Called by UserManagerService */
22845    void createNewUser(int userId, String[] disallowedPackages) {
22846        synchronized (mInstallLock) {
22847            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22848        }
22849        synchronized (mPackages) {
22850            scheduleWritePackageRestrictionsLocked(userId);
22851            scheduleWritePackageListLocked(userId);
22852            applyFactoryDefaultBrowserLPw(userId);
22853            primeDomainVerificationsLPw(userId);
22854        }
22855    }
22856
22857    void onNewUserCreated(final int userId) {
22858        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22859        // If permission review for legacy apps is required, we represent
22860        // dagerous permissions for such apps as always granted runtime
22861        // permissions to keep per user flag state whether review is needed.
22862        // Hence, if a new user is added we have to propagate dangerous
22863        // permission grants for these legacy apps.
22864        if (mPermissionReviewRequired) {
22865            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
22866                    | UPDATE_PERMISSIONS_REPLACE_ALL);
22867        }
22868    }
22869
22870    @Override
22871    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22872        mContext.enforceCallingOrSelfPermission(
22873                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22874                "Only package verification agents can read the verifier device identity");
22875
22876        synchronized (mPackages) {
22877            return mSettings.getVerifierDeviceIdentityLPw();
22878        }
22879    }
22880
22881    @Override
22882    public void setPermissionEnforced(String permission, boolean enforced) {
22883        // TODO: Now that we no longer change GID for storage, this should to away.
22884        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22885                "setPermissionEnforced");
22886        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22887            synchronized (mPackages) {
22888                if (mSettings.mReadExternalStorageEnforced == null
22889                        || mSettings.mReadExternalStorageEnforced != enforced) {
22890                    mSettings.mReadExternalStorageEnforced = enforced;
22891                    mSettings.writeLPr();
22892                }
22893            }
22894            // kill any non-foreground processes so we restart them and
22895            // grant/revoke the GID.
22896            final IActivityManager am = ActivityManager.getService();
22897            if (am != null) {
22898                final long token = Binder.clearCallingIdentity();
22899                try {
22900                    am.killProcessesBelowForeground("setPermissionEnforcement");
22901                } catch (RemoteException e) {
22902                } finally {
22903                    Binder.restoreCallingIdentity(token);
22904                }
22905            }
22906        } else {
22907            throw new IllegalArgumentException("No selective enforcement for " + permission);
22908        }
22909    }
22910
22911    @Override
22912    @Deprecated
22913    public boolean isPermissionEnforced(String permission) {
22914        return true;
22915    }
22916
22917    @Override
22918    public boolean isStorageLow() {
22919        final long token = Binder.clearCallingIdentity();
22920        try {
22921            final DeviceStorageMonitorInternal
22922                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22923            if (dsm != null) {
22924                return dsm.isMemoryLow();
22925            } else {
22926                return false;
22927            }
22928        } finally {
22929            Binder.restoreCallingIdentity(token);
22930        }
22931    }
22932
22933    @Override
22934    public IPackageInstaller getPackageInstaller() {
22935        return mInstallerService;
22936    }
22937
22938    private boolean userNeedsBadging(int userId) {
22939        int index = mUserNeedsBadging.indexOfKey(userId);
22940        if (index < 0) {
22941            final UserInfo userInfo;
22942            final long token = Binder.clearCallingIdentity();
22943            try {
22944                userInfo = sUserManager.getUserInfo(userId);
22945            } finally {
22946                Binder.restoreCallingIdentity(token);
22947            }
22948            final boolean b;
22949            if (userInfo != null && userInfo.isManagedProfile()) {
22950                b = true;
22951            } else {
22952                b = false;
22953            }
22954            mUserNeedsBadging.put(userId, b);
22955            return b;
22956        }
22957        return mUserNeedsBadging.valueAt(index);
22958    }
22959
22960    @Override
22961    public KeySet getKeySetByAlias(String packageName, String alias) {
22962        if (packageName == null || alias == null) {
22963            return null;
22964        }
22965        synchronized(mPackages) {
22966            final PackageParser.Package pkg = mPackages.get(packageName);
22967            if (pkg == null) {
22968                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22969                throw new IllegalArgumentException("Unknown package: " + packageName);
22970            }
22971            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22972            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22973        }
22974    }
22975
22976    @Override
22977    public KeySet getSigningKeySet(String packageName) {
22978        if (packageName == null) {
22979            return null;
22980        }
22981        synchronized(mPackages) {
22982            final PackageParser.Package pkg = mPackages.get(packageName);
22983            if (pkg == null) {
22984                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22985                throw new IllegalArgumentException("Unknown package: " + packageName);
22986            }
22987            if (pkg.applicationInfo.uid != Binder.getCallingUid()
22988                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
22989                throw new SecurityException("May not access signing KeySet of other apps.");
22990            }
22991            KeySetManagerService ksms = mSettings.mKeySetManagerService;
22992            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22993        }
22994    }
22995
22996    @Override
22997    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22998        if (packageName == null || ks == null) {
22999            return false;
23000        }
23001        synchronized(mPackages) {
23002            final PackageParser.Package pkg = mPackages.get(packageName);
23003            if (pkg == null) {
23004                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23005                throw new IllegalArgumentException("Unknown package: " + packageName);
23006            }
23007            IBinder ksh = ks.getToken();
23008            if (ksh instanceof KeySetHandle) {
23009                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23010                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23011            }
23012            return false;
23013        }
23014    }
23015
23016    @Override
23017    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23018        if (packageName == null || ks == null) {
23019            return false;
23020        }
23021        synchronized(mPackages) {
23022            final PackageParser.Package pkg = mPackages.get(packageName);
23023            if (pkg == null) {
23024                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23025                throw new IllegalArgumentException("Unknown package: " + packageName);
23026            }
23027            IBinder ksh = ks.getToken();
23028            if (ksh instanceof KeySetHandle) {
23029                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23030                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23031            }
23032            return false;
23033        }
23034    }
23035
23036    private void deletePackageIfUnusedLPr(final String packageName) {
23037        PackageSetting ps = mSettings.mPackages.get(packageName);
23038        if (ps == null) {
23039            return;
23040        }
23041        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23042            // TODO Implement atomic delete if package is unused
23043            // It is currently possible that the package will be deleted even if it is installed
23044            // after this method returns.
23045            mHandler.post(new Runnable() {
23046                public void run() {
23047                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23048                            0, PackageManager.DELETE_ALL_USERS);
23049                }
23050            });
23051        }
23052    }
23053
23054    /**
23055     * Check and throw if the given before/after packages would be considered a
23056     * downgrade.
23057     */
23058    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23059            throws PackageManagerException {
23060        if (after.versionCode < before.mVersionCode) {
23061            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23062                    "Update version code " + after.versionCode + " is older than current "
23063                    + before.mVersionCode);
23064        } else if (after.versionCode == before.mVersionCode) {
23065            if (after.baseRevisionCode < before.baseRevisionCode) {
23066                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23067                        "Update base revision code " + after.baseRevisionCode
23068                        + " is older than current " + before.baseRevisionCode);
23069            }
23070
23071            if (!ArrayUtils.isEmpty(after.splitNames)) {
23072                for (int i = 0; i < after.splitNames.length; i++) {
23073                    final String splitName = after.splitNames[i];
23074                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23075                    if (j != -1) {
23076                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23077                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23078                                    "Update split " + splitName + " revision code "
23079                                    + after.splitRevisionCodes[i] + " is older than current "
23080                                    + before.splitRevisionCodes[j]);
23081                        }
23082                    }
23083                }
23084            }
23085        }
23086    }
23087
23088    private static class MoveCallbacks extends Handler {
23089        private static final int MSG_CREATED = 1;
23090        private static final int MSG_STATUS_CHANGED = 2;
23091
23092        private final RemoteCallbackList<IPackageMoveObserver>
23093                mCallbacks = new RemoteCallbackList<>();
23094
23095        private final SparseIntArray mLastStatus = new SparseIntArray();
23096
23097        public MoveCallbacks(Looper looper) {
23098            super(looper);
23099        }
23100
23101        public void register(IPackageMoveObserver callback) {
23102            mCallbacks.register(callback);
23103        }
23104
23105        public void unregister(IPackageMoveObserver callback) {
23106            mCallbacks.unregister(callback);
23107        }
23108
23109        @Override
23110        public void handleMessage(Message msg) {
23111            final SomeArgs args = (SomeArgs) msg.obj;
23112            final int n = mCallbacks.beginBroadcast();
23113            for (int i = 0; i < n; i++) {
23114                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23115                try {
23116                    invokeCallback(callback, msg.what, args);
23117                } catch (RemoteException ignored) {
23118                }
23119            }
23120            mCallbacks.finishBroadcast();
23121            args.recycle();
23122        }
23123
23124        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23125                throws RemoteException {
23126            switch (what) {
23127                case MSG_CREATED: {
23128                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23129                    break;
23130                }
23131                case MSG_STATUS_CHANGED: {
23132                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23133                    break;
23134                }
23135            }
23136        }
23137
23138        private void notifyCreated(int moveId, Bundle extras) {
23139            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23140
23141            final SomeArgs args = SomeArgs.obtain();
23142            args.argi1 = moveId;
23143            args.arg2 = extras;
23144            obtainMessage(MSG_CREATED, args).sendToTarget();
23145        }
23146
23147        private void notifyStatusChanged(int moveId, int status) {
23148            notifyStatusChanged(moveId, status, -1);
23149        }
23150
23151        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23152            Slog.v(TAG, "Move " + moveId + " status " + status);
23153
23154            final SomeArgs args = SomeArgs.obtain();
23155            args.argi1 = moveId;
23156            args.argi2 = status;
23157            args.arg3 = estMillis;
23158            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23159
23160            synchronized (mLastStatus) {
23161                mLastStatus.put(moveId, status);
23162            }
23163        }
23164    }
23165
23166    private final static class OnPermissionChangeListeners extends Handler {
23167        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23168
23169        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23170                new RemoteCallbackList<>();
23171
23172        public OnPermissionChangeListeners(Looper looper) {
23173            super(looper);
23174        }
23175
23176        @Override
23177        public void handleMessage(Message msg) {
23178            switch (msg.what) {
23179                case MSG_ON_PERMISSIONS_CHANGED: {
23180                    final int uid = msg.arg1;
23181                    handleOnPermissionsChanged(uid);
23182                } break;
23183            }
23184        }
23185
23186        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23187            mPermissionListeners.register(listener);
23188
23189        }
23190
23191        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23192            mPermissionListeners.unregister(listener);
23193        }
23194
23195        public void onPermissionsChanged(int uid) {
23196            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23197                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23198            }
23199        }
23200
23201        private void handleOnPermissionsChanged(int uid) {
23202            final int count = mPermissionListeners.beginBroadcast();
23203            try {
23204                for (int i = 0; i < count; i++) {
23205                    IOnPermissionsChangeListener callback = mPermissionListeners
23206                            .getBroadcastItem(i);
23207                    try {
23208                        callback.onPermissionsChanged(uid);
23209                    } catch (RemoteException e) {
23210                        Log.e(TAG, "Permission listener is dead", e);
23211                    }
23212                }
23213            } finally {
23214                mPermissionListeners.finishBroadcast();
23215            }
23216        }
23217    }
23218
23219    private class PackageManagerInternalImpl extends PackageManagerInternal {
23220        @Override
23221        public void setLocationPackagesProvider(PackagesProvider provider) {
23222            synchronized (mPackages) {
23223                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23224            }
23225        }
23226
23227        @Override
23228        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23229            synchronized (mPackages) {
23230                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23231            }
23232        }
23233
23234        @Override
23235        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23236            synchronized (mPackages) {
23237                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23238            }
23239        }
23240
23241        @Override
23242        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23243            synchronized (mPackages) {
23244                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23245            }
23246        }
23247
23248        @Override
23249        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23250            synchronized (mPackages) {
23251                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23252            }
23253        }
23254
23255        @Override
23256        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23257            synchronized (mPackages) {
23258                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23259            }
23260        }
23261
23262        @Override
23263        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23264            synchronized (mPackages) {
23265                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23266                        packageName, userId);
23267            }
23268        }
23269
23270        @Override
23271        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23272            synchronized (mPackages) {
23273                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23274                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23275                        packageName, userId);
23276            }
23277        }
23278
23279        @Override
23280        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23281            synchronized (mPackages) {
23282                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23283                        packageName, userId);
23284            }
23285        }
23286
23287        @Override
23288        public void setKeepUninstalledPackages(final List<String> packageList) {
23289            Preconditions.checkNotNull(packageList);
23290            List<String> removedFromList = null;
23291            synchronized (mPackages) {
23292                if (mKeepUninstalledPackages != null) {
23293                    final int packagesCount = mKeepUninstalledPackages.size();
23294                    for (int i = 0; i < packagesCount; i++) {
23295                        String oldPackage = mKeepUninstalledPackages.get(i);
23296                        if (packageList != null && packageList.contains(oldPackage)) {
23297                            continue;
23298                        }
23299                        if (removedFromList == null) {
23300                            removedFromList = new ArrayList<>();
23301                        }
23302                        removedFromList.add(oldPackage);
23303                    }
23304                }
23305                mKeepUninstalledPackages = new ArrayList<>(packageList);
23306                if (removedFromList != null) {
23307                    final int removedCount = removedFromList.size();
23308                    for (int i = 0; i < removedCount; i++) {
23309                        deletePackageIfUnusedLPr(removedFromList.get(i));
23310                    }
23311                }
23312            }
23313        }
23314
23315        @Override
23316        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23317            synchronized (mPackages) {
23318                // If we do not support permission review, done.
23319                if (!mPermissionReviewRequired) {
23320                    return false;
23321                }
23322
23323                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23324                if (packageSetting == null) {
23325                    return false;
23326                }
23327
23328                // Permission review applies only to apps not supporting the new permission model.
23329                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23330                    return false;
23331                }
23332
23333                // Legacy apps have the permission and get user consent on launch.
23334                PermissionsState permissionsState = packageSetting.getPermissionsState();
23335                return permissionsState.isPermissionReviewRequired(userId);
23336            }
23337        }
23338
23339        @Override
23340        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23341            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23342        }
23343
23344        @Override
23345        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23346                int userId) {
23347            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23348        }
23349
23350        @Override
23351        public void setDeviceAndProfileOwnerPackages(
23352                int deviceOwnerUserId, String deviceOwnerPackage,
23353                SparseArray<String> profileOwnerPackages) {
23354            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23355                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23356        }
23357
23358        @Override
23359        public boolean isPackageDataProtected(int userId, String packageName) {
23360            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23361        }
23362
23363        @Override
23364        public boolean isPackageEphemeral(int userId, String packageName) {
23365            synchronized (mPackages) {
23366                final PackageSetting ps = mSettings.mPackages.get(packageName);
23367                return ps != null ? ps.getInstantApp(userId) : false;
23368            }
23369        }
23370
23371        @Override
23372        public boolean wasPackageEverLaunched(String packageName, int userId) {
23373            synchronized (mPackages) {
23374                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23375            }
23376        }
23377
23378        @Override
23379        public void grantRuntimePermission(String packageName, String name, int userId,
23380                boolean overridePolicy) {
23381            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23382                    overridePolicy);
23383        }
23384
23385        @Override
23386        public void revokeRuntimePermission(String packageName, String name, int userId,
23387                boolean overridePolicy) {
23388            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23389                    overridePolicy);
23390        }
23391
23392        @Override
23393        public String getNameForUid(int uid) {
23394            return PackageManagerService.this.getNameForUid(uid);
23395        }
23396
23397        @Override
23398        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23399                Intent origIntent, String resolvedType, String callingPackage, int userId) {
23400            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23401                    responseObj, origIntent, resolvedType, callingPackage, userId);
23402        }
23403
23404        @Override
23405        public void grantEphemeralAccess(int userId, Intent intent,
23406                int targetAppId, int ephemeralAppId) {
23407            synchronized (mPackages) {
23408                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23409                        targetAppId, ephemeralAppId);
23410            }
23411        }
23412
23413        @Override
23414        public boolean isInstantAppInstallerComponent(ComponentName component) {
23415            synchronized (mPackages) {
23416                return mInstantAppInstallerActivity != null
23417                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23418            }
23419        }
23420
23421        @Override
23422        public void pruneInstantApps() {
23423            synchronized (mPackages) {
23424                mInstantAppRegistry.pruneInstantAppsLPw();
23425            }
23426        }
23427
23428        @Override
23429        public String getSetupWizardPackageName() {
23430            return mSetupWizardPackage;
23431        }
23432
23433        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23434            if (policy != null) {
23435                mExternalSourcesPolicy = policy;
23436            }
23437        }
23438
23439        @Override
23440        public boolean isPackagePersistent(String packageName) {
23441            synchronized (mPackages) {
23442                PackageParser.Package pkg = mPackages.get(packageName);
23443                return pkg != null
23444                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23445                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23446                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23447                        : false;
23448            }
23449        }
23450
23451        @Override
23452        public List<PackageInfo> getOverlayPackages(int userId) {
23453            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23454            synchronized (mPackages) {
23455                for (PackageParser.Package p : mPackages.values()) {
23456                    if (p.mOverlayTarget != null) {
23457                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23458                        if (pkg != null) {
23459                            overlayPackages.add(pkg);
23460                        }
23461                    }
23462                }
23463            }
23464            return overlayPackages;
23465        }
23466
23467        @Override
23468        public List<String> getTargetPackageNames(int userId) {
23469            List<String> targetPackages = new ArrayList<>();
23470            synchronized (mPackages) {
23471                for (PackageParser.Package p : mPackages.values()) {
23472                    if (p.mOverlayTarget == null) {
23473                        targetPackages.add(p.packageName);
23474                    }
23475                }
23476            }
23477            return targetPackages;
23478        }
23479
23480        @Override
23481        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23482                @Nullable List<String> overlayPackageNames) {
23483            synchronized (mPackages) {
23484                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23485                    Slog.e(TAG, "failed to find package " + targetPackageName);
23486                    return false;
23487                }
23488
23489                ArrayList<String> paths = null;
23490                if (overlayPackageNames != null) {
23491                    final int N = overlayPackageNames.size();
23492                    paths = new ArrayList<>(N);
23493                    for (int i = 0; i < N; i++) {
23494                        final String packageName = overlayPackageNames.get(i);
23495                        final PackageParser.Package pkg = mPackages.get(packageName);
23496                        if (pkg == null) {
23497                            Slog.e(TAG, "failed to find package " + packageName);
23498                            return false;
23499                        }
23500                        paths.add(pkg.baseCodePath);
23501                    }
23502                }
23503
23504                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23505                    mEnabledOverlayPaths.get(userId);
23506                if (userSpecificOverlays == null) {
23507                    userSpecificOverlays = new ArrayMap<>();
23508                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23509                }
23510
23511                if (paths != null && paths.size() > 0) {
23512                    userSpecificOverlays.put(targetPackageName, paths);
23513                } else {
23514                    userSpecificOverlays.remove(targetPackageName);
23515                }
23516                return true;
23517            }
23518        }
23519
23520        @Override
23521        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23522                int flags, int userId) {
23523            return resolveIntentInternal(
23524                    intent, resolvedType, flags, userId, true /*includeInstantApps*/);
23525        }
23526
23527        @Override
23528        public ResolveInfo resolveService(Intent intent, String resolvedType,
23529                int flags, int userId, int callingUid) {
23530            return resolveServiceInternal(
23531                    intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
23532        }
23533
23534        @Override
23535        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23536            synchronized (mPackages) {
23537                mIsolatedOwners.put(isolatedUid, ownerUid);
23538            }
23539        }
23540
23541        @Override
23542        public void removeIsolatedUid(int isolatedUid) {
23543            synchronized (mPackages) {
23544                mIsolatedOwners.delete(isolatedUid);
23545            }
23546        }
23547
23548        @Override
23549        public int getUidTargetSdkVersion(int uid) {
23550            synchronized (mPackages) {
23551                return getUidTargetSdkVersionLockedLPr(uid);
23552            }
23553        }
23554    }
23555
23556    @Override
23557    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23558        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23559        synchronized (mPackages) {
23560            final long identity = Binder.clearCallingIdentity();
23561            try {
23562                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23563                        packageNames, userId);
23564            } finally {
23565                Binder.restoreCallingIdentity(identity);
23566            }
23567        }
23568    }
23569
23570    @Override
23571    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23572        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23573        synchronized (mPackages) {
23574            final long identity = Binder.clearCallingIdentity();
23575            try {
23576                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23577                        packageNames, userId);
23578            } finally {
23579                Binder.restoreCallingIdentity(identity);
23580            }
23581        }
23582    }
23583
23584    private static void enforceSystemOrPhoneCaller(String tag) {
23585        int callingUid = Binder.getCallingUid();
23586        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23587            throw new SecurityException(
23588                    "Cannot call " + tag + " from UID " + callingUid);
23589        }
23590    }
23591
23592    boolean isHistoricalPackageUsageAvailable() {
23593        return mPackageUsage.isHistoricalPackageUsageAvailable();
23594    }
23595
23596    /**
23597     * Return a <b>copy</b> of the collection of packages known to the package manager.
23598     * @return A copy of the values of mPackages.
23599     */
23600    Collection<PackageParser.Package> getPackages() {
23601        synchronized (mPackages) {
23602            return new ArrayList<>(mPackages.values());
23603        }
23604    }
23605
23606    /**
23607     * Logs process start information (including base APK hash) to the security log.
23608     * @hide
23609     */
23610    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23611            String apkFile, int pid) {
23612        if (!SecurityLog.isLoggingEnabled()) {
23613            return;
23614        }
23615        Bundle data = new Bundle();
23616        data.putLong("startTimestamp", System.currentTimeMillis());
23617        data.putString("processName", processName);
23618        data.putInt("uid", uid);
23619        data.putString("seinfo", seinfo);
23620        data.putString("apkFile", apkFile);
23621        data.putInt("pid", pid);
23622        Message msg = mProcessLoggingHandler.obtainMessage(
23623                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23624        msg.setData(data);
23625        mProcessLoggingHandler.sendMessage(msg);
23626    }
23627
23628    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23629        return mCompilerStats.getPackageStats(pkgName);
23630    }
23631
23632    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23633        return getOrCreateCompilerPackageStats(pkg.packageName);
23634    }
23635
23636    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23637        return mCompilerStats.getOrCreatePackageStats(pkgName);
23638    }
23639
23640    public void deleteCompilerPackageStats(String pkgName) {
23641        mCompilerStats.deletePackageStats(pkgName);
23642    }
23643
23644    @Override
23645    public int getInstallReason(String packageName, int userId) {
23646        enforceCrossUserPermission(Binder.getCallingUid(), userId,
23647                true /* requireFullPermission */, false /* checkShell */,
23648                "get install reason");
23649        synchronized (mPackages) {
23650            final PackageSetting ps = mSettings.mPackages.get(packageName);
23651            if (ps != null) {
23652                return ps.getInstallReason(userId);
23653            }
23654        }
23655        return PackageManager.INSTALL_REASON_UNKNOWN;
23656    }
23657
23658    @Override
23659    public boolean canRequestPackageInstalls(String packageName, int userId) {
23660        int callingUid = Binder.getCallingUid();
23661        int uid = getPackageUid(packageName, 0, userId);
23662        if (callingUid != uid && callingUid != Process.ROOT_UID
23663                && callingUid != Process.SYSTEM_UID) {
23664            throw new SecurityException(
23665                    "Caller uid " + callingUid + " does not own package " + packageName);
23666        }
23667        ApplicationInfo info = getApplicationInfo(packageName, 0, userId);
23668        if (info == null) {
23669            return false;
23670        }
23671        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23672            throw new UnsupportedOperationException(
23673                    "Operation only supported on apps targeting Android O or higher");
23674        }
23675        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23676        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23677        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23678            throw new SecurityException("Need to declare " + appOpPermission + " to call this api");
23679        }
23680        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23681            return false;
23682        }
23683        if (mExternalSourcesPolicy != null) {
23684            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23685            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23686                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23687            }
23688        }
23689        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23690    }
23691
23692    @Override
23693    public ComponentName getInstantAppResolverSettingsComponent() {
23694        return mInstantAppResolverSettingsComponent;
23695    }
23696
23697    @Override
23698    public ComponentName getInstantAppInstallerComponent() {
23699        return mInstantAppInstallerActivity == null
23700                ? null : mInstantAppInstallerActivity.getComponentName();
23701    }
23702
23703    @Override
23704    public String getInstantAppAndroidId(String packageName, int userId) {
23705        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
23706                "getInstantAppAndroidId");
23707        enforceCrossUserPermission(Binder.getCallingUid(), userId,
23708                true /* requireFullPermission */, false /* checkShell */,
23709                "getInstantAppAndroidId");
23710        // Make sure the target is an Instant App.
23711        if (!isInstantApp(packageName, userId)) {
23712            return null;
23713        }
23714        synchronized (mPackages) {
23715            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
23716        }
23717    }
23718}
23719
23720interface PackageSender {
23721    void sendPackageBroadcast(final String action, final String pkg,
23722        final Bundle extras, final int flags, final String targetPkg,
23723        final IIntentReceiver finishedReceiver, final int[] userIds);
23724    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
23725        int appId, int... userIds);
23726}
23727