PackageManagerService.java revision e6393c95716e5ad9bfb52931eb6e4f23f7640f01
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.PermissionsState.PERMISSION_OPERATION_FAILURE;
101import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
102import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
103
104import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
105
106import android.Manifest;
107import android.annotation.NonNull;
108import android.annotation.Nullable;
109import android.app.ActivityManager;
110import android.app.AppOpsManager;
111import android.app.IActivityManager;
112import android.app.ResourcesManager;
113import android.app.admin.IDevicePolicyManager;
114import android.app.admin.SecurityLog;
115import android.app.backup.IBackupManager;
116import android.content.BroadcastReceiver;
117import android.content.ComponentName;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.IIntentReceiver;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.IntentSender.SendIntentException;
125import android.content.ServiceConnection;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.AppsQueryHelper;
129import android.content.pm.ChangedPackages;
130import android.content.pm.ComponentInfo;
131import android.content.pm.InstantAppRequest;
132import android.content.pm.AuxiliaryResolveInfo;
133import android.content.pm.FallbackCategoryProvider;
134import android.content.pm.FeatureInfo;
135import android.content.pm.IOnPermissionsChangeListener;
136import android.content.pm.IPackageDataObserver;
137import android.content.pm.IPackageDeleteObserver;
138import android.content.pm.IPackageDeleteObserver2;
139import android.content.pm.IPackageInstallObserver2;
140import android.content.pm.IPackageInstaller;
141import android.content.pm.IPackageManager;
142import android.content.pm.IPackageMoveObserver;
143import android.content.pm.IPackageStatsObserver;
144import android.content.pm.InstantAppInfo;
145import android.content.pm.InstantAppResolveInfo;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.IntentFilterVerificationInfo;
148import android.content.pm.KeySet;
149import android.content.pm.PackageCleanItem;
150import android.content.pm.PackageInfo;
151import android.content.pm.PackageInfoLite;
152import android.content.pm.PackageInstaller;
153import android.content.pm.PackageManager;
154import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
155import android.content.pm.PackageManagerInternal;
156import android.content.pm.PackageParser;
157import android.content.pm.PackageParser.ActivityIntentInfo;
158import android.content.pm.PackageParser.PackageLite;
159import android.content.pm.PackageParser.PackageParserException;
160import android.content.pm.PackageStats;
161import android.content.pm.PackageUserState;
162import android.content.pm.ParceledListSlice;
163import android.content.pm.PermissionGroupInfo;
164import android.content.pm.PermissionInfo;
165import android.content.pm.ProviderInfo;
166import android.content.pm.ResolveInfo;
167import android.content.pm.ServiceInfo;
168import android.content.pm.SharedLibraryInfo;
169import android.content.pm.Signature;
170import android.content.pm.UserInfo;
171import android.content.pm.VerifierDeviceIdentity;
172import android.content.pm.VerifierInfo;
173import android.content.pm.VersionedPackage;
174import android.content.res.Resources;
175import android.database.ContentObserver;
176import android.graphics.Bitmap;
177import android.hardware.display.DisplayManager;
178import android.net.Uri;
179import android.os.Binder;
180import android.os.Build;
181import android.os.Bundle;
182import android.os.Debug;
183import android.os.Environment;
184import android.os.Environment.UserEnvironment;
185import android.os.FileUtils;
186import android.os.Handler;
187import android.os.IBinder;
188import android.os.Looper;
189import android.os.Message;
190import android.os.Parcel;
191import android.os.ParcelFileDescriptor;
192import android.os.PatternMatcher;
193import android.os.Process;
194import android.os.RemoteCallbackList;
195import android.os.RemoteException;
196import android.os.ResultReceiver;
197import android.os.SELinux;
198import android.os.ServiceManager;
199import android.os.ShellCallback;
200import android.os.SystemClock;
201import android.os.SystemProperties;
202import android.os.Trace;
203import android.os.UserHandle;
204import android.os.UserManager;
205import android.os.UserManagerInternal;
206import android.os.storage.IStorageManager;
207import android.os.storage.StorageEventListener;
208import android.os.storage.StorageManager;
209import android.os.storage.StorageManagerInternal;
210import android.os.storage.VolumeInfo;
211import android.os.storage.VolumeRecord;
212import android.provider.Settings.Global;
213import android.provider.Settings.Secure;
214import android.security.KeyStore;
215import android.security.SystemKeyStore;
216import android.service.pm.PackageServiceDumpProto;
217import android.system.ErrnoException;
218import android.system.Os;
219import android.text.TextUtils;
220import android.text.format.DateUtils;
221import android.util.ArrayMap;
222import android.util.ArraySet;
223import android.util.Base64;
224import android.util.BootTimingsTraceLog;
225import android.util.DisplayMetrics;
226import android.util.EventLog;
227import android.util.ExceptionUtils;
228import android.util.Log;
229import android.util.LogPrinter;
230import android.util.MathUtils;
231import android.util.PackageUtils;
232import android.util.Pair;
233import android.util.PrintStreamPrinter;
234import android.util.Slog;
235import android.util.SparseArray;
236import android.util.SparseBooleanArray;
237import android.util.SparseIntArray;
238import android.util.Xml;
239import android.util.jar.StrictJarFile;
240import android.util.proto.ProtoOutputStream;
241import android.view.Display;
242
243import com.android.internal.R;
244import com.android.internal.annotations.GuardedBy;
245import com.android.internal.app.IMediaContainerService;
246import com.android.internal.app.ResolverActivity;
247import com.android.internal.content.NativeLibraryHelper;
248import com.android.internal.content.PackageHelper;
249import com.android.internal.logging.MetricsLogger;
250import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
251import com.android.internal.os.IParcelFileDescriptorFactory;
252import com.android.internal.os.RoSystemProperties;
253import com.android.internal.os.SomeArgs;
254import com.android.internal.os.Zygote;
255import com.android.internal.telephony.CarrierAppUtils;
256import com.android.internal.util.ArrayUtils;
257import com.android.internal.util.ConcurrentUtils;
258import com.android.internal.util.DumpUtils;
259import com.android.internal.util.FastPrintWriter;
260import com.android.internal.util.FastXmlSerializer;
261import com.android.internal.util.IndentingPrintWriter;
262import com.android.internal.util.Preconditions;
263import com.android.internal.util.XmlUtils;
264import com.android.server.AttributeCache;
265import com.android.server.DeviceIdleController;
266import com.android.server.EventLogTags;
267import com.android.server.FgThread;
268import com.android.server.IntentResolver;
269import com.android.server.LocalServices;
270import com.android.server.LockGuard;
271import com.android.server.ServiceThread;
272import com.android.server.SystemConfig;
273import com.android.server.SystemServerInitThreadPool;
274import com.android.server.Watchdog;
275import com.android.server.net.NetworkPolicyManagerInternal;
276import com.android.server.pm.Installer.InstallerException;
277import com.android.server.pm.PermissionsState.PermissionState;
278import com.android.server.pm.Settings.DatabaseVersion;
279import com.android.server.pm.Settings.VersionInfo;
280import com.android.server.pm.dex.DexManager;
281import com.android.server.storage.DeviceStorageMonitorInternal;
282
283import dalvik.system.CloseGuard;
284import dalvik.system.DexFile;
285import dalvik.system.VMRuntime;
286
287import libcore.io.IoUtils;
288import libcore.util.EmptyArray;
289
290import org.xmlpull.v1.XmlPullParser;
291import org.xmlpull.v1.XmlPullParserException;
292import org.xmlpull.v1.XmlSerializer;
293
294import java.io.BufferedOutputStream;
295import java.io.BufferedReader;
296import java.io.ByteArrayInputStream;
297import java.io.ByteArrayOutputStream;
298import java.io.File;
299import java.io.FileDescriptor;
300import java.io.FileInputStream;
301import java.io.FileOutputStream;
302import java.io.FileReader;
303import java.io.FilenameFilter;
304import java.io.IOException;
305import java.io.PrintWriter;
306import java.nio.charset.StandardCharsets;
307import java.security.DigestInputStream;
308import java.security.MessageDigest;
309import java.security.NoSuchAlgorithmException;
310import java.security.PublicKey;
311import java.security.SecureRandom;
312import java.security.cert.Certificate;
313import java.security.cert.CertificateEncodingException;
314import java.security.cert.CertificateException;
315import java.text.SimpleDateFormat;
316import java.util.ArrayList;
317import java.util.Arrays;
318import java.util.Collection;
319import java.util.Collections;
320import java.util.Comparator;
321import java.util.Date;
322import java.util.HashMap;
323import java.util.HashSet;
324import java.util.Iterator;
325import java.util.List;
326import java.util.Map;
327import java.util.Objects;
328import java.util.Set;
329import java.util.concurrent.CountDownLatch;
330import java.util.concurrent.Future;
331import java.util.concurrent.TimeUnit;
332import java.util.concurrent.atomic.AtomicBoolean;
333import java.util.concurrent.atomic.AtomicInteger;
334
335/**
336 * Keep track of all those APKs everywhere.
337 * <p>
338 * Internally there are two important locks:
339 * <ul>
340 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
341 * and other related state. It is a fine-grained lock that should only be held
342 * momentarily, as it's one of the most contended locks in the system.
343 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
344 * operations typically involve heavy lifting of application data on disk. Since
345 * {@code installd} is single-threaded, and it's operations can often be slow,
346 * this lock should never be acquired while already holding {@link #mPackages}.
347 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
348 * holding {@link #mInstallLock}.
349 * </ul>
350 * Many internal methods rely on the caller to hold the appropriate locks, and
351 * this contract is expressed through method name suffixes:
352 * <ul>
353 * <li>fooLI(): the caller must hold {@link #mInstallLock}
354 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
355 * being modified must be frozen
356 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
357 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
358 * </ul>
359 * <p>
360 * Because this class is very central to the platform's security; please run all
361 * CTS and unit tests whenever making modifications:
362 *
363 * <pre>
364 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
365 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
366 * </pre>
367 */
368public class PackageManagerService extends IPackageManager.Stub
369        implements PackageSender {
370    static final String TAG = "PackageManager";
371    static final boolean DEBUG_SETTINGS = false;
372    static final boolean DEBUG_PREFERRED = false;
373    static final boolean DEBUG_UPGRADE = false;
374    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
375    private static final boolean DEBUG_BACKUP = false;
376    private static final boolean DEBUG_INSTALL = false;
377    private static final boolean DEBUG_REMOVE = false;
378    private static final boolean DEBUG_BROADCASTS = false;
379    private static final boolean DEBUG_SHOW_INFO = false;
380    private static final boolean DEBUG_PACKAGE_INFO = false;
381    private static final boolean DEBUG_INTENT_MATCHING = false;
382    private static final boolean DEBUG_PACKAGE_SCANNING = false;
383    private static final boolean DEBUG_VERIFY = false;
384    private static final boolean DEBUG_FILTERS = false;
385    private static final boolean DEBUG_PERMISSIONS = false;
386    private static final boolean DEBUG_SHARED_LIBRARIES = false;
387
388    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
389    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
390    // user, but by default initialize to this.
391    public static final boolean DEBUG_DEXOPT = false;
392
393    private static final boolean DEBUG_ABI_SELECTION = false;
394    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
395    private static final boolean DEBUG_TRIAGED_MISSING = false;
396    private static final boolean DEBUG_APP_DATA = false;
397
398    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
399    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
400
401    private static final boolean HIDE_EPHEMERAL_APIS = false;
402
403    private static final boolean ENABLE_FREE_CACHE_V2 =
404            SystemProperties.getBoolean("fw.free_cache_v2", true);
405
406    private static final int RADIO_UID = Process.PHONE_UID;
407    private static final int LOG_UID = Process.LOG_UID;
408    private static final int NFC_UID = Process.NFC_UID;
409    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
410    private static final int SHELL_UID = Process.SHELL_UID;
411
412    // Cap the size of permission trees that 3rd party apps can define
413    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
414
415    // Suffix used during package installation when copying/moving
416    // package apks to install directory.
417    private static final String INSTALL_PACKAGE_SUFFIX = "-";
418
419    static final int SCAN_NO_DEX = 1<<1;
420    static final int SCAN_FORCE_DEX = 1<<2;
421    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
422    static final int SCAN_NEW_INSTALL = 1<<4;
423    static final int SCAN_UPDATE_TIME = 1<<5;
424    static final int SCAN_BOOTING = 1<<6;
425    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
426    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
427    static final int SCAN_REPLACING = 1<<9;
428    static final int SCAN_REQUIRE_KNOWN = 1<<10;
429    static final int SCAN_MOVE = 1<<11;
430    static final int SCAN_INITIAL = 1<<12;
431    static final int SCAN_CHECK_ONLY = 1<<13;
432    static final int SCAN_DONT_KILL_APP = 1<<14;
433    static final int SCAN_IGNORE_FROZEN = 1<<15;
434    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
435    static final int SCAN_AS_INSTANT_APP = 1<<17;
436    static final int SCAN_AS_FULL_APP = 1<<18;
437    /** Should not be with the scan flags */
438    static final int FLAGS_REMOVE_CHATTY = 1<<31;
439
440    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
441
442    private static final int[] EMPTY_INT_ARRAY = new int[0];
443
444    /**
445     * Timeout (in milliseconds) after which the watchdog should declare that
446     * our handler thread is wedged.  The usual default for such things is one
447     * minute but we sometimes do very lengthy I/O operations on this thread,
448     * such as installing multi-gigabyte applications, so ours needs to be longer.
449     */
450    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
451
452    /**
453     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
454     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
455     * settings entry if available, otherwise we use the hardcoded default.  If it's been
456     * more than this long since the last fstrim, we force one during the boot sequence.
457     *
458     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
459     * one gets run at the next available charging+idle time.  This final mandatory
460     * no-fstrim check kicks in only of the other scheduling criteria is never met.
461     */
462    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
463
464    /**
465     * Whether verification is enabled by default.
466     */
467    private static final boolean DEFAULT_VERIFY_ENABLE = true;
468
469    /**
470     * The default maximum time to wait for the verification agent to return in
471     * milliseconds.
472     */
473    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
474
475    /**
476     * The default response for package verification timeout.
477     *
478     * This can be either PackageManager.VERIFICATION_ALLOW or
479     * PackageManager.VERIFICATION_REJECT.
480     */
481    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
482
483    static final String PLATFORM_PACKAGE_NAME = "android";
484
485    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
486
487    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
488            DEFAULT_CONTAINER_PACKAGE,
489            "com.android.defcontainer.DefaultContainerService");
490
491    private static final String KILL_APP_REASON_GIDS_CHANGED =
492            "permission grant or revoke changed gids";
493
494    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
495            "permissions revoked";
496
497    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
498
499    private static final String PACKAGE_SCHEME = "package";
500
501    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
502
503    /** Permission grant: not grant the permission. */
504    private static final int GRANT_DENIED = 1;
505
506    /** Permission grant: grant the permission as an install permission. */
507    private static final int GRANT_INSTALL = 2;
508
509    /** Permission grant: grant the permission as a runtime one. */
510    private static final int GRANT_RUNTIME = 3;
511
512    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
513    private static final int GRANT_UPGRADE = 4;
514
515    /** Canonical intent used to identify what counts as a "web browser" app */
516    private static final Intent sBrowserIntent;
517    static {
518        sBrowserIntent = new Intent();
519        sBrowserIntent.setAction(Intent.ACTION_VIEW);
520        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
521        sBrowserIntent.setData(Uri.parse("http:"));
522    }
523
524    /**
525     * The set of all protected actions [i.e. those actions for which a high priority
526     * intent filter is disallowed].
527     */
528    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
529    static {
530        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
531        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
532        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
533        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
534    }
535
536    // Compilation reasons.
537    public static final int REASON_FIRST_BOOT = 0;
538    public static final int REASON_BOOT = 1;
539    public static final int REASON_INSTALL = 2;
540    public static final int REASON_BACKGROUND_DEXOPT = 3;
541    public static final int REASON_AB_OTA = 4;
542
543    public static final int REASON_LAST = REASON_AB_OTA;
544
545    /** All dangerous permission names in the same order as the events in MetricsEvent */
546    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
547            Manifest.permission.READ_CALENDAR,
548            Manifest.permission.WRITE_CALENDAR,
549            Manifest.permission.CAMERA,
550            Manifest.permission.READ_CONTACTS,
551            Manifest.permission.WRITE_CONTACTS,
552            Manifest.permission.GET_ACCOUNTS,
553            Manifest.permission.ACCESS_FINE_LOCATION,
554            Manifest.permission.ACCESS_COARSE_LOCATION,
555            Manifest.permission.RECORD_AUDIO,
556            Manifest.permission.READ_PHONE_STATE,
557            Manifest.permission.CALL_PHONE,
558            Manifest.permission.READ_CALL_LOG,
559            Manifest.permission.WRITE_CALL_LOG,
560            Manifest.permission.ADD_VOICEMAIL,
561            Manifest.permission.USE_SIP,
562            Manifest.permission.PROCESS_OUTGOING_CALLS,
563            Manifest.permission.READ_CELL_BROADCASTS,
564            Manifest.permission.BODY_SENSORS,
565            Manifest.permission.SEND_SMS,
566            Manifest.permission.RECEIVE_SMS,
567            Manifest.permission.READ_SMS,
568            Manifest.permission.RECEIVE_WAP_PUSH,
569            Manifest.permission.RECEIVE_MMS,
570            Manifest.permission.READ_EXTERNAL_STORAGE,
571            Manifest.permission.WRITE_EXTERNAL_STORAGE,
572            Manifest.permission.READ_PHONE_NUMBERS,
573            Manifest.permission.ANSWER_PHONE_CALLS);
574
575
576    /**
577     * Version number for the package parser cache. Increment this whenever the format or
578     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
579     */
580    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
581
582    /**
583     * Whether the package parser cache is enabled.
584     */
585    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
586
587    final ServiceThread mHandlerThread;
588
589    final PackageHandler mHandler;
590
591    private final ProcessLoggingHandler mProcessLoggingHandler;
592
593    /**
594     * Messages for {@link #mHandler} that need to wait for system ready before
595     * being dispatched.
596     */
597    private ArrayList<Message> mPostSystemReadyMessages;
598
599    final int mSdkVersion = Build.VERSION.SDK_INT;
600
601    final Context mContext;
602    final boolean mFactoryTest;
603    final boolean mOnlyCore;
604    final DisplayMetrics mMetrics;
605    final int mDefParseFlags;
606    final String[] mSeparateProcesses;
607    final boolean mIsUpgrade;
608    final boolean mIsPreNUpgrade;
609    final boolean mIsPreNMR1Upgrade;
610
611    // Have we told the Activity Manager to whitelist the default container service by uid yet?
612    @GuardedBy("mPackages")
613    boolean mDefaultContainerWhitelisted = false;
614
615    @GuardedBy("mPackages")
616    private boolean mDexOptDialogShown;
617
618    /** The location for ASEC container files on internal storage. */
619    final String mAsecInternalPath;
620
621    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
622    // LOCK HELD.  Can be called with mInstallLock held.
623    @GuardedBy("mInstallLock")
624    final Installer mInstaller;
625
626    /** Directory where installed third-party apps stored */
627    final File mAppInstallDir;
628
629    /**
630     * Directory to which applications installed internally have their
631     * 32 bit native libraries copied.
632     */
633    private File mAppLib32InstallDir;
634
635    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
636    // apps.
637    final File mDrmAppPrivateInstallDir;
638
639    // ----------------------------------------------------------------
640
641    // Lock for state used when installing and doing other long running
642    // operations.  Methods that must be called with this lock held have
643    // the suffix "LI".
644    final Object mInstallLock = new Object();
645
646    // ----------------------------------------------------------------
647
648    // Keys are String (package name), values are Package.  This also serves
649    // as the lock for the global state.  Methods that must be called with
650    // this lock held have the prefix "LP".
651    @GuardedBy("mPackages")
652    final ArrayMap<String, PackageParser.Package> mPackages =
653            new ArrayMap<String, PackageParser.Package>();
654
655    final ArrayMap<String, Set<String>> mKnownCodebase =
656            new ArrayMap<String, Set<String>>();
657
658    // Keys are isolated uids and values are the uid of the application
659    // that created the isolated proccess.
660    @GuardedBy("mPackages")
661    final SparseIntArray mIsolatedOwners = new SparseIntArray();
662
663    // List of APK paths to load for each user and package. This data is never
664    // persisted by the package manager. Instead, the overlay manager will
665    // ensure the data is up-to-date in runtime.
666    @GuardedBy("mPackages")
667    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
668        new SparseArray<ArrayMap<String, ArrayList<String>>>();
669
670    /**
671     * Tracks new system packages [received in an OTA] that we expect to
672     * find updated user-installed versions. Keys are package name, values
673     * are package location.
674     */
675    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
676    /**
677     * Tracks high priority intent filters for protected actions. During boot, certain
678     * filter actions are protected and should never be allowed to have a high priority
679     * intent filter for them. However, there is one, and only one exception -- the
680     * setup wizard. It must be able to define a high priority intent filter for these
681     * actions to ensure there are no escapes from the wizard. We need to delay processing
682     * of these during boot as we need to look at all of the system packages in order
683     * to know which component is the setup wizard.
684     */
685    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
686    /**
687     * Whether or not processing protected filters should be deferred.
688     */
689    private boolean mDeferProtectedFilters = true;
690
691    /**
692     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
693     */
694    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
695    /**
696     * Whether or not system app permissions should be promoted from install to runtime.
697     */
698    boolean mPromoteSystemApps;
699
700    @GuardedBy("mPackages")
701    final Settings mSettings;
702
703    /**
704     * Set of package names that are currently "frozen", which means active
705     * surgery is being done on the code/data for that package. The platform
706     * will refuse to launch frozen packages to avoid race conditions.
707     *
708     * @see PackageFreezer
709     */
710    @GuardedBy("mPackages")
711    final ArraySet<String> mFrozenPackages = new ArraySet<>();
712
713    final ProtectedPackages mProtectedPackages;
714
715    boolean mFirstBoot;
716
717    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
718
719    // System configuration read by SystemConfig.
720    final int[] mGlobalGids;
721    final SparseArray<ArraySet<String>> mSystemPermissions;
722    @GuardedBy("mAvailableFeatures")
723    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
724
725    // If mac_permissions.xml was found for seinfo labeling.
726    boolean mFoundPolicyFile;
727
728    private final InstantAppRegistry mInstantAppRegistry;
729
730    @GuardedBy("mPackages")
731    int mChangedPackagesSequenceNumber;
732    /**
733     * List of changed [installed, removed or updated] packages.
734     * mapping from user id -> sequence number -> package name
735     */
736    @GuardedBy("mPackages")
737    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
738    /**
739     * The sequence number of the last change to a package.
740     * mapping from user id -> package name -> sequence number
741     */
742    @GuardedBy("mPackages")
743    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
744
745    class PackageParserCallback implements PackageParser.Callback {
746        @Override public final boolean hasFeature(String feature) {
747            return PackageManagerService.this.hasSystemFeature(feature, 0);
748        }
749
750        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
751                Collection<PackageParser.Package> allPackages, String targetPackageName) {
752            List<PackageParser.Package> overlayPackages = null;
753            for (PackageParser.Package p : allPackages) {
754                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
755                    if (overlayPackages == null) {
756                        overlayPackages = new ArrayList<PackageParser.Package>();
757                    }
758                    overlayPackages.add(p);
759                }
760            }
761            if (overlayPackages != null) {
762                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
763                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
764                        return p1.mOverlayPriority - p2.mOverlayPriority;
765                    }
766                };
767                Collections.sort(overlayPackages, cmp);
768            }
769            return overlayPackages;
770        }
771
772        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
773                String targetPackageName, String targetPath) {
774            if ("android".equals(targetPackageName)) {
775                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
776                // native AssetManager.
777                return null;
778            }
779            List<PackageParser.Package> overlayPackages =
780                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
781            if (overlayPackages == null || overlayPackages.isEmpty()) {
782                return null;
783            }
784            List<String> overlayPathList = null;
785            for (PackageParser.Package overlayPackage : overlayPackages) {
786                if (targetPath == null) {
787                    if (overlayPathList == null) {
788                        overlayPathList = new ArrayList<String>();
789                    }
790                    overlayPathList.add(overlayPackage.baseCodePath);
791                    continue;
792                }
793
794                try {
795                    // Creates idmaps for system to parse correctly the Android manifest of the
796                    // target package.
797                    //
798                    // OverlayManagerService will update each of them with a correct gid from its
799                    // target package app id.
800                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
801                            UserHandle.getSharedAppGid(
802                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
803                    if (overlayPathList == null) {
804                        overlayPathList = new ArrayList<String>();
805                    }
806                    overlayPathList.add(overlayPackage.baseCodePath);
807                } catch (InstallerException e) {
808                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
809                            overlayPackage.baseCodePath);
810                }
811            }
812            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
813        }
814
815        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
816            synchronized (mPackages) {
817                return getStaticOverlayPathsLocked(
818                        mPackages.values(), targetPackageName, targetPath);
819            }
820        }
821
822        @Override public final String[] getOverlayApks(String targetPackageName) {
823            return getStaticOverlayPaths(targetPackageName, null);
824        }
825
826        @Override public final String[] getOverlayPaths(String targetPackageName,
827                String targetPath) {
828            return getStaticOverlayPaths(targetPackageName, targetPath);
829        }
830    };
831
832    class ParallelPackageParserCallback extends PackageParserCallback {
833        List<PackageParser.Package> mOverlayPackages = null;
834
835        void findStaticOverlayPackages() {
836            synchronized (mPackages) {
837                for (PackageParser.Package p : mPackages.values()) {
838                    if (p.mIsStaticOverlay) {
839                        if (mOverlayPackages == null) {
840                            mOverlayPackages = new ArrayList<PackageParser.Package>();
841                        }
842                        mOverlayPackages.add(p);
843                    }
844                }
845            }
846        }
847
848        @Override
849        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
850            // We can trust mOverlayPackages without holding mPackages because package uninstall
851            // can't happen while running parallel parsing.
852            // Moreover holding mPackages on each parsing thread causes dead-lock.
853            return mOverlayPackages == null ? null :
854                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
855        }
856    }
857
858    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
859    final ParallelPackageParserCallback mParallelPackageParserCallback =
860            new ParallelPackageParserCallback();
861
862    public static final class SharedLibraryEntry {
863        public final String path;
864        public final String apk;
865        public final SharedLibraryInfo info;
866
867        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
868                String declaringPackageName, int declaringPackageVersionCode) {
869            path = _path;
870            apk = _apk;
871            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
872                    declaringPackageName, declaringPackageVersionCode), null);
873        }
874    }
875
876    // Currently known shared libraries.
877    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
878    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
879            new ArrayMap<>();
880
881    // All available activities, for your resolving pleasure.
882    final ActivityIntentResolver mActivities =
883            new ActivityIntentResolver();
884
885    // All available receivers, for your resolving pleasure.
886    final ActivityIntentResolver mReceivers =
887            new ActivityIntentResolver();
888
889    // All available services, for your resolving pleasure.
890    final ServiceIntentResolver mServices = new ServiceIntentResolver();
891
892    // All available providers, for your resolving pleasure.
893    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
894
895    // Mapping from provider base names (first directory in content URI codePath)
896    // to the provider information.
897    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
898            new ArrayMap<String, PackageParser.Provider>();
899
900    // Mapping from instrumentation class names to info about them.
901    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
902            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
903
904    // Mapping from permission names to info about them.
905    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
906            new ArrayMap<String, PackageParser.PermissionGroup>();
907
908    // Packages whose data we have transfered into another package, thus
909    // should no longer exist.
910    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
911
912    // Broadcast actions that are only available to the system.
913    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
914
915    /** List of packages waiting for verification. */
916    final SparseArray<PackageVerificationState> mPendingVerification
917            = new SparseArray<PackageVerificationState>();
918
919    /** Set of packages associated with each app op permission. */
920    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
921
922    final PackageInstallerService mInstallerService;
923
924    private final PackageDexOptimizer mPackageDexOptimizer;
925    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
926    // is used by other apps).
927    private final DexManager mDexManager;
928
929    private AtomicInteger mNextMoveId = new AtomicInteger();
930    private final MoveCallbacks mMoveCallbacks;
931
932    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
933
934    // Cache of users who need badging.
935    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
936
937    /** Token for keys in mPendingVerification. */
938    private int mPendingVerificationToken = 0;
939
940    volatile boolean mSystemReady;
941    volatile boolean mSafeMode;
942    volatile boolean mHasSystemUidErrors;
943    private volatile boolean mEphemeralAppsDisabled;
944
945    ApplicationInfo mAndroidApplication;
946    final ActivityInfo mResolveActivity = new ActivityInfo();
947    final ResolveInfo mResolveInfo = new ResolveInfo();
948    ComponentName mResolveComponentName;
949    PackageParser.Package mPlatformPackage;
950    ComponentName mCustomResolverComponentName;
951
952    boolean mResolverReplaced = false;
953
954    private final @Nullable ComponentName mIntentFilterVerifierComponent;
955    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
956
957    private int mIntentFilterVerificationToken = 0;
958
959    /** The service connection to the ephemeral resolver */
960    final EphemeralResolverConnection mInstantAppResolverConnection;
961    /** Component used to show resolver settings for Instant Apps */
962    final ComponentName mInstantAppResolverSettingsComponent;
963
964    /** Activity used to install instant applications */
965    ActivityInfo mInstantAppInstallerActivity;
966    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
967
968    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
969            = new SparseArray<IntentFilterVerificationState>();
970
971    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
972
973    // List of packages names to keep cached, even if they are uninstalled for all users
974    private List<String> mKeepUninstalledPackages;
975
976    private UserManagerInternal mUserManagerInternal;
977
978    private DeviceIdleController.LocalService mDeviceIdleController;
979
980    private File mCacheDir;
981
982    private ArraySet<String> mPrivappPermissionsViolations;
983
984    private Future<?> mPrepareAppDataFuture;
985
986    private static class IFVerificationParams {
987        PackageParser.Package pkg;
988        boolean replacing;
989        int userId;
990        int verifierUid;
991
992        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
993                int _userId, int _verifierUid) {
994            pkg = _pkg;
995            replacing = _replacing;
996            userId = _userId;
997            replacing = _replacing;
998            verifierUid = _verifierUid;
999        }
1000    }
1001
1002    private interface IntentFilterVerifier<T extends IntentFilter> {
1003        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1004                                               T filter, String packageName);
1005        void startVerifications(int userId);
1006        void receiveVerificationResponse(int verificationId);
1007    }
1008
1009    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1010        private Context mContext;
1011        private ComponentName mIntentFilterVerifierComponent;
1012        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1013
1014        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1015            mContext = context;
1016            mIntentFilterVerifierComponent = verifierComponent;
1017        }
1018
1019        private String getDefaultScheme() {
1020            return IntentFilter.SCHEME_HTTPS;
1021        }
1022
1023        @Override
1024        public void startVerifications(int userId) {
1025            // Launch verifications requests
1026            int count = mCurrentIntentFilterVerifications.size();
1027            for (int n=0; n<count; n++) {
1028                int verificationId = mCurrentIntentFilterVerifications.get(n);
1029                final IntentFilterVerificationState ivs =
1030                        mIntentFilterVerificationStates.get(verificationId);
1031
1032                String packageName = ivs.getPackageName();
1033
1034                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1035                final int filterCount = filters.size();
1036                ArraySet<String> domainsSet = new ArraySet<>();
1037                for (int m=0; m<filterCount; m++) {
1038                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1039                    domainsSet.addAll(filter.getHostsList());
1040                }
1041                synchronized (mPackages) {
1042                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1043                            packageName, domainsSet) != null) {
1044                        scheduleWriteSettingsLocked();
1045                    }
1046                }
1047                sendVerificationRequest(userId, verificationId, ivs);
1048            }
1049            mCurrentIntentFilterVerifications.clear();
1050        }
1051
1052        private void sendVerificationRequest(int userId, int verificationId,
1053                IntentFilterVerificationState ivs) {
1054
1055            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1056            verificationIntent.putExtra(
1057                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1058                    verificationId);
1059            verificationIntent.putExtra(
1060                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1061                    getDefaultScheme());
1062            verificationIntent.putExtra(
1063                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1064                    ivs.getHostsString());
1065            verificationIntent.putExtra(
1066                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1067                    ivs.getPackageName());
1068            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1069            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1070
1071            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1072            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1073                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1074                    userId, false, "intent filter verifier");
1075
1076            UserHandle user = new UserHandle(userId);
1077            mContext.sendBroadcastAsUser(verificationIntent, user);
1078            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1079                    "Sending IntentFilter verification broadcast");
1080        }
1081
1082        public void receiveVerificationResponse(int verificationId) {
1083            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1084
1085            final boolean verified = ivs.isVerified();
1086
1087            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1088            final int count = filters.size();
1089            if (DEBUG_DOMAIN_VERIFICATION) {
1090                Slog.i(TAG, "Received verification response " + verificationId
1091                        + " for " + count + " filters, verified=" + verified);
1092            }
1093            for (int n=0; n<count; n++) {
1094                PackageParser.ActivityIntentInfo filter = filters.get(n);
1095                filter.setVerified(verified);
1096
1097                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1098                        + " verified with result:" + verified + " and hosts:"
1099                        + ivs.getHostsString());
1100            }
1101
1102            mIntentFilterVerificationStates.remove(verificationId);
1103
1104            final String packageName = ivs.getPackageName();
1105            IntentFilterVerificationInfo ivi = null;
1106
1107            synchronized (mPackages) {
1108                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1109            }
1110            if (ivi == null) {
1111                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1112                        + verificationId + " packageName:" + packageName);
1113                return;
1114            }
1115            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1116                    "Updating IntentFilterVerificationInfo for package " + packageName
1117                            +" verificationId:" + verificationId);
1118
1119            synchronized (mPackages) {
1120                if (verified) {
1121                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1122                } else {
1123                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1124                }
1125                scheduleWriteSettingsLocked();
1126
1127                final int userId = ivs.getUserId();
1128                if (userId != UserHandle.USER_ALL) {
1129                    final int userStatus =
1130                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1131
1132                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1133                    boolean needUpdate = false;
1134
1135                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1136                    // already been set by the User thru the Disambiguation dialog
1137                    switch (userStatus) {
1138                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1139                            if (verified) {
1140                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1141                            } else {
1142                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1143                            }
1144                            needUpdate = true;
1145                            break;
1146
1147                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1148                            if (verified) {
1149                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1150                                needUpdate = true;
1151                            }
1152                            break;
1153
1154                        default:
1155                            // Nothing to do
1156                    }
1157
1158                    if (needUpdate) {
1159                        mSettings.updateIntentFilterVerificationStatusLPw(
1160                                packageName, updatedStatus, userId);
1161                        scheduleWritePackageRestrictionsLocked(userId);
1162                    }
1163                }
1164            }
1165        }
1166
1167        @Override
1168        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1169                    ActivityIntentInfo filter, String packageName) {
1170            if (!hasValidDomains(filter)) {
1171                return false;
1172            }
1173            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1174            if (ivs == null) {
1175                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1176                        packageName);
1177            }
1178            if (DEBUG_DOMAIN_VERIFICATION) {
1179                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1180            }
1181            ivs.addFilter(filter);
1182            return true;
1183        }
1184
1185        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1186                int userId, int verificationId, String packageName) {
1187            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1188                    verifierUid, userId, packageName);
1189            ivs.setPendingState();
1190            synchronized (mPackages) {
1191                mIntentFilterVerificationStates.append(verificationId, ivs);
1192                mCurrentIntentFilterVerifications.add(verificationId);
1193            }
1194            return ivs;
1195        }
1196    }
1197
1198    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1199        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1200                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1201                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1202    }
1203
1204    // Set of pending broadcasts for aggregating enable/disable of components.
1205    static class PendingPackageBroadcasts {
1206        // for each user id, a map of <package name -> components within that package>
1207        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1208
1209        public PendingPackageBroadcasts() {
1210            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1211        }
1212
1213        public ArrayList<String> get(int userId, String packageName) {
1214            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1215            return packages.get(packageName);
1216        }
1217
1218        public void put(int userId, String packageName, ArrayList<String> components) {
1219            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1220            packages.put(packageName, components);
1221        }
1222
1223        public void remove(int userId, String packageName) {
1224            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1225            if (packages != null) {
1226                packages.remove(packageName);
1227            }
1228        }
1229
1230        public void remove(int userId) {
1231            mUidMap.remove(userId);
1232        }
1233
1234        public int userIdCount() {
1235            return mUidMap.size();
1236        }
1237
1238        public int userIdAt(int n) {
1239            return mUidMap.keyAt(n);
1240        }
1241
1242        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1243            return mUidMap.get(userId);
1244        }
1245
1246        public int size() {
1247            // total number of pending broadcast entries across all userIds
1248            int num = 0;
1249            for (int i = 0; i< mUidMap.size(); i++) {
1250                num += mUidMap.valueAt(i).size();
1251            }
1252            return num;
1253        }
1254
1255        public void clear() {
1256            mUidMap.clear();
1257        }
1258
1259        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1260            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1261            if (map == null) {
1262                map = new ArrayMap<String, ArrayList<String>>();
1263                mUidMap.put(userId, map);
1264            }
1265            return map;
1266        }
1267    }
1268    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1269
1270    // Service Connection to remote media container service to copy
1271    // package uri's from external media onto secure containers
1272    // or internal storage.
1273    private IMediaContainerService mContainerService = null;
1274
1275    static final int SEND_PENDING_BROADCAST = 1;
1276    static final int MCS_BOUND = 3;
1277    static final int END_COPY = 4;
1278    static final int INIT_COPY = 5;
1279    static final int MCS_UNBIND = 6;
1280    static final int START_CLEANING_PACKAGE = 7;
1281    static final int FIND_INSTALL_LOC = 8;
1282    static final int POST_INSTALL = 9;
1283    static final int MCS_RECONNECT = 10;
1284    static final int MCS_GIVE_UP = 11;
1285    static final int UPDATED_MEDIA_STATUS = 12;
1286    static final int WRITE_SETTINGS = 13;
1287    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1288    static final int PACKAGE_VERIFIED = 15;
1289    static final int CHECK_PENDING_VERIFICATION = 16;
1290    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1291    static final int INTENT_FILTER_VERIFIED = 18;
1292    static final int WRITE_PACKAGE_LIST = 19;
1293    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1294
1295    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1296
1297    // Delay time in millisecs
1298    static final int BROADCAST_DELAY = 10 * 1000;
1299
1300    static UserManagerService sUserManager;
1301
1302    // Stores a list of users whose package restrictions file needs to be updated
1303    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1304
1305    final private DefaultContainerConnection mDefContainerConn =
1306            new DefaultContainerConnection();
1307    class DefaultContainerConnection implements ServiceConnection {
1308        public void onServiceConnected(ComponentName name, IBinder service) {
1309            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1310            final IMediaContainerService imcs = IMediaContainerService.Stub
1311                    .asInterface(Binder.allowBlocking(service));
1312            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1313        }
1314
1315        public void onServiceDisconnected(ComponentName name) {
1316            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1317        }
1318    }
1319
1320    // Recordkeeping of restore-after-install operations that are currently in flight
1321    // between the Package Manager and the Backup Manager
1322    static class PostInstallData {
1323        public InstallArgs args;
1324        public PackageInstalledInfo res;
1325
1326        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1327            args = _a;
1328            res = _r;
1329        }
1330    }
1331
1332    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1333    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1334
1335    // XML tags for backup/restore of various bits of state
1336    private static final String TAG_PREFERRED_BACKUP = "pa";
1337    private static final String TAG_DEFAULT_APPS = "da";
1338    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1339
1340    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1341    private static final String TAG_ALL_GRANTS = "rt-grants";
1342    private static final String TAG_GRANT = "grant";
1343    private static final String ATTR_PACKAGE_NAME = "pkg";
1344
1345    private static final String TAG_PERMISSION = "perm";
1346    private static final String ATTR_PERMISSION_NAME = "name";
1347    private static final String ATTR_IS_GRANTED = "g";
1348    private static final String ATTR_USER_SET = "set";
1349    private static final String ATTR_USER_FIXED = "fixed";
1350    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1351
1352    // System/policy permission grants are not backed up
1353    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1354            FLAG_PERMISSION_POLICY_FIXED
1355            | FLAG_PERMISSION_SYSTEM_FIXED
1356            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1357
1358    // And we back up these user-adjusted states
1359    private static final int USER_RUNTIME_GRANT_MASK =
1360            FLAG_PERMISSION_USER_SET
1361            | FLAG_PERMISSION_USER_FIXED
1362            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1363
1364    final @Nullable String mRequiredVerifierPackage;
1365    final @NonNull String mRequiredInstallerPackage;
1366    final @NonNull String mRequiredUninstallerPackage;
1367    final @Nullable String mSetupWizardPackage;
1368    final @Nullable String mStorageManagerPackage;
1369    final @NonNull String mServicesSystemSharedLibraryPackageName;
1370    final @NonNull String mSharedSystemSharedLibraryPackageName;
1371
1372    final boolean mPermissionReviewRequired;
1373
1374    private final PackageUsage mPackageUsage = new PackageUsage();
1375    private final CompilerStats mCompilerStats = new CompilerStats();
1376
1377    class PackageHandler extends Handler {
1378        private boolean mBound = false;
1379        final ArrayList<HandlerParams> mPendingInstalls =
1380            new ArrayList<HandlerParams>();
1381
1382        private boolean connectToService() {
1383            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1384                    " DefaultContainerService");
1385            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1386            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1387            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1388                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1389                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1390                mBound = true;
1391                return true;
1392            }
1393            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1394            return false;
1395        }
1396
1397        private void disconnectService() {
1398            mContainerService = null;
1399            mBound = false;
1400            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1401            mContext.unbindService(mDefContainerConn);
1402            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1403        }
1404
1405        PackageHandler(Looper looper) {
1406            super(looper);
1407        }
1408
1409        public void handleMessage(Message msg) {
1410            try {
1411                doHandleMessage(msg);
1412            } finally {
1413                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1414            }
1415        }
1416
1417        void doHandleMessage(Message msg) {
1418            switch (msg.what) {
1419                case INIT_COPY: {
1420                    HandlerParams params = (HandlerParams) msg.obj;
1421                    int idx = mPendingInstalls.size();
1422                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1423                    // If a bind was already initiated we dont really
1424                    // need to do anything. The pending install
1425                    // will be processed later on.
1426                    if (!mBound) {
1427                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1428                                System.identityHashCode(mHandler));
1429                        // If this is the only one pending we might
1430                        // have to bind to the service again.
1431                        if (!connectToService()) {
1432                            Slog.e(TAG, "Failed to bind to media container service");
1433                            params.serviceError();
1434                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1435                                    System.identityHashCode(mHandler));
1436                            if (params.traceMethod != null) {
1437                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1438                                        params.traceCookie);
1439                            }
1440                            return;
1441                        } else {
1442                            // Once we bind to the service, the first
1443                            // pending request will be processed.
1444                            mPendingInstalls.add(idx, params);
1445                        }
1446                    } else {
1447                        mPendingInstalls.add(idx, params);
1448                        // Already bound to the service. Just make
1449                        // sure we trigger off processing the first request.
1450                        if (idx == 0) {
1451                            mHandler.sendEmptyMessage(MCS_BOUND);
1452                        }
1453                    }
1454                    break;
1455                }
1456                case MCS_BOUND: {
1457                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1458                    if (msg.obj != null) {
1459                        mContainerService = (IMediaContainerService) msg.obj;
1460                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1461                                System.identityHashCode(mHandler));
1462                    }
1463                    if (mContainerService == null) {
1464                        if (!mBound) {
1465                            // Something seriously wrong since we are not bound and we are not
1466                            // waiting for connection. Bail out.
1467                            Slog.e(TAG, "Cannot bind to media container service");
1468                            for (HandlerParams params : mPendingInstalls) {
1469                                // Indicate service bind error
1470                                params.serviceError();
1471                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1472                                        System.identityHashCode(params));
1473                                if (params.traceMethod != null) {
1474                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1475                                            params.traceMethod, params.traceCookie);
1476                                }
1477                                return;
1478                            }
1479                            mPendingInstalls.clear();
1480                        } else {
1481                            Slog.w(TAG, "Waiting to connect to media container service");
1482                        }
1483                    } else if (mPendingInstalls.size() > 0) {
1484                        HandlerParams params = mPendingInstalls.get(0);
1485                        if (params != null) {
1486                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1487                                    System.identityHashCode(params));
1488                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1489                            if (params.startCopy()) {
1490                                // We are done...  look for more work or to
1491                                // go idle.
1492                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1493                                        "Checking for more work or unbind...");
1494                                // Delete pending install
1495                                if (mPendingInstalls.size() > 0) {
1496                                    mPendingInstalls.remove(0);
1497                                }
1498                                if (mPendingInstalls.size() == 0) {
1499                                    if (mBound) {
1500                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1501                                                "Posting delayed MCS_UNBIND");
1502                                        removeMessages(MCS_UNBIND);
1503                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1504                                        // Unbind after a little delay, to avoid
1505                                        // continual thrashing.
1506                                        sendMessageDelayed(ubmsg, 10000);
1507                                    }
1508                                } else {
1509                                    // There are more pending requests in queue.
1510                                    // Just post MCS_BOUND message to trigger processing
1511                                    // of next pending install.
1512                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1513                                            "Posting MCS_BOUND for next work");
1514                                    mHandler.sendEmptyMessage(MCS_BOUND);
1515                                }
1516                            }
1517                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1518                        }
1519                    } else {
1520                        // Should never happen ideally.
1521                        Slog.w(TAG, "Empty queue");
1522                    }
1523                    break;
1524                }
1525                case MCS_RECONNECT: {
1526                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1527                    if (mPendingInstalls.size() > 0) {
1528                        if (mBound) {
1529                            disconnectService();
1530                        }
1531                        if (!connectToService()) {
1532                            Slog.e(TAG, "Failed to bind to media container service");
1533                            for (HandlerParams params : mPendingInstalls) {
1534                                // Indicate service bind error
1535                                params.serviceError();
1536                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1537                                        System.identityHashCode(params));
1538                            }
1539                            mPendingInstalls.clear();
1540                        }
1541                    }
1542                    break;
1543                }
1544                case MCS_UNBIND: {
1545                    // If there is no actual work left, then time to unbind.
1546                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1547
1548                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1549                        if (mBound) {
1550                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1551
1552                            disconnectService();
1553                        }
1554                    } else if (mPendingInstalls.size() > 0) {
1555                        // There are more pending requests in queue.
1556                        // Just post MCS_BOUND message to trigger processing
1557                        // of next pending install.
1558                        mHandler.sendEmptyMessage(MCS_BOUND);
1559                    }
1560
1561                    break;
1562                }
1563                case MCS_GIVE_UP: {
1564                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1565                    HandlerParams params = mPendingInstalls.remove(0);
1566                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1567                            System.identityHashCode(params));
1568                    break;
1569                }
1570                case SEND_PENDING_BROADCAST: {
1571                    String packages[];
1572                    ArrayList<String> components[];
1573                    int size = 0;
1574                    int uids[];
1575                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1576                    synchronized (mPackages) {
1577                        if (mPendingBroadcasts == null) {
1578                            return;
1579                        }
1580                        size = mPendingBroadcasts.size();
1581                        if (size <= 0) {
1582                            // Nothing to be done. Just return
1583                            return;
1584                        }
1585                        packages = new String[size];
1586                        components = new ArrayList[size];
1587                        uids = new int[size];
1588                        int i = 0;  // filling out the above arrays
1589
1590                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1591                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1592                            Iterator<Map.Entry<String, ArrayList<String>>> it
1593                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1594                                            .entrySet().iterator();
1595                            while (it.hasNext() && i < size) {
1596                                Map.Entry<String, ArrayList<String>> ent = it.next();
1597                                packages[i] = ent.getKey();
1598                                components[i] = ent.getValue();
1599                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1600                                uids[i] = (ps != null)
1601                                        ? UserHandle.getUid(packageUserId, ps.appId)
1602                                        : -1;
1603                                i++;
1604                            }
1605                        }
1606                        size = i;
1607                        mPendingBroadcasts.clear();
1608                    }
1609                    // Send broadcasts
1610                    for (int i = 0; i < size; i++) {
1611                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1612                    }
1613                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1614                    break;
1615                }
1616                case START_CLEANING_PACKAGE: {
1617                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1618                    final String packageName = (String)msg.obj;
1619                    final int userId = msg.arg1;
1620                    final boolean andCode = msg.arg2 != 0;
1621                    synchronized (mPackages) {
1622                        if (userId == UserHandle.USER_ALL) {
1623                            int[] users = sUserManager.getUserIds();
1624                            for (int user : users) {
1625                                mSettings.addPackageToCleanLPw(
1626                                        new PackageCleanItem(user, packageName, andCode));
1627                            }
1628                        } else {
1629                            mSettings.addPackageToCleanLPw(
1630                                    new PackageCleanItem(userId, packageName, andCode));
1631                        }
1632                    }
1633                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1634                    startCleaningPackages();
1635                } break;
1636                case POST_INSTALL: {
1637                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1638
1639                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1640                    final boolean didRestore = (msg.arg2 != 0);
1641                    mRunningInstalls.delete(msg.arg1);
1642
1643                    if (data != null) {
1644                        InstallArgs args = data.args;
1645                        PackageInstalledInfo parentRes = data.res;
1646
1647                        final boolean grantPermissions = (args.installFlags
1648                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1649                        final boolean killApp = (args.installFlags
1650                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1651                        final String[] grantedPermissions = args.installGrantPermissions;
1652
1653                        // Handle the parent package
1654                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1655                                grantedPermissions, didRestore, args.installerPackageName,
1656                                args.observer);
1657
1658                        // Handle the child packages
1659                        final int childCount = (parentRes.addedChildPackages != null)
1660                                ? parentRes.addedChildPackages.size() : 0;
1661                        for (int i = 0; i < childCount; i++) {
1662                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1663                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1664                                    grantedPermissions, false, args.installerPackageName,
1665                                    args.observer);
1666                        }
1667
1668                        // Log tracing if needed
1669                        if (args.traceMethod != null) {
1670                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1671                                    args.traceCookie);
1672                        }
1673                    } else {
1674                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1675                    }
1676
1677                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1678                } break;
1679                case UPDATED_MEDIA_STATUS: {
1680                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1681                    boolean reportStatus = msg.arg1 == 1;
1682                    boolean doGc = msg.arg2 == 1;
1683                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1684                    if (doGc) {
1685                        // Force a gc to clear up stale containers.
1686                        Runtime.getRuntime().gc();
1687                    }
1688                    if (msg.obj != null) {
1689                        @SuppressWarnings("unchecked")
1690                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1691                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1692                        // Unload containers
1693                        unloadAllContainers(args);
1694                    }
1695                    if (reportStatus) {
1696                        try {
1697                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1698                                    "Invoking StorageManagerService call back");
1699                            PackageHelper.getStorageManager().finishMediaUpdate();
1700                        } catch (RemoteException e) {
1701                            Log.e(TAG, "StorageManagerService not running?");
1702                        }
1703                    }
1704                } break;
1705                case WRITE_SETTINGS: {
1706                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1707                    synchronized (mPackages) {
1708                        removeMessages(WRITE_SETTINGS);
1709                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1710                        mSettings.writeLPr();
1711                        mDirtyUsers.clear();
1712                    }
1713                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1714                } break;
1715                case WRITE_PACKAGE_RESTRICTIONS: {
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1717                    synchronized (mPackages) {
1718                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1719                        for (int userId : mDirtyUsers) {
1720                            mSettings.writePackageRestrictionsLPr(userId);
1721                        }
1722                        mDirtyUsers.clear();
1723                    }
1724                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1725                } break;
1726                case WRITE_PACKAGE_LIST: {
1727                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1728                    synchronized (mPackages) {
1729                        removeMessages(WRITE_PACKAGE_LIST);
1730                        mSettings.writePackageListLPr(msg.arg1);
1731                    }
1732                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1733                } break;
1734                case CHECK_PENDING_VERIFICATION: {
1735                    final int verificationId = msg.arg1;
1736                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1737
1738                    if ((state != null) && !state.timeoutExtended()) {
1739                        final InstallArgs args = state.getInstallArgs();
1740                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1741
1742                        Slog.i(TAG, "Verification timed out for " + originUri);
1743                        mPendingVerification.remove(verificationId);
1744
1745                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1746
1747                        final UserHandle user = args.getUser();
1748                        if (getDefaultVerificationResponse(user)
1749                                == PackageManager.VERIFICATION_ALLOW) {
1750                            Slog.i(TAG, "Continuing with installation of " + originUri);
1751                            state.setVerifierResponse(Binder.getCallingUid(),
1752                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1753                            broadcastPackageVerified(verificationId, originUri,
1754                                    PackageManager.VERIFICATION_ALLOW, user);
1755                            try {
1756                                ret = args.copyApk(mContainerService, true);
1757                            } catch (RemoteException e) {
1758                                Slog.e(TAG, "Could not contact the ContainerService");
1759                            }
1760                        } else {
1761                            broadcastPackageVerified(verificationId, originUri,
1762                                    PackageManager.VERIFICATION_REJECT, user);
1763                        }
1764
1765                        Trace.asyncTraceEnd(
1766                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1767
1768                        processPendingInstall(args, ret);
1769                        mHandler.sendEmptyMessage(MCS_UNBIND);
1770                    }
1771                    break;
1772                }
1773                case PACKAGE_VERIFIED: {
1774                    final int verificationId = msg.arg1;
1775
1776                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1777                    if (state == null) {
1778                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1779                        break;
1780                    }
1781
1782                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1783
1784                    state.setVerifierResponse(response.callerUid, response.code);
1785
1786                    if (state.isVerificationComplete()) {
1787                        mPendingVerification.remove(verificationId);
1788
1789                        final InstallArgs args = state.getInstallArgs();
1790                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1791
1792                        int ret;
1793                        if (state.isInstallAllowed()) {
1794                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1795                            broadcastPackageVerified(verificationId, originUri,
1796                                    response.code, state.getInstallArgs().getUser());
1797                            try {
1798                                ret = args.copyApk(mContainerService, true);
1799                            } catch (RemoteException e) {
1800                                Slog.e(TAG, "Could not contact the ContainerService");
1801                            }
1802                        } else {
1803                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1804                        }
1805
1806                        Trace.asyncTraceEnd(
1807                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1808
1809                        processPendingInstall(args, ret);
1810                        mHandler.sendEmptyMessage(MCS_UNBIND);
1811                    }
1812
1813                    break;
1814                }
1815                case START_INTENT_FILTER_VERIFICATIONS: {
1816                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1817                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1818                            params.replacing, params.pkg);
1819                    break;
1820                }
1821                case INTENT_FILTER_VERIFIED: {
1822                    final int verificationId = msg.arg1;
1823
1824                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1825                            verificationId);
1826                    if (state == null) {
1827                        Slog.w(TAG, "Invalid IntentFilter verification token "
1828                                + verificationId + " received");
1829                        break;
1830                    }
1831
1832                    final int userId = state.getUserId();
1833
1834                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1835                            "Processing IntentFilter verification with token:"
1836                            + verificationId + " and userId:" + userId);
1837
1838                    final IntentFilterVerificationResponse response =
1839                            (IntentFilterVerificationResponse) msg.obj;
1840
1841                    state.setVerifierResponse(response.callerUid, response.code);
1842
1843                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1844                            "IntentFilter verification with token:" + verificationId
1845                            + " and userId:" + userId
1846                            + " is settings verifier response with response code:"
1847                            + response.code);
1848
1849                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1850                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1851                                + response.getFailedDomainsString());
1852                    }
1853
1854                    if (state.isVerificationComplete()) {
1855                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1856                    } else {
1857                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1858                                "IntentFilter verification with token:" + verificationId
1859                                + " was not said to be complete");
1860                    }
1861
1862                    break;
1863                }
1864                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1865                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1866                            mInstantAppResolverConnection,
1867                            (InstantAppRequest) msg.obj,
1868                            mInstantAppInstallerActivity,
1869                            mHandler);
1870                }
1871            }
1872        }
1873    }
1874
1875    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1876            boolean killApp, String[] grantedPermissions,
1877            boolean launchedForRestore, String installerPackage,
1878            IPackageInstallObserver2 installObserver) {
1879        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1880            // Send the removed broadcasts
1881            if (res.removedInfo != null) {
1882                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1883            }
1884
1885            // Now that we successfully installed the package, grant runtime
1886            // permissions if requested before broadcasting the install. Also
1887            // for legacy apps in permission review mode we clear the permission
1888            // review flag which is used to emulate runtime permissions for
1889            // legacy apps.
1890            if (grantPermissions) {
1891                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1892            }
1893
1894            final boolean update = res.removedInfo != null
1895                    && res.removedInfo.removedPackage != null;
1896            final String origInstallerPackageName = res.removedInfo != null
1897                    ? res.removedInfo.installerPackageName : null;
1898
1899            // If this is the first time we have child packages for a disabled privileged
1900            // app that had no children, we grant requested runtime permissions to the new
1901            // children if the parent on the system image had them already granted.
1902            if (res.pkg.parentPackage != null) {
1903                synchronized (mPackages) {
1904                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1905                }
1906            }
1907
1908            synchronized (mPackages) {
1909                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1910            }
1911
1912            final String packageName = res.pkg.applicationInfo.packageName;
1913
1914            // Determine the set of users who are adding this package for
1915            // the first time vs. those who are seeing an update.
1916            int[] firstUsers = EMPTY_INT_ARRAY;
1917            int[] updateUsers = EMPTY_INT_ARRAY;
1918            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1919            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1920            for (int newUser : res.newUsers) {
1921                if (ps.getInstantApp(newUser)) {
1922                    continue;
1923                }
1924                if (allNewUsers) {
1925                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1926                    continue;
1927                }
1928                boolean isNew = true;
1929                for (int origUser : res.origUsers) {
1930                    if (origUser == newUser) {
1931                        isNew = false;
1932                        break;
1933                    }
1934                }
1935                if (isNew) {
1936                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1937                } else {
1938                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1939                }
1940            }
1941
1942            // Send installed broadcasts if the package is not a static shared lib.
1943            if (res.pkg.staticSharedLibName == null) {
1944                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1945
1946                // Send added for users that see the package for the first time
1947                // sendPackageAddedForNewUsers also deals with system apps
1948                int appId = UserHandle.getAppId(res.uid);
1949                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1950                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1951
1952                // Send added for users that don't see the package for the first time
1953                Bundle extras = new Bundle(1);
1954                extras.putInt(Intent.EXTRA_UID, res.uid);
1955                if (update) {
1956                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1957                }
1958                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1959                        extras, 0 /*flags*/,
1960                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1961                if (origInstallerPackageName != null) {
1962                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1963                            extras, 0 /*flags*/,
1964                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1965                }
1966
1967                // Send replaced for users that don't see the package for the first time
1968                if (update) {
1969                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1970                            packageName, extras, 0 /*flags*/,
1971                            null /*targetPackage*/, null /*finishedReceiver*/,
1972                            updateUsers);
1973                    if (origInstallerPackageName != null) {
1974                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1975                                extras, 0 /*flags*/,
1976                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1977                    }
1978                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1979                            null /*package*/, null /*extras*/, 0 /*flags*/,
1980                            packageName /*targetPackage*/,
1981                            null /*finishedReceiver*/, updateUsers);
1982                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1983                    // First-install and we did a restore, so we're responsible for the
1984                    // first-launch broadcast.
1985                    if (DEBUG_BACKUP) {
1986                        Slog.i(TAG, "Post-restore of " + packageName
1987                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
1988                    }
1989                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
1990                }
1991
1992                // Send broadcast package appeared if forward locked/external for all users
1993                // treat asec-hosted packages like removable media on upgrade
1994                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
1995                    if (DEBUG_INSTALL) {
1996                        Slog.i(TAG, "upgrading pkg " + res.pkg
1997                                + " is ASEC-hosted -> AVAILABLE");
1998                    }
1999                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2000                    ArrayList<String> pkgList = new ArrayList<>(1);
2001                    pkgList.add(packageName);
2002                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2003                }
2004            }
2005
2006            // Work that needs to happen on first install within each user
2007            if (firstUsers != null && firstUsers.length > 0) {
2008                synchronized (mPackages) {
2009                    for (int userId : firstUsers) {
2010                        // If this app is a browser and it's newly-installed for some
2011                        // users, clear any default-browser state in those users. The
2012                        // app's nature doesn't depend on the user, so we can just check
2013                        // its browser nature in any user and generalize.
2014                        if (packageIsBrowser(packageName, userId)) {
2015                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2016                        }
2017
2018                        // We may also need to apply pending (restored) runtime
2019                        // permission grants within these users.
2020                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2021                    }
2022                }
2023            }
2024
2025            // Log current value of "unknown sources" setting
2026            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2027                    getUnknownSourcesSettings());
2028
2029            // Force a gc to clear up things
2030            Runtime.getRuntime().gc();
2031
2032            // Remove the replaced package's older resources safely now
2033            // We delete after a gc for applications  on sdcard.
2034            if (res.removedInfo != null && res.removedInfo.args != null) {
2035                synchronized (mInstallLock) {
2036                    res.removedInfo.args.doPostDeleteLI(true);
2037                }
2038            }
2039
2040            // Notify DexManager that the package was installed for new users.
2041            // The updated users should already be indexed and the package code paths
2042            // should not change.
2043            // Don't notify the manager for ephemeral apps as they are not expected to
2044            // survive long enough to benefit of background optimizations.
2045            for (int userId : firstUsers) {
2046                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2047                // There's a race currently where some install events may interleave with an uninstall.
2048                // This can lead to package info being null (b/36642664).
2049                if (info != null) {
2050                    mDexManager.notifyPackageInstalled(info, userId);
2051                }
2052            }
2053        }
2054
2055        // If someone is watching installs - notify them
2056        if (installObserver != null) {
2057            try {
2058                Bundle extras = extrasForInstallResult(res);
2059                installObserver.onPackageInstalled(res.name, res.returnCode,
2060                        res.returnMsg, extras);
2061            } catch (RemoteException e) {
2062                Slog.i(TAG, "Observer no longer exists.");
2063            }
2064        }
2065    }
2066
2067    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2068            PackageParser.Package pkg) {
2069        if (pkg.parentPackage == null) {
2070            return;
2071        }
2072        if (pkg.requestedPermissions == null) {
2073            return;
2074        }
2075        final PackageSetting disabledSysParentPs = mSettings
2076                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2077        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2078                || !disabledSysParentPs.isPrivileged()
2079                || (disabledSysParentPs.childPackageNames != null
2080                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2081            return;
2082        }
2083        final int[] allUserIds = sUserManager.getUserIds();
2084        final int permCount = pkg.requestedPermissions.size();
2085        for (int i = 0; i < permCount; i++) {
2086            String permission = pkg.requestedPermissions.get(i);
2087            BasePermission bp = mSettings.mPermissions.get(permission);
2088            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2089                continue;
2090            }
2091            for (int userId : allUserIds) {
2092                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2093                        permission, userId)) {
2094                    grantRuntimePermission(pkg.packageName, permission, userId);
2095                }
2096            }
2097        }
2098    }
2099
2100    private StorageEventListener mStorageListener = new StorageEventListener() {
2101        @Override
2102        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2103            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2104                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2105                    final String volumeUuid = vol.getFsUuid();
2106
2107                    // Clean up any users or apps that were removed or recreated
2108                    // while this volume was missing
2109                    sUserManager.reconcileUsers(volumeUuid);
2110                    reconcileApps(volumeUuid);
2111
2112                    // Clean up any install sessions that expired or were
2113                    // cancelled while this volume was missing
2114                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2115
2116                    loadPrivatePackages(vol);
2117
2118                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2119                    unloadPrivatePackages(vol);
2120                }
2121            }
2122
2123            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2124                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2125                    updateExternalMediaStatus(true, false);
2126                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2127                    updateExternalMediaStatus(false, false);
2128                }
2129            }
2130        }
2131
2132        @Override
2133        public void onVolumeForgotten(String fsUuid) {
2134            if (TextUtils.isEmpty(fsUuid)) {
2135                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2136                return;
2137            }
2138
2139            // Remove any apps installed on the forgotten volume
2140            synchronized (mPackages) {
2141                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2142                for (PackageSetting ps : packages) {
2143                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2144                    deletePackageVersioned(new VersionedPackage(ps.name,
2145                            PackageManager.VERSION_CODE_HIGHEST),
2146                            new LegacyPackageDeleteObserver(null).getBinder(),
2147                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2148                    // Try very hard to release any references to this package
2149                    // so we don't risk the system server being killed due to
2150                    // open FDs
2151                    AttributeCache.instance().removePackage(ps.name);
2152                }
2153
2154                mSettings.onVolumeForgotten(fsUuid);
2155                mSettings.writeLPr();
2156            }
2157        }
2158    };
2159
2160    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2161            String[] grantedPermissions) {
2162        for (int userId : userIds) {
2163            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2164        }
2165    }
2166
2167    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2168            String[] grantedPermissions) {
2169        SettingBase sb = (SettingBase) pkg.mExtras;
2170        if (sb == null) {
2171            return;
2172        }
2173
2174        PermissionsState permissionsState = sb.getPermissionsState();
2175
2176        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2177                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2178
2179        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2180                >= Build.VERSION_CODES.M;
2181
2182        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2183
2184        for (String permission : pkg.requestedPermissions) {
2185            final BasePermission bp;
2186            synchronized (mPackages) {
2187                bp = mSettings.mPermissions.get(permission);
2188            }
2189            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2190                    && (!instantApp || bp.isInstant())
2191                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2192                    && (grantedPermissions == null
2193                           || ArrayUtils.contains(grantedPermissions, permission))) {
2194                final int flags = permissionsState.getPermissionFlags(permission, userId);
2195                if (supportsRuntimePermissions) {
2196                    // Installer cannot change immutable permissions.
2197                    if ((flags & immutableFlags) == 0) {
2198                        grantRuntimePermission(pkg.packageName, permission, userId);
2199                    }
2200                } else if (mPermissionReviewRequired) {
2201                    // In permission review mode we clear the review flag when we
2202                    // are asked to install the app with all permissions granted.
2203                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2204                        updatePermissionFlags(permission, pkg.packageName,
2205                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2206                    }
2207                }
2208            }
2209        }
2210    }
2211
2212    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2213        Bundle extras = null;
2214        switch (res.returnCode) {
2215            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2216                extras = new Bundle();
2217                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2218                        res.origPermission);
2219                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2220                        res.origPackage);
2221                break;
2222            }
2223            case PackageManager.INSTALL_SUCCEEDED: {
2224                extras = new Bundle();
2225                extras.putBoolean(Intent.EXTRA_REPLACING,
2226                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2227                break;
2228            }
2229        }
2230        return extras;
2231    }
2232
2233    void scheduleWriteSettingsLocked() {
2234        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2235            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2236        }
2237    }
2238
2239    void scheduleWritePackageListLocked(int userId) {
2240        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2241            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2242            msg.arg1 = userId;
2243            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2244        }
2245    }
2246
2247    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2248        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2249        scheduleWritePackageRestrictionsLocked(userId);
2250    }
2251
2252    void scheduleWritePackageRestrictionsLocked(int userId) {
2253        final int[] userIds = (userId == UserHandle.USER_ALL)
2254                ? sUserManager.getUserIds() : new int[]{userId};
2255        for (int nextUserId : userIds) {
2256            if (!sUserManager.exists(nextUserId)) return;
2257            mDirtyUsers.add(nextUserId);
2258            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2259                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2260            }
2261        }
2262    }
2263
2264    public static PackageManagerService main(Context context, Installer installer,
2265            boolean factoryTest, boolean onlyCore) {
2266        // Self-check for initial settings.
2267        PackageManagerServiceCompilerMapping.checkProperties();
2268
2269        PackageManagerService m = new PackageManagerService(context, installer,
2270                factoryTest, onlyCore);
2271        m.enableSystemUserPackages();
2272        ServiceManager.addService("package", m);
2273        return m;
2274    }
2275
2276    private void enableSystemUserPackages() {
2277        if (!UserManager.isSplitSystemUser()) {
2278            return;
2279        }
2280        // For system user, enable apps based on the following conditions:
2281        // - app is whitelisted or belong to one of these groups:
2282        //   -- system app which has no launcher icons
2283        //   -- system app which has INTERACT_ACROSS_USERS permission
2284        //   -- system IME app
2285        // - app is not in the blacklist
2286        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2287        Set<String> enableApps = new ArraySet<>();
2288        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2289                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2290                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2291        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2292        enableApps.addAll(wlApps);
2293        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2294                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2295        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2296        enableApps.removeAll(blApps);
2297        Log.i(TAG, "Applications installed for system user: " + enableApps);
2298        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2299                UserHandle.SYSTEM);
2300        final int allAppsSize = allAps.size();
2301        synchronized (mPackages) {
2302            for (int i = 0; i < allAppsSize; i++) {
2303                String pName = allAps.get(i);
2304                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2305                // Should not happen, but we shouldn't be failing if it does
2306                if (pkgSetting == null) {
2307                    continue;
2308                }
2309                boolean install = enableApps.contains(pName);
2310                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2311                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2312                            + " for system user");
2313                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2314                }
2315            }
2316            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2317        }
2318    }
2319
2320    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2321        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2322                Context.DISPLAY_SERVICE);
2323        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2324    }
2325
2326    /**
2327     * Requests that files preopted on a secondary system partition be copied to the data partition
2328     * if possible.  Note that the actual copying of the files is accomplished by init for security
2329     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2330     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2331     */
2332    private static void requestCopyPreoptedFiles() {
2333        final int WAIT_TIME_MS = 100;
2334        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2335        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2336            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2337            // We will wait for up to 100 seconds.
2338            final long timeStart = SystemClock.uptimeMillis();
2339            final long timeEnd = timeStart + 100 * 1000;
2340            long timeNow = timeStart;
2341            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2342                try {
2343                    Thread.sleep(WAIT_TIME_MS);
2344                } catch (InterruptedException e) {
2345                    // Do nothing
2346                }
2347                timeNow = SystemClock.uptimeMillis();
2348                if (timeNow > timeEnd) {
2349                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2350                    Slog.wtf(TAG, "cppreopt did not finish!");
2351                    break;
2352                }
2353            }
2354
2355            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2356        }
2357    }
2358
2359    public PackageManagerService(Context context, Installer installer,
2360            boolean factoryTest, boolean onlyCore) {
2361        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2362        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2363        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2364                SystemClock.uptimeMillis());
2365
2366        if (mSdkVersion <= 0) {
2367            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2368        }
2369
2370        mContext = context;
2371
2372        mPermissionReviewRequired = context.getResources().getBoolean(
2373                R.bool.config_permissionReviewRequired);
2374
2375        mFactoryTest = factoryTest;
2376        mOnlyCore = onlyCore;
2377        mMetrics = new DisplayMetrics();
2378        mSettings = new Settings(mPackages);
2379        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2380                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2381        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2382                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2383        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2384                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2385        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2386                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2387        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2388                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2389        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2390                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2391
2392        String separateProcesses = SystemProperties.get("debug.separate_processes");
2393        if (separateProcesses != null && separateProcesses.length() > 0) {
2394            if ("*".equals(separateProcesses)) {
2395                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2396                mSeparateProcesses = null;
2397                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2398            } else {
2399                mDefParseFlags = 0;
2400                mSeparateProcesses = separateProcesses.split(",");
2401                Slog.w(TAG, "Running with debug.separate_processes: "
2402                        + separateProcesses);
2403            }
2404        } else {
2405            mDefParseFlags = 0;
2406            mSeparateProcesses = null;
2407        }
2408
2409        mInstaller = installer;
2410        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2411                "*dexopt*");
2412        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2413        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2414
2415        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2416                FgThread.get().getLooper());
2417
2418        getDefaultDisplayMetrics(context, mMetrics);
2419
2420        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2421        SystemConfig systemConfig = SystemConfig.getInstance();
2422        mGlobalGids = systemConfig.getGlobalGids();
2423        mSystemPermissions = systemConfig.getSystemPermissions();
2424        mAvailableFeatures = systemConfig.getAvailableFeatures();
2425        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2426
2427        mProtectedPackages = new ProtectedPackages(mContext);
2428
2429        synchronized (mInstallLock) {
2430        // writer
2431        synchronized (mPackages) {
2432            mHandlerThread = new ServiceThread(TAG,
2433                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2434            mHandlerThread.start();
2435            mHandler = new PackageHandler(mHandlerThread.getLooper());
2436            mProcessLoggingHandler = new ProcessLoggingHandler();
2437            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2438
2439            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2440            mInstantAppRegistry = new InstantAppRegistry(this);
2441
2442            File dataDir = Environment.getDataDirectory();
2443            mAppInstallDir = new File(dataDir, "app");
2444            mAppLib32InstallDir = new File(dataDir, "app-lib");
2445            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2446            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2447            sUserManager = new UserManagerService(context, this,
2448                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2449
2450            // Propagate permission configuration in to package manager.
2451            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2452                    = systemConfig.getPermissions();
2453            for (int i=0; i<permConfig.size(); i++) {
2454                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2455                BasePermission bp = mSettings.mPermissions.get(perm.name);
2456                if (bp == null) {
2457                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2458                    mSettings.mPermissions.put(perm.name, bp);
2459                }
2460                if (perm.gids != null) {
2461                    bp.setGids(perm.gids, perm.perUser);
2462                }
2463            }
2464
2465            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2466            final int builtInLibCount = libConfig.size();
2467            for (int i = 0; i < builtInLibCount; i++) {
2468                String name = libConfig.keyAt(i);
2469                String path = libConfig.valueAt(i);
2470                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2471                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2472            }
2473
2474            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2475
2476            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2477            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2478            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2479
2480            // Clean up orphaned packages for which the code path doesn't exist
2481            // and they are an update to a system app - caused by bug/32321269
2482            final int packageSettingCount = mSettings.mPackages.size();
2483            for (int i = packageSettingCount - 1; i >= 0; i--) {
2484                PackageSetting ps = mSettings.mPackages.valueAt(i);
2485                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2486                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2487                    mSettings.mPackages.removeAt(i);
2488                    mSettings.enableSystemPackageLPw(ps.name);
2489                }
2490            }
2491
2492            if (mFirstBoot) {
2493                requestCopyPreoptedFiles();
2494            }
2495
2496            String customResolverActivity = Resources.getSystem().getString(
2497                    R.string.config_customResolverActivity);
2498            if (TextUtils.isEmpty(customResolverActivity)) {
2499                customResolverActivity = null;
2500            } else {
2501                mCustomResolverComponentName = ComponentName.unflattenFromString(
2502                        customResolverActivity);
2503            }
2504
2505            long startTime = SystemClock.uptimeMillis();
2506
2507            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2508                    startTime);
2509
2510            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2511            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2512
2513            if (bootClassPath == null) {
2514                Slog.w(TAG, "No BOOTCLASSPATH found!");
2515            }
2516
2517            if (systemServerClassPath == null) {
2518                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2519            }
2520
2521            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2522
2523            final VersionInfo ver = mSettings.getInternalVersion();
2524            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2525            if (mIsUpgrade) {
2526                logCriticalInfo(Log.INFO,
2527                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2528            }
2529
2530            // when upgrading from pre-M, promote system app permissions from install to runtime
2531            mPromoteSystemApps =
2532                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2533
2534            // When upgrading from pre-N, we need to handle package extraction like first boot,
2535            // as there is no profiling data available.
2536            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2537
2538            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2539
2540            // save off the names of pre-existing system packages prior to scanning; we don't
2541            // want to automatically grant runtime permissions for new system apps
2542            if (mPromoteSystemApps) {
2543                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2544                while (pkgSettingIter.hasNext()) {
2545                    PackageSetting ps = pkgSettingIter.next();
2546                    if (isSystemApp(ps)) {
2547                        mExistingSystemPackages.add(ps.name);
2548                    }
2549                }
2550            }
2551
2552            mCacheDir = preparePackageParserCache(mIsUpgrade);
2553
2554            // Set flag to monitor and not change apk file paths when
2555            // scanning install directories.
2556            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2557
2558            if (mIsUpgrade || mFirstBoot) {
2559                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2560            }
2561
2562            // Collect vendor overlay packages. (Do this before scanning any apps.)
2563            // For security and version matching reason, only consider
2564            // overlay packages if they reside in the right directory.
2565            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2566                    | PackageParser.PARSE_IS_SYSTEM
2567                    | PackageParser.PARSE_IS_SYSTEM_DIR
2568                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2569
2570            mParallelPackageParserCallback.findStaticOverlayPackages();
2571
2572            // Find base frameworks (resource packages without code).
2573            scanDirTracedLI(frameworkDir, mDefParseFlags
2574                    | PackageParser.PARSE_IS_SYSTEM
2575                    | PackageParser.PARSE_IS_SYSTEM_DIR
2576                    | PackageParser.PARSE_IS_PRIVILEGED,
2577                    scanFlags | SCAN_NO_DEX, 0);
2578
2579            // Collected privileged system packages.
2580            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2581            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2582                    | PackageParser.PARSE_IS_SYSTEM
2583                    | PackageParser.PARSE_IS_SYSTEM_DIR
2584                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2585
2586            // Collect ordinary system packages.
2587            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2588            scanDirTracedLI(systemAppDir, mDefParseFlags
2589                    | PackageParser.PARSE_IS_SYSTEM
2590                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2591
2592            // Collect all vendor packages.
2593            File vendorAppDir = new File("/vendor/app");
2594            try {
2595                vendorAppDir = vendorAppDir.getCanonicalFile();
2596            } catch (IOException e) {
2597                // failed to look up canonical path, continue with original one
2598            }
2599            scanDirTracedLI(vendorAppDir, mDefParseFlags
2600                    | PackageParser.PARSE_IS_SYSTEM
2601                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2602
2603            // Collect all OEM packages.
2604            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2605            scanDirTracedLI(oemAppDir, mDefParseFlags
2606                    | PackageParser.PARSE_IS_SYSTEM
2607                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2608
2609            // Prune any system packages that no longer exist.
2610            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2611            if (!mOnlyCore) {
2612                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2613                while (psit.hasNext()) {
2614                    PackageSetting ps = psit.next();
2615
2616                    /*
2617                     * If this is not a system app, it can't be a
2618                     * disable system app.
2619                     */
2620                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2621                        continue;
2622                    }
2623
2624                    /*
2625                     * If the package is scanned, it's not erased.
2626                     */
2627                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2628                    if (scannedPkg != null) {
2629                        /*
2630                         * If the system app is both scanned and in the
2631                         * disabled packages list, then it must have been
2632                         * added via OTA. Remove it from the currently
2633                         * scanned package so the previously user-installed
2634                         * application can be scanned.
2635                         */
2636                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2637                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2638                                    + ps.name + "; removing system app.  Last known codePath="
2639                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2640                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2641                                    + scannedPkg.mVersionCode);
2642                            removePackageLI(scannedPkg, true);
2643                            mExpectingBetter.put(ps.name, ps.codePath);
2644                        }
2645
2646                        continue;
2647                    }
2648
2649                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2650                        psit.remove();
2651                        logCriticalInfo(Log.WARN, "System package " + ps.name
2652                                + " no longer exists; it's data will be wiped");
2653                        // Actual deletion of code and data will be handled by later
2654                        // reconciliation step
2655                    } else {
2656                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2657                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2658                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2659                        }
2660                    }
2661                }
2662            }
2663
2664            //look for any incomplete package installations
2665            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2666            for (int i = 0; i < deletePkgsList.size(); i++) {
2667                // Actual deletion of code and data will be handled by later
2668                // reconciliation step
2669                final String packageName = deletePkgsList.get(i).name;
2670                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2671                synchronized (mPackages) {
2672                    mSettings.removePackageLPw(packageName);
2673                }
2674            }
2675
2676            //delete tmp files
2677            deleteTempPackageFiles();
2678
2679            // Remove any shared userIDs that have no associated packages
2680            mSettings.pruneSharedUsersLPw();
2681
2682            if (!mOnlyCore) {
2683                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2684                        SystemClock.uptimeMillis());
2685                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2686
2687                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2688                        | PackageParser.PARSE_FORWARD_LOCK,
2689                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2690
2691                /**
2692                 * Remove disable package settings for any updated system
2693                 * apps that were removed via an OTA. If they're not a
2694                 * previously-updated app, remove them completely.
2695                 * Otherwise, just revoke their system-level permissions.
2696                 */
2697                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2698                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2699                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2700
2701                    String msg;
2702                    if (deletedPkg == null) {
2703                        msg = "Updated system package " + deletedAppName
2704                                + " no longer exists; it's data will be wiped";
2705                        // Actual deletion of code and data will be handled by later
2706                        // reconciliation step
2707                    } else {
2708                        msg = "Updated system app + " + deletedAppName
2709                                + " no longer present; removing system privileges for "
2710                                + deletedAppName;
2711
2712                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2713
2714                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2715                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2716                    }
2717                    logCriticalInfo(Log.WARN, msg);
2718                }
2719
2720                /**
2721                 * Make sure all system apps that we expected to appear on
2722                 * the userdata partition actually showed up. If they never
2723                 * appeared, crawl back and revive the system version.
2724                 */
2725                for (int i = 0; i < mExpectingBetter.size(); i++) {
2726                    final String packageName = mExpectingBetter.keyAt(i);
2727                    if (!mPackages.containsKey(packageName)) {
2728                        final File scanFile = mExpectingBetter.valueAt(i);
2729
2730                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2731                                + " but never showed up; reverting to system");
2732
2733                        int reparseFlags = mDefParseFlags;
2734                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2735                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2736                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2737                                    | PackageParser.PARSE_IS_PRIVILEGED;
2738                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2739                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2740                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2741                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2742                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2743                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2744                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2745                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2746                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2747                        } else {
2748                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2749                            continue;
2750                        }
2751
2752                        mSettings.enableSystemPackageLPw(packageName);
2753
2754                        try {
2755                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2756                        } catch (PackageManagerException e) {
2757                            Slog.e(TAG, "Failed to parse original system package: "
2758                                    + e.getMessage());
2759                        }
2760                    }
2761                }
2762            }
2763            mExpectingBetter.clear();
2764
2765            // Resolve the storage manager.
2766            mStorageManagerPackage = getStorageManagerPackageName();
2767
2768            // Resolve protected action filters. Only the setup wizard is allowed to
2769            // have a high priority filter for these actions.
2770            mSetupWizardPackage = getSetupWizardPackageName();
2771            if (mProtectedFilters.size() > 0) {
2772                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2773                    Slog.i(TAG, "No setup wizard;"
2774                        + " All protected intents capped to priority 0");
2775                }
2776                for (ActivityIntentInfo filter : mProtectedFilters) {
2777                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2778                        if (DEBUG_FILTERS) {
2779                            Slog.i(TAG, "Found setup wizard;"
2780                                + " allow priority " + filter.getPriority() + ";"
2781                                + " package: " + filter.activity.info.packageName
2782                                + " activity: " + filter.activity.className
2783                                + " priority: " + filter.getPriority());
2784                        }
2785                        // skip setup wizard; allow it to keep the high priority filter
2786                        continue;
2787                    }
2788                    if (DEBUG_FILTERS) {
2789                        Slog.i(TAG, "Protected action; cap priority to 0;"
2790                                + " package: " + filter.activity.info.packageName
2791                                + " activity: " + filter.activity.className
2792                                + " origPrio: " + filter.getPriority());
2793                    }
2794                    filter.setPriority(0);
2795                }
2796            }
2797            mDeferProtectedFilters = false;
2798            mProtectedFilters.clear();
2799
2800            // Now that we know all of the shared libraries, update all clients to have
2801            // the correct library paths.
2802            updateAllSharedLibrariesLPw(null);
2803
2804            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2805                // NOTE: We ignore potential failures here during a system scan (like
2806                // the rest of the commands above) because there's precious little we
2807                // can do about it. A settings error is reported, though.
2808                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2809            }
2810
2811            // Now that we know all the packages we are keeping,
2812            // read and update their last usage times.
2813            mPackageUsage.read(mPackages);
2814            mCompilerStats.read();
2815
2816            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2817                    SystemClock.uptimeMillis());
2818            Slog.i(TAG, "Time to scan packages: "
2819                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2820                    + " seconds");
2821
2822            // If the platform SDK has changed since the last time we booted,
2823            // we need to re-grant app permission to catch any new ones that
2824            // appear.  This is really a hack, and means that apps can in some
2825            // cases get permissions that the user didn't initially explicitly
2826            // allow...  it would be nice to have some better way to handle
2827            // this situation.
2828            int updateFlags = UPDATE_PERMISSIONS_ALL;
2829            if (ver.sdkVersion != mSdkVersion) {
2830                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2831                        + mSdkVersion + "; regranting permissions for internal storage");
2832                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2833            }
2834            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2835            ver.sdkVersion = mSdkVersion;
2836
2837            // If this is the first boot or an update from pre-M, and it is a normal
2838            // boot, then we need to initialize the default preferred apps across
2839            // all defined users.
2840            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2841                for (UserInfo user : sUserManager.getUsers(true)) {
2842                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2843                    applyFactoryDefaultBrowserLPw(user.id);
2844                    primeDomainVerificationsLPw(user.id);
2845                }
2846            }
2847
2848            // Prepare storage for system user really early during boot,
2849            // since core system apps like SettingsProvider and SystemUI
2850            // can't wait for user to start
2851            final int storageFlags;
2852            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2853                storageFlags = StorageManager.FLAG_STORAGE_DE;
2854            } else {
2855                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2856            }
2857            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2858                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2859                    true /* onlyCoreApps */);
2860            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2861                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2862                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2863                traceLog.traceBegin("AppDataFixup");
2864                try {
2865                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2866                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2867                } catch (InstallerException e) {
2868                    Slog.w(TAG, "Trouble fixing GIDs", e);
2869                }
2870                traceLog.traceEnd();
2871
2872                traceLog.traceBegin("AppDataPrepare");
2873                if (deferPackages == null || deferPackages.isEmpty()) {
2874                    return;
2875                }
2876                int count = 0;
2877                for (String pkgName : deferPackages) {
2878                    PackageParser.Package pkg = null;
2879                    synchronized (mPackages) {
2880                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2881                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2882                            pkg = ps.pkg;
2883                        }
2884                    }
2885                    if (pkg != null) {
2886                        synchronized (mInstallLock) {
2887                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2888                                    true /* maybeMigrateAppData */);
2889                        }
2890                        count++;
2891                    }
2892                }
2893                traceLog.traceEnd();
2894                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2895            }, "prepareAppData");
2896
2897            // If this is first boot after an OTA, and a normal boot, then
2898            // we need to clear code cache directories.
2899            // Note that we do *not* clear the application profiles. These remain valid
2900            // across OTAs and are used to drive profile verification (post OTA) and
2901            // profile compilation (without waiting to collect a fresh set of profiles).
2902            if (mIsUpgrade && !onlyCore) {
2903                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2904                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2905                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2906                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2907                        // No apps are running this early, so no need to freeze
2908                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2909                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2910                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2911                    }
2912                }
2913                ver.fingerprint = Build.FINGERPRINT;
2914            }
2915
2916            checkDefaultBrowser();
2917
2918            // clear only after permissions and other defaults have been updated
2919            mExistingSystemPackages.clear();
2920            mPromoteSystemApps = false;
2921
2922            // All the changes are done during package scanning.
2923            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2924
2925            // can downgrade to reader
2926            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2927            mSettings.writeLPr();
2928            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2929
2930            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2931                    SystemClock.uptimeMillis());
2932
2933            if (!mOnlyCore) {
2934                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2935                mRequiredInstallerPackage = getRequiredInstallerLPr();
2936                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2937                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2938                if (mIntentFilterVerifierComponent != null) {
2939                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2940                            mIntentFilterVerifierComponent);
2941                } else {
2942                    mIntentFilterVerifier = null;
2943                }
2944                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2945                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2946                        SharedLibraryInfo.VERSION_UNDEFINED);
2947                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2948                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2949                        SharedLibraryInfo.VERSION_UNDEFINED);
2950            } else {
2951                mRequiredVerifierPackage = null;
2952                mRequiredInstallerPackage = null;
2953                mRequiredUninstallerPackage = null;
2954                mIntentFilterVerifierComponent = null;
2955                mIntentFilterVerifier = null;
2956                mServicesSystemSharedLibraryPackageName = null;
2957                mSharedSystemSharedLibraryPackageName = null;
2958            }
2959
2960            mInstallerService = new PackageInstallerService(context, this);
2961            final Pair<ComponentName, String> instantAppResolverComponent =
2962                    getInstantAppResolverLPr();
2963            if (instantAppResolverComponent != null) {
2964                if (DEBUG_EPHEMERAL) {
2965                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2966                }
2967                mInstantAppResolverConnection = new EphemeralResolverConnection(
2968                        mContext, instantAppResolverComponent.first,
2969                        instantAppResolverComponent.second);
2970                mInstantAppResolverSettingsComponent =
2971                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2972            } else {
2973                mInstantAppResolverConnection = null;
2974                mInstantAppResolverSettingsComponent = null;
2975            }
2976            updateInstantAppInstallerLocked(null);
2977
2978            // Read and update the usage of dex files.
2979            // Do this at the end of PM init so that all the packages have their
2980            // data directory reconciled.
2981            // At this point we know the code paths of the packages, so we can validate
2982            // the disk file and build the internal cache.
2983            // The usage file is expected to be small so loading and verifying it
2984            // should take a fairly small time compare to the other activities (e.g. package
2985            // scanning).
2986            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
2987            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2988            for (int userId : currentUserIds) {
2989                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
2990            }
2991            mDexManager.load(userPackages);
2992        } // synchronized (mPackages)
2993        } // synchronized (mInstallLock)
2994
2995        // Now after opening every single application zip, make sure they
2996        // are all flushed.  Not really needed, but keeps things nice and
2997        // tidy.
2998        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
2999        Runtime.getRuntime().gc();
3000        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3001
3002        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3003        FallbackCategoryProvider.loadFallbacks();
3004        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3005
3006        // The initial scanning above does many calls into installd while
3007        // holding the mPackages lock, but we're mostly interested in yelling
3008        // once we have a booted system.
3009        mInstaller.setWarnIfHeld(mPackages);
3010
3011        // Expose private service for system components to use.
3012        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3013        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3014    }
3015
3016    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3017        // we're only interested in updating the installer appliction when 1) it's not
3018        // already set or 2) the modified package is the installer
3019        if (mInstantAppInstallerActivity != null
3020                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3021                        .equals(modifiedPackage)) {
3022            return;
3023        }
3024        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3025    }
3026
3027    private static File preparePackageParserCache(boolean isUpgrade) {
3028        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3029            return null;
3030        }
3031
3032        // Disable package parsing on eng builds to allow for faster incremental development.
3033        if ("eng".equals(Build.TYPE)) {
3034            return null;
3035        }
3036
3037        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3038            Slog.i(TAG, "Disabling package parser cache due to system property.");
3039            return null;
3040        }
3041
3042        // The base directory for the package parser cache lives under /data/system/.
3043        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3044                "package_cache");
3045        if (cacheBaseDir == null) {
3046            return null;
3047        }
3048
3049        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3050        // This also serves to "GC" unused entries when the package cache version changes (which
3051        // can only happen during upgrades).
3052        if (isUpgrade) {
3053            FileUtils.deleteContents(cacheBaseDir);
3054        }
3055
3056
3057        // Return the versioned package cache directory. This is something like
3058        // "/data/system/package_cache/1"
3059        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3060
3061        // The following is a workaround to aid development on non-numbered userdebug
3062        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3063        // the system partition is newer.
3064        //
3065        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3066        // that starts with "eng." to signify that this is an engineering build and not
3067        // destined for release.
3068        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3069            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3070
3071            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3072            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3073            // in general and should not be used for production changes. In this specific case,
3074            // we know that they will work.
3075            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3076            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3077                FileUtils.deleteContents(cacheBaseDir);
3078                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3079            }
3080        }
3081
3082        return cacheDir;
3083    }
3084
3085    @Override
3086    public boolean isFirstBoot() {
3087        return mFirstBoot;
3088    }
3089
3090    @Override
3091    public boolean isOnlyCoreApps() {
3092        return mOnlyCore;
3093    }
3094
3095    @Override
3096    public boolean isUpgrade() {
3097        return mIsUpgrade;
3098    }
3099
3100    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3101        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3102
3103        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3104                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3105                UserHandle.USER_SYSTEM);
3106        if (matches.size() == 1) {
3107            return matches.get(0).getComponentInfo().packageName;
3108        } else if (matches.size() == 0) {
3109            Log.e(TAG, "There should probably be a verifier, but, none were found");
3110            return null;
3111        }
3112        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3113    }
3114
3115    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3116        synchronized (mPackages) {
3117            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3118            if (libraryEntry == null) {
3119                throw new IllegalStateException("Missing required shared library:" + name);
3120            }
3121            return libraryEntry.apk;
3122        }
3123    }
3124
3125    private @NonNull String getRequiredInstallerLPr() {
3126        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3127        intent.addCategory(Intent.CATEGORY_DEFAULT);
3128        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3129
3130        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3131                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3132                UserHandle.USER_SYSTEM);
3133        if (matches.size() == 1) {
3134            ResolveInfo resolveInfo = matches.get(0);
3135            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3136                throw new RuntimeException("The installer must be a privileged app");
3137            }
3138            return matches.get(0).getComponentInfo().packageName;
3139        } else {
3140            throw new RuntimeException("There must be exactly one installer; found " + matches);
3141        }
3142    }
3143
3144    private @NonNull String getRequiredUninstallerLPr() {
3145        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3146        intent.addCategory(Intent.CATEGORY_DEFAULT);
3147        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3148
3149        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3150                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3151                UserHandle.USER_SYSTEM);
3152        if (resolveInfo == null ||
3153                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3154            throw new RuntimeException("There must be exactly one uninstaller; found "
3155                    + resolveInfo);
3156        }
3157        return resolveInfo.getComponentInfo().packageName;
3158    }
3159
3160    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3161        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3162
3163        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3164                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3165                UserHandle.USER_SYSTEM);
3166        ResolveInfo best = null;
3167        final int N = matches.size();
3168        for (int i = 0; i < N; i++) {
3169            final ResolveInfo cur = matches.get(i);
3170            final String packageName = cur.getComponentInfo().packageName;
3171            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3172                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3173                continue;
3174            }
3175
3176            if (best == null || cur.priority > best.priority) {
3177                best = cur;
3178            }
3179        }
3180
3181        if (best != null) {
3182            return best.getComponentInfo().getComponentName();
3183        }
3184        Slog.w(TAG, "Intent filter verifier not found");
3185        return null;
3186    }
3187
3188    @Override
3189    public @Nullable ComponentName getInstantAppResolverComponent() {
3190        synchronized (mPackages) {
3191            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3192            if (instantAppResolver == null) {
3193                return null;
3194            }
3195            return instantAppResolver.first;
3196        }
3197    }
3198
3199    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3200        final String[] packageArray =
3201                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3202        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3203            if (DEBUG_EPHEMERAL) {
3204                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3205            }
3206            return null;
3207        }
3208
3209        final int callingUid = Binder.getCallingUid();
3210        final int resolveFlags =
3211                MATCH_DIRECT_BOOT_AWARE
3212                | MATCH_DIRECT_BOOT_UNAWARE
3213                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3214        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3215        final Intent resolverIntent = new Intent(actionName);
3216        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3217                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3218        // temporarily look for the old action
3219        if (resolvers.size() == 0) {
3220            if (DEBUG_EPHEMERAL) {
3221                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3222            }
3223            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3224            resolverIntent.setAction(actionName);
3225            resolvers = queryIntentServicesInternal(resolverIntent, null,
3226                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3227        }
3228        final int N = resolvers.size();
3229        if (N == 0) {
3230            if (DEBUG_EPHEMERAL) {
3231                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3232            }
3233            return null;
3234        }
3235
3236        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3237        for (int i = 0; i < N; i++) {
3238            final ResolveInfo info = resolvers.get(i);
3239
3240            if (info.serviceInfo == null) {
3241                continue;
3242            }
3243
3244            final String packageName = info.serviceInfo.packageName;
3245            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3246                if (DEBUG_EPHEMERAL) {
3247                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3248                            + " pkg: " + packageName + ", info:" + info);
3249                }
3250                continue;
3251            }
3252
3253            if (DEBUG_EPHEMERAL) {
3254                Slog.v(TAG, "Ephemeral resolver found;"
3255                        + " pkg: " + packageName + ", info:" + info);
3256            }
3257            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3258        }
3259        if (DEBUG_EPHEMERAL) {
3260            Slog.v(TAG, "Ephemeral resolver NOT found");
3261        }
3262        return null;
3263    }
3264
3265    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3266        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3267        intent.addCategory(Intent.CATEGORY_DEFAULT);
3268        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3269
3270        final int resolveFlags =
3271                MATCH_DIRECT_BOOT_AWARE
3272                | MATCH_DIRECT_BOOT_UNAWARE
3273                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3274        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3275                resolveFlags, UserHandle.USER_SYSTEM);
3276        // temporarily look for the old action
3277        if (matches.isEmpty()) {
3278            if (DEBUG_EPHEMERAL) {
3279                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3280            }
3281            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3282            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3283                    resolveFlags, UserHandle.USER_SYSTEM);
3284        }
3285        Iterator<ResolveInfo> iter = matches.iterator();
3286        while (iter.hasNext()) {
3287            final ResolveInfo rInfo = iter.next();
3288            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3289            if (ps != null) {
3290                final PermissionsState permissionsState = ps.getPermissionsState();
3291                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3292                    continue;
3293                }
3294            }
3295            iter.remove();
3296        }
3297        if (matches.size() == 0) {
3298            return null;
3299        } else if (matches.size() == 1) {
3300            return (ActivityInfo) matches.get(0).getComponentInfo();
3301        } else {
3302            throw new RuntimeException(
3303                    "There must be at most one ephemeral installer; found " + matches);
3304        }
3305    }
3306
3307    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3308            @NonNull ComponentName resolver) {
3309        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3310                .addCategory(Intent.CATEGORY_DEFAULT)
3311                .setPackage(resolver.getPackageName());
3312        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3313        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3314                UserHandle.USER_SYSTEM);
3315        // temporarily look for the old action
3316        if (matches.isEmpty()) {
3317            if (DEBUG_EPHEMERAL) {
3318                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3319            }
3320            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3321            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3322                    UserHandle.USER_SYSTEM);
3323        }
3324        if (matches.isEmpty()) {
3325            return null;
3326        }
3327        return matches.get(0).getComponentInfo().getComponentName();
3328    }
3329
3330    private void primeDomainVerificationsLPw(int userId) {
3331        if (DEBUG_DOMAIN_VERIFICATION) {
3332            Slog.d(TAG, "Priming domain verifications in user " + userId);
3333        }
3334
3335        SystemConfig systemConfig = SystemConfig.getInstance();
3336        ArraySet<String> packages = systemConfig.getLinkedApps();
3337
3338        for (String packageName : packages) {
3339            PackageParser.Package pkg = mPackages.get(packageName);
3340            if (pkg != null) {
3341                if (!pkg.isSystemApp()) {
3342                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3343                    continue;
3344                }
3345
3346                ArraySet<String> domains = null;
3347                for (PackageParser.Activity a : pkg.activities) {
3348                    for (ActivityIntentInfo filter : a.intents) {
3349                        if (hasValidDomains(filter)) {
3350                            if (domains == null) {
3351                                domains = new ArraySet<String>();
3352                            }
3353                            domains.addAll(filter.getHostsList());
3354                        }
3355                    }
3356                }
3357
3358                if (domains != null && domains.size() > 0) {
3359                    if (DEBUG_DOMAIN_VERIFICATION) {
3360                        Slog.v(TAG, "      + " + packageName);
3361                    }
3362                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3363                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3364                    // and then 'always' in the per-user state actually used for intent resolution.
3365                    final IntentFilterVerificationInfo ivi;
3366                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3367                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3368                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3369                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3370                } else {
3371                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3372                            + "' does not handle web links");
3373                }
3374            } else {
3375                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3376            }
3377        }
3378
3379        scheduleWritePackageRestrictionsLocked(userId);
3380        scheduleWriteSettingsLocked();
3381    }
3382
3383    private void applyFactoryDefaultBrowserLPw(int userId) {
3384        // The default browser app's package name is stored in a string resource,
3385        // with a product-specific overlay used for vendor customization.
3386        String browserPkg = mContext.getResources().getString(
3387                com.android.internal.R.string.default_browser);
3388        if (!TextUtils.isEmpty(browserPkg)) {
3389            // non-empty string => required to be a known package
3390            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3391            if (ps == null) {
3392                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3393                browserPkg = null;
3394            } else {
3395                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3396            }
3397        }
3398
3399        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3400        // default.  If there's more than one, just leave everything alone.
3401        if (browserPkg == null) {
3402            calculateDefaultBrowserLPw(userId);
3403        }
3404    }
3405
3406    private void calculateDefaultBrowserLPw(int userId) {
3407        List<String> allBrowsers = resolveAllBrowserApps(userId);
3408        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3409        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3410    }
3411
3412    private List<String> resolveAllBrowserApps(int userId) {
3413        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3414        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3415                PackageManager.MATCH_ALL, userId);
3416
3417        final int count = list.size();
3418        List<String> result = new ArrayList<String>(count);
3419        for (int i=0; i<count; i++) {
3420            ResolveInfo info = list.get(i);
3421            if (info.activityInfo == null
3422                    || !info.handleAllWebDataURI
3423                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3424                    || result.contains(info.activityInfo.packageName)) {
3425                continue;
3426            }
3427            result.add(info.activityInfo.packageName);
3428        }
3429
3430        return result;
3431    }
3432
3433    private boolean packageIsBrowser(String packageName, int userId) {
3434        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3435                PackageManager.MATCH_ALL, userId);
3436        final int N = list.size();
3437        for (int i = 0; i < N; i++) {
3438            ResolveInfo info = list.get(i);
3439            if (packageName.equals(info.activityInfo.packageName)) {
3440                return true;
3441            }
3442        }
3443        return false;
3444    }
3445
3446    private void checkDefaultBrowser() {
3447        final int myUserId = UserHandle.myUserId();
3448        final String packageName = getDefaultBrowserPackageName(myUserId);
3449        if (packageName != null) {
3450            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3451            if (info == null) {
3452                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3453                synchronized (mPackages) {
3454                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3455                }
3456            }
3457        }
3458    }
3459
3460    @Override
3461    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3462            throws RemoteException {
3463        try {
3464            return super.onTransact(code, data, reply, flags);
3465        } catch (RuntimeException e) {
3466            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3467                Slog.wtf(TAG, "Package Manager Crash", e);
3468            }
3469            throw e;
3470        }
3471    }
3472
3473    static int[] appendInts(int[] cur, int[] add) {
3474        if (add == null) return cur;
3475        if (cur == null) return add;
3476        final int N = add.length;
3477        for (int i=0; i<N; i++) {
3478            cur = appendInt(cur, add[i]);
3479        }
3480        return cur;
3481    }
3482
3483    /**
3484     * Returns whether or not a full application can see an instant application.
3485     * <p>
3486     * Currently, there are three cases in which this can occur:
3487     * <ol>
3488     * <li>The calling application is a "special" process. The special
3489     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3490     *     and {@code 0}</li>
3491     * <li>The calling application has the permission
3492     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3493     * <li>[TODO] The calling application is the default launcher on the
3494     *     system partition.</li>
3495     * </ol>
3496     */
3497    private boolean canAccessInstantApps(int callingUid) {
3498        final boolean isSpecialProcess =
3499                callingUid == Process.SYSTEM_UID
3500                        || callingUid == Process.SHELL_UID
3501                        || callingUid == 0;
3502        final boolean allowMatchInstant =
3503                isSpecialProcess
3504                        || mContext.checkCallingOrSelfPermission(
3505                        android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED;
3506        return allowMatchInstant;
3507    }
3508    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3509        if (!sUserManager.exists(userId)) return null;
3510        if (ps == null) {
3511            return null;
3512        }
3513        PackageParser.Package p = ps.pkg;
3514        if (p == null) {
3515            return null;
3516        }
3517        final int callingUid =  Binder.getCallingUid();
3518        // Filter out ephemeral app metadata:
3519        //   * The system/shell/root can see metadata for any app
3520        //   * An installed app can see metadata for 1) other installed apps
3521        //     and 2) ephemeral apps that have explicitly interacted with it
3522        //   * Ephemeral apps can only see their own data and exposed installed apps
3523        //   * Holding a signature permission allows seeing instant apps
3524        if (!canAccessInstantApps(callingUid)) {
3525            final String instantAppPackageName = getInstantAppPackageName(callingUid);
3526            if (instantAppPackageName != null) {
3527                // ephemeral apps can only get information on themselves or
3528                // installed apps that are exposed.
3529                if (!instantAppPackageName.equals(p.packageName)
3530                        && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) {
3531                    return null;
3532                }
3533            } else {
3534                if (ps.getInstantApp(userId)) {
3535                    // only get access to the ephemeral app if we've been granted access
3536                    final int callingAppId = UserHandle.getAppId(callingUid);
3537                    if (!mInstantAppRegistry.isInstantAccessGranted(
3538                            userId, callingAppId, ps.appId)) {
3539                        return null;
3540                    }
3541                }
3542            }
3543        }
3544
3545        final PermissionsState permissionsState = ps.getPermissionsState();
3546
3547        // Compute GIDs only if requested
3548        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3549                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3550        // Compute granted permissions only if package has requested permissions
3551        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3552                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3553        final PackageUserState state = ps.readUserState(userId);
3554
3555        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3556                && ps.isSystem()) {
3557            flags |= MATCH_ANY_USER;
3558        }
3559
3560        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3561                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3562
3563        if (packageInfo == null) {
3564            return null;
3565        }
3566
3567        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3568
3569        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3570                resolveExternalPackageNameLPr(p);
3571
3572        return packageInfo;
3573    }
3574
3575    @Override
3576    public void checkPackageStartable(String packageName, int userId) {
3577        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3578
3579        synchronized (mPackages) {
3580            final PackageSetting ps = mSettings.mPackages.get(packageName);
3581            if (ps == null) {
3582                throw new SecurityException("Package " + packageName + " was not found!");
3583            }
3584
3585            if (!ps.getInstalled(userId)) {
3586                throw new SecurityException(
3587                        "Package " + packageName + " was not installed for user " + userId + "!");
3588            }
3589
3590            if (mSafeMode && !ps.isSystem()) {
3591                throw new SecurityException("Package " + packageName + " not a system app!");
3592            }
3593
3594            if (mFrozenPackages.contains(packageName)) {
3595                throw new SecurityException("Package " + packageName + " is currently frozen!");
3596            }
3597
3598            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3599                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3600                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3601            }
3602        }
3603    }
3604
3605    @Override
3606    public boolean isPackageAvailable(String packageName, int userId) {
3607        if (!sUserManager.exists(userId)) return false;
3608        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3609                false /* requireFullPermission */, false /* checkShell */, "is package available");
3610        synchronized (mPackages) {
3611            PackageParser.Package p = mPackages.get(packageName);
3612            if (p != null) {
3613                final PackageSetting ps = (PackageSetting) p.mExtras;
3614                if (ps != null) {
3615                    final PackageUserState state = ps.readUserState(userId);
3616                    if (state != null) {
3617                        return PackageParser.isAvailable(state);
3618                    }
3619                }
3620            }
3621        }
3622        return false;
3623    }
3624
3625    @Override
3626    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3627        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3628                flags, userId);
3629    }
3630
3631    @Override
3632    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3633            int flags, int userId) {
3634        return getPackageInfoInternal(versionedPackage.getPackageName(),
3635                versionedPackage.getVersionCode(), flags, userId);
3636    }
3637
3638    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3639            int flags, int userId) {
3640        if (!sUserManager.exists(userId)) return null;
3641        final int callingUid = Binder.getCallingUid();
3642        flags = updateFlagsForPackage(flags, userId, packageName);
3643        enforceCrossUserPermission(callingUid, userId,
3644                false /* requireFullPermission */, false /* checkShell */, "get package info");
3645
3646        // reader
3647        synchronized (mPackages) {
3648            // Normalize package name to handle renamed packages and static libs
3649            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3650
3651            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3652            if (matchFactoryOnly) {
3653                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3654                if (ps != null) {
3655                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3656                        return null;
3657                    }
3658                    if (filterAppAccessLPr(ps, callingUid, userId)) {
3659                        return null;
3660                    }
3661                    return generatePackageInfo(ps, flags, userId);
3662                }
3663            }
3664
3665            PackageParser.Package p = mPackages.get(packageName);
3666            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3667                return null;
3668            }
3669            if (DEBUG_PACKAGE_INFO)
3670                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3671            if (p != null) {
3672                final PackageSetting ps = (PackageSetting) p.mExtras;
3673                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3674                    return null;
3675                }
3676                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
3677                    return null;
3678                }
3679                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3680            }
3681            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3682                final PackageSetting ps = mSettings.mPackages.get(packageName);
3683                if (ps == null) return null;
3684                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3685                    return null;
3686                }
3687                if (filterAppAccessLPr(ps, callingUid, userId)) {
3688                    return null;
3689                }
3690                return generatePackageInfo(ps, flags, userId);
3691            }
3692        }
3693        return null;
3694    }
3695
3696    /**
3697     * Returns whether or not access to the application should be filtered.
3698     * <p>
3699     * Access may be limited based upon whether the calling or target applications
3700     * are instant applications.
3701     *
3702     * @see #canAccessInstantApps(int)
3703     */
3704    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid,
3705            @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) {
3706        // if we're in an isolated process, get the real calling UID
3707        if (Process.isIsolated(callingUid)) {
3708            callingUid = mIsolatedOwners.get(callingUid);
3709        }
3710        // if the target and caller are the same application, don't filter
3711        if (isCallerSameApp(ps.name, callingUid)) {
3712            return false;
3713        }
3714        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3715        final boolean callerIsInstantApp = instantAppPkgName != null;
3716        if (callerIsInstantApp) {
3717            // request for a specific component; if it hasn't been explicitly exposed, filter
3718            if (component != null) {
3719                return !componentVisibleToInstantApp;
3720            }
3721            // request for application; if no components have been explicitly exposed, filter
3722            return !ps.pkg.visibleToInstantApps;
3723        }
3724        if (ps.getInstantApp(userId)) {
3725            // caller can see all components of all instant applications, don't filter
3726            if (canAccessInstantApps(callingUid)) {
3727                return false;
3728            }
3729            // request for a specific instant application component, filter
3730            if (component != null) {
3731                return true;
3732            }
3733            // request for an instant application; if the caller hasn't been granted access, filter
3734            return !mInstantAppRegistry.isInstantAccessGranted(
3735                    userId, UserHandle.getAppId(callingUid), ps.appId);
3736        }
3737        return false;
3738    }
3739
3740    /**
3741     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
3742     */
3743    private boolean filterAppAccessLPr(@NonNull PackageSetting ps, int callingUid, int userId) {
3744        return filterAppAccessLPr(ps, callingUid, null, false, userId);
3745    }
3746
3747    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
3748            int flags) {
3749        // Callers can access only the libs they depend on, otherwise they need to explicitly
3750        // ask for the shared libraries given the caller is allowed to access all static libs.
3751        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3752            // System/shell/root get to see all static libs
3753            final int appId = UserHandle.getAppId(uid);
3754            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3755                    || appId == Process.ROOT_UID) {
3756                return false;
3757            }
3758        }
3759
3760        // No package means no static lib as it is always on internal storage
3761        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3762            return false;
3763        }
3764
3765        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3766                ps.pkg.staticSharedLibVersion);
3767        if (libEntry == null) {
3768            return false;
3769        }
3770
3771        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3772        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3773        if (uidPackageNames == null) {
3774            return true;
3775        }
3776
3777        for (String uidPackageName : uidPackageNames) {
3778            if (ps.name.equals(uidPackageName)) {
3779                return false;
3780            }
3781            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3782            if (uidPs != null) {
3783                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3784                        libEntry.info.getName());
3785                if (index < 0) {
3786                    continue;
3787                }
3788                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3789                    return false;
3790                }
3791            }
3792        }
3793        return true;
3794    }
3795
3796    @Override
3797    public String[] currentToCanonicalPackageNames(String[] names) {
3798        String[] out = new String[names.length];
3799        // reader
3800        synchronized (mPackages) {
3801            for (int i=names.length-1; i>=0; i--) {
3802                PackageSetting ps = mSettings.mPackages.get(names[i]);
3803                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3804            }
3805        }
3806        return out;
3807    }
3808
3809    @Override
3810    public String[] canonicalToCurrentPackageNames(String[] names) {
3811        String[] out = new String[names.length];
3812        // reader
3813        synchronized (mPackages) {
3814            for (int i=names.length-1; i>=0; i--) {
3815                String cur = mSettings.getRenamedPackageLPr(names[i]);
3816                out[i] = cur != null ? cur : names[i];
3817            }
3818        }
3819        return out;
3820    }
3821
3822    @Override
3823    public int getPackageUid(String packageName, int flags, int userId) {
3824        if (!sUserManager.exists(userId)) return -1;
3825        flags = updateFlagsForPackage(flags, userId, packageName);
3826        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3827                false /* requireFullPermission */, false /* checkShell */, "get package uid");
3828
3829        // reader
3830        synchronized (mPackages) {
3831            final PackageParser.Package p = mPackages.get(packageName);
3832            if (p != null && p.isMatch(flags)) {
3833                return UserHandle.getUid(userId, p.applicationInfo.uid);
3834            }
3835            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3836                final PackageSetting ps = mSettings.mPackages.get(packageName);
3837                if (ps != null && ps.isMatch(flags)) {
3838                    return UserHandle.getUid(userId, ps.appId);
3839                }
3840            }
3841        }
3842
3843        return -1;
3844    }
3845
3846    @Override
3847    public int[] getPackageGids(String packageName, int flags, int userId) {
3848        if (!sUserManager.exists(userId)) return null;
3849        flags = updateFlagsForPackage(flags, userId, packageName);
3850        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3851                false /* requireFullPermission */, false /* checkShell */,
3852                "getPackageGids");
3853
3854        // reader
3855        synchronized (mPackages) {
3856            final PackageParser.Package p = mPackages.get(packageName);
3857            if (p != null && p.isMatch(flags)) {
3858                PackageSetting ps = (PackageSetting) p.mExtras;
3859                // TODO: Shouldn't this be checking for package installed state for userId and
3860                // return null?
3861                return ps.getPermissionsState().computeGids(userId);
3862            }
3863            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3864                final PackageSetting ps = mSettings.mPackages.get(packageName);
3865                if (ps != null && ps.isMatch(flags)) {
3866                    return ps.getPermissionsState().computeGids(userId);
3867                }
3868            }
3869        }
3870
3871        return null;
3872    }
3873
3874    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3875        if (bp.perm != null) {
3876            return PackageParser.generatePermissionInfo(bp.perm, flags);
3877        }
3878        PermissionInfo pi = new PermissionInfo();
3879        pi.name = bp.name;
3880        pi.packageName = bp.sourcePackage;
3881        pi.nonLocalizedLabel = bp.name;
3882        pi.protectionLevel = bp.protectionLevel;
3883        return pi;
3884    }
3885
3886    @Override
3887    public PermissionInfo getPermissionInfo(String name, int flags) {
3888        // reader
3889        synchronized (mPackages) {
3890            final BasePermission p = mSettings.mPermissions.get(name);
3891            if (p != null) {
3892                return generatePermissionInfo(p, flags);
3893            }
3894            return null;
3895        }
3896    }
3897
3898    @Override
3899    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3900            int flags) {
3901        // reader
3902        synchronized (mPackages) {
3903            if (group != null && !mPermissionGroups.containsKey(group)) {
3904                // This is thrown as NameNotFoundException
3905                return null;
3906            }
3907
3908            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
3909            for (BasePermission p : mSettings.mPermissions.values()) {
3910                if (group == null) {
3911                    if (p.perm == null || p.perm.info.group == null) {
3912                        out.add(generatePermissionInfo(p, flags));
3913                    }
3914                } else {
3915                    if (p.perm != null && group.equals(p.perm.info.group)) {
3916                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
3917                    }
3918                }
3919            }
3920            return new ParceledListSlice<>(out);
3921        }
3922    }
3923
3924    @Override
3925    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
3926        // reader
3927        synchronized (mPackages) {
3928            return PackageParser.generatePermissionGroupInfo(
3929                    mPermissionGroups.get(name), flags);
3930        }
3931    }
3932
3933    @Override
3934    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
3935        // reader
3936        synchronized (mPackages) {
3937            final int N = mPermissionGroups.size();
3938            ArrayList<PermissionGroupInfo> out
3939                    = new ArrayList<PermissionGroupInfo>(N);
3940            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
3941                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
3942            }
3943            return new ParceledListSlice<>(out);
3944        }
3945    }
3946
3947    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
3948            int uid, int userId) {
3949        if (!sUserManager.exists(userId)) return null;
3950        PackageSetting ps = mSettings.mPackages.get(packageName);
3951        if (ps != null) {
3952            if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
3953                return null;
3954            }
3955            if (filterAppAccessLPr(ps, uid, userId)) {
3956                return null;
3957            }
3958            if (ps.pkg == null) {
3959                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
3960                if (pInfo != null) {
3961                    return pInfo.applicationInfo;
3962                }
3963                return null;
3964            }
3965            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3966                    ps.readUserState(userId), userId);
3967            if (ai != null) {
3968                rebaseEnabledOverlays(ai, userId);
3969                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
3970            }
3971            return ai;
3972        }
3973        return null;
3974    }
3975
3976    @Override
3977    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
3978        if (!sUserManager.exists(userId)) return null;
3979        flags = updateFlagsForApplication(flags, userId, packageName);
3980        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3981                false /* requireFullPermission */, false /* checkShell */, "get application info");
3982
3983        // writer
3984        synchronized (mPackages) {
3985            // Normalize package name to handle renamed packages and static libs
3986            packageName = resolveInternalPackageNameLPr(packageName,
3987                    PackageManager.VERSION_CODE_HIGHEST);
3988
3989            PackageParser.Package p = mPackages.get(packageName);
3990            if (DEBUG_PACKAGE_INFO) Log.v(
3991                    TAG, "getApplicationInfo " + packageName
3992                    + ": " + p);
3993            if (p != null) {
3994                PackageSetting ps = mSettings.mPackages.get(packageName);
3995                if (ps == null) return null;
3996                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
3997                    return null;
3998                }
3999                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
4000                    return null;
4001                }
4002                // Note: isEnabledLP() does not apply here - always return info
4003                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4004                        p, flags, ps.readUserState(userId), userId);
4005                if (ai != null) {
4006                    rebaseEnabledOverlays(ai, userId);
4007                    ai.packageName = resolveExternalPackageNameLPr(p);
4008                }
4009                return ai;
4010            }
4011            if ("android".equals(packageName)||"system".equals(packageName)) {
4012                return mAndroidApplication;
4013            }
4014            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4015                // Already generates the external package name
4016                return generateApplicationInfoFromSettingsLPw(packageName,
4017                        Binder.getCallingUid(), flags, userId);
4018            }
4019        }
4020        return null;
4021    }
4022
4023    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
4024        List<String> paths = new ArrayList<>();
4025        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
4026            mEnabledOverlayPaths.get(userId);
4027        if (userSpecificOverlays != null) {
4028            if (!"android".equals(ai.packageName)) {
4029                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
4030                if (frameworkOverlays != null) {
4031                    paths.addAll(frameworkOverlays);
4032                }
4033            }
4034
4035            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
4036            if (appOverlays != null) {
4037                paths.addAll(appOverlays);
4038            }
4039        }
4040        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
4041    }
4042
4043    private String normalizePackageNameLPr(String packageName) {
4044        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4045        return normalizedPackageName != null ? normalizedPackageName : packageName;
4046    }
4047
4048    @Override
4049    public void deletePreloadsFileCache() {
4050        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4051            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4052        }
4053        File dir = Environment.getDataPreloadsFileCacheDirectory();
4054        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4055        FileUtils.deleteContents(dir);
4056    }
4057
4058    @Override
4059    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4060            final IPackageDataObserver observer) {
4061        mContext.enforceCallingOrSelfPermission(
4062                android.Manifest.permission.CLEAR_APP_CACHE, null);
4063        mHandler.post(() -> {
4064            boolean success = false;
4065            try {
4066                freeStorage(volumeUuid, freeStorageSize, 0);
4067                success = true;
4068            } catch (IOException e) {
4069                Slog.w(TAG, e);
4070            }
4071            if (observer != null) {
4072                try {
4073                    observer.onRemoveCompleted(null, success);
4074                } catch (RemoteException e) {
4075                    Slog.w(TAG, e);
4076                }
4077            }
4078        });
4079    }
4080
4081    @Override
4082    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4083            final IntentSender pi) {
4084        mContext.enforceCallingOrSelfPermission(
4085                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4086        mHandler.post(() -> {
4087            boolean success = false;
4088            try {
4089                freeStorage(volumeUuid, freeStorageSize, 0);
4090                success = true;
4091            } catch (IOException e) {
4092                Slog.w(TAG, e);
4093            }
4094            if (pi != null) {
4095                try {
4096                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4097                } catch (SendIntentException e) {
4098                    Slog.w(TAG, e);
4099                }
4100            }
4101        });
4102    }
4103
4104    /**
4105     * Blocking call to clear various types of cached data across the system
4106     * until the requested bytes are available.
4107     */
4108    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4109        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4110        final File file = storage.findPathForUuid(volumeUuid);
4111        if (file.getUsableSpace() >= bytes) return;
4112
4113        if (ENABLE_FREE_CACHE_V2) {
4114            final boolean aggressive = (storageFlags
4115                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4116            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4117                    volumeUuid);
4118
4119            // 1. Pre-flight to determine if we have any chance to succeed
4120            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4121            if (internalVolume && (aggressive || SystemProperties
4122                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4123                deletePreloadsFileCache();
4124                if (file.getUsableSpace() >= bytes) return;
4125            }
4126
4127            // 3. Consider parsed APK data (aggressive only)
4128            if (internalVolume && aggressive) {
4129                FileUtils.deleteContents(mCacheDir);
4130                if (file.getUsableSpace() >= bytes) return;
4131            }
4132
4133            // 4. Consider cached app data (above quotas)
4134            try {
4135                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
4136            } catch (InstallerException ignored) {
4137            }
4138            if (file.getUsableSpace() >= bytes) return;
4139
4140            // 5. Consider shared libraries with refcount=0 and age>2h
4141            // 6. Consider dexopt output (aggressive only)
4142            // 7. Consider ephemeral apps not used in last week
4143
4144            // 8. Consider cached app data (below quotas)
4145            try {
4146                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
4147                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4148            } catch (InstallerException ignored) {
4149            }
4150            if (file.getUsableSpace() >= bytes) return;
4151
4152            // 9. Consider DropBox entries
4153            // 10. Consider ephemeral cookies
4154
4155        } else {
4156            try {
4157                mInstaller.freeCache(volumeUuid, bytes, 0);
4158            } catch (InstallerException ignored) {
4159            }
4160            if (file.getUsableSpace() >= bytes) return;
4161        }
4162
4163        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4164    }
4165
4166    /**
4167     * Update given flags based on encryption status of current user.
4168     */
4169    private int updateFlags(int flags, int userId) {
4170        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4171                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4172            // Caller expressed an explicit opinion about what encryption
4173            // aware/unaware components they want to see, so fall through and
4174            // give them what they want
4175        } else {
4176            // Caller expressed no opinion, so match based on user state
4177            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4178                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4179            } else {
4180                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4181            }
4182        }
4183        return flags;
4184    }
4185
4186    private UserManagerInternal getUserManagerInternal() {
4187        if (mUserManagerInternal == null) {
4188            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4189        }
4190        return mUserManagerInternal;
4191    }
4192
4193    private DeviceIdleController.LocalService getDeviceIdleController() {
4194        if (mDeviceIdleController == null) {
4195            mDeviceIdleController =
4196                    LocalServices.getService(DeviceIdleController.LocalService.class);
4197        }
4198        return mDeviceIdleController;
4199    }
4200
4201    /**
4202     * Update given flags when being used to request {@link PackageInfo}.
4203     */
4204    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4205        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4206        boolean triaged = true;
4207        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4208                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4209            // Caller is asking for component details, so they'd better be
4210            // asking for specific encryption matching behavior, or be triaged
4211            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4212                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4213                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4214                triaged = false;
4215            }
4216        }
4217        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4218                | PackageManager.MATCH_SYSTEM_ONLY
4219                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4220            triaged = false;
4221        }
4222        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4223            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4224                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4225                    + Debug.getCallers(5));
4226        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4227                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4228            // If the caller wants all packages and has a restricted profile associated with it,
4229            // then match all users. This is to make sure that launchers that need to access work
4230            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4231            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4232            flags |= PackageManager.MATCH_ANY_USER;
4233        }
4234        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4235            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4236                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4237        }
4238        return updateFlags(flags, userId);
4239    }
4240
4241    /**
4242     * Update given flags when being used to request {@link ApplicationInfo}.
4243     */
4244    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4245        return updateFlagsForPackage(flags, userId, cookie);
4246    }
4247
4248    /**
4249     * Update given flags when being used to request {@link ComponentInfo}.
4250     */
4251    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4252        if (cookie instanceof Intent) {
4253            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4254                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4255            }
4256        }
4257
4258        boolean triaged = true;
4259        // Caller is asking for component details, so they'd better be
4260        // asking for specific encryption matching behavior, or be triaged
4261        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4262                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4263                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4264            triaged = false;
4265        }
4266        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4267            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4268                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4269        }
4270
4271        return updateFlags(flags, userId);
4272    }
4273
4274    /**
4275     * Update given intent when being used to request {@link ResolveInfo}.
4276     */
4277    private Intent updateIntentForResolve(Intent intent) {
4278        if (intent.getSelector() != null) {
4279            intent = intent.getSelector();
4280        }
4281        if (DEBUG_PREFERRED) {
4282            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4283        }
4284        return intent;
4285    }
4286
4287    /**
4288     * Update given flags when being used to request {@link ResolveInfo}.
4289     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4290     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4291     * flag set. However, this flag is only honoured in three circumstances:
4292     * <ul>
4293     * <li>when called from a system process</li>
4294     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4295     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4296     * action and a {@code android.intent.category.BROWSABLE} category</li>
4297     * </ul>
4298     */
4299    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4300        return updateFlagsForResolve(flags, userId, intent, callingUid,
4301                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4302    }
4303    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4304            boolean wantInstantApps) {
4305        return updateFlagsForResolve(flags, userId, intent, callingUid,
4306                wantInstantApps, false /*onlyExposedExplicitly*/);
4307    }
4308    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4309            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4310        // Safe mode means we shouldn't match any third-party components
4311        if (mSafeMode) {
4312            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4313        }
4314        if (getInstantAppPackageName(callingUid) != null) {
4315            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4316            if (onlyExposedExplicitly) {
4317                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4318            }
4319            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4320            flags |= PackageManager.MATCH_INSTANT;
4321        } else {
4322            final boolean allowMatchInstant =
4323                    (wantInstantApps
4324                            && Intent.ACTION_VIEW.equals(intent.getAction())
4325                            && hasWebURI(intent))
4326                    || canAccessInstantApps(callingUid);
4327            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4328                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4329            if (!allowMatchInstant) {
4330                flags &= ~PackageManager.MATCH_INSTANT;
4331            }
4332        }
4333        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4334    }
4335
4336    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4337            int userId) {
4338        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4339        if (ret != null) {
4340            rebaseEnabledOverlays(ret.applicationInfo, userId);
4341        }
4342        return ret;
4343    }
4344
4345    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4346            PackageUserState state, int userId) {
4347        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4348        if (ai != null) {
4349            rebaseEnabledOverlays(ai.applicationInfo, userId);
4350        }
4351        return ai;
4352    }
4353
4354    @Override
4355    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4356        if (!sUserManager.exists(userId)) return null;
4357        final int callingUid = Binder.getCallingUid();
4358        flags = updateFlagsForComponent(flags, userId, component);
4359        enforceCrossUserPermission(callingUid, userId,
4360                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4361        synchronized (mPackages) {
4362            PackageParser.Activity a = mActivities.mActivities.get(component);
4363
4364            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4365            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4366                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4367                if (ps == null) return null;
4368                final boolean visibleToInstantApp =
4369                        (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4370                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4371                    return null;
4372                }
4373                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4374            }
4375            if (mResolveComponentName.equals(component)) {
4376                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4377                        userId);
4378            }
4379        }
4380        return null;
4381    }
4382
4383    @Override
4384    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4385            String resolvedType) {
4386        synchronized (mPackages) {
4387            if (component.equals(mResolveComponentName)) {
4388                // The resolver supports EVERYTHING!
4389                return true;
4390            }
4391            PackageParser.Activity a = mActivities.mActivities.get(component);
4392            if (a == null) {
4393                return false;
4394            }
4395            for (int i=0; i<a.intents.size(); i++) {
4396                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4397                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4398                    return true;
4399                }
4400            }
4401            return false;
4402        }
4403    }
4404
4405    @Override
4406    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4407        if (!sUserManager.exists(userId)) return null;
4408        flags = updateFlagsForComponent(flags, userId, component);
4409        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4410                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4411        synchronized (mPackages) {
4412            PackageParser.Activity a = mReceivers.mActivities.get(component);
4413            if (DEBUG_PACKAGE_INFO) Log.v(
4414                TAG, "getReceiverInfo " + component + ": " + a);
4415            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4416                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4417                if (ps == null) return null;
4418                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4419            }
4420        }
4421        return null;
4422    }
4423
4424    @Override
4425    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4426            int flags, int userId) {
4427        if (!sUserManager.exists(userId)) return null;
4428        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4429
4430        flags = updateFlagsForPackage(flags, userId, null);
4431
4432        final boolean canSeeStaticLibraries =
4433                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4434                        == PERMISSION_GRANTED
4435                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4436                        == PERMISSION_GRANTED
4437                || canRequestPackageInstallsInternal(packageName,
4438                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4439                        false  /* throwIfPermNotDeclared*/)
4440                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4441                        == PERMISSION_GRANTED;
4442
4443        synchronized (mPackages) {
4444            List<SharedLibraryInfo> result = null;
4445
4446            final int libCount = mSharedLibraries.size();
4447            for (int i = 0; i < libCount; i++) {
4448                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4449                if (versionedLib == null) {
4450                    continue;
4451                }
4452
4453                final int versionCount = versionedLib.size();
4454                for (int j = 0; j < versionCount; j++) {
4455                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4456                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4457                        break;
4458                    }
4459                    final long identity = Binder.clearCallingIdentity();
4460                    try {
4461                        PackageInfo packageInfo = getPackageInfoVersioned(
4462                                libInfo.getDeclaringPackage(), flags
4463                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4464                        if (packageInfo == null) {
4465                            continue;
4466                        }
4467                    } finally {
4468                        Binder.restoreCallingIdentity(identity);
4469                    }
4470
4471                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4472                            libInfo.getVersion(), libInfo.getType(),
4473                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4474                            flags, userId));
4475
4476                    if (result == null) {
4477                        result = new ArrayList<>();
4478                    }
4479                    result.add(resLibInfo);
4480                }
4481            }
4482
4483            return result != null ? new ParceledListSlice<>(result) : null;
4484        }
4485    }
4486
4487    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4488            SharedLibraryInfo libInfo, int flags, int userId) {
4489        List<VersionedPackage> versionedPackages = null;
4490        final int packageCount = mSettings.mPackages.size();
4491        for (int i = 0; i < packageCount; i++) {
4492            PackageSetting ps = mSettings.mPackages.valueAt(i);
4493
4494            if (ps == null) {
4495                continue;
4496            }
4497
4498            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4499                continue;
4500            }
4501
4502            final String libName = libInfo.getName();
4503            if (libInfo.isStatic()) {
4504                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4505                if (libIdx < 0) {
4506                    continue;
4507                }
4508                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4509                    continue;
4510                }
4511                if (versionedPackages == null) {
4512                    versionedPackages = new ArrayList<>();
4513                }
4514                // If the dependent is a static shared lib, use the public package name
4515                String dependentPackageName = ps.name;
4516                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4517                    dependentPackageName = ps.pkg.manifestPackageName;
4518                }
4519                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4520            } else if (ps.pkg != null) {
4521                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4522                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4523                    if (versionedPackages == null) {
4524                        versionedPackages = new ArrayList<>();
4525                    }
4526                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4527                }
4528            }
4529        }
4530
4531        return versionedPackages;
4532    }
4533
4534    @Override
4535    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4536        if (!sUserManager.exists(userId)) return null;
4537        final int callingUid = Binder.getCallingUid();
4538        flags = updateFlagsForComponent(flags, userId, component);
4539        enforceCrossUserPermission(callingUid, userId,
4540                false /* requireFullPermission */, false /* checkShell */, "get service info");
4541        synchronized (mPackages) {
4542            PackageParser.Service s = mServices.mServices.get(component);
4543            if (DEBUG_PACKAGE_INFO) Log.v(
4544                TAG, "getServiceInfo " + component + ": " + s);
4545            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4546                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4547                if (ps == null) return null;
4548                final boolean visibleToInstantApp =
4549                        (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4550                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4551                    return null;
4552                }
4553                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4554                        ps.readUserState(userId), userId);
4555                if (si != null) {
4556                    rebaseEnabledOverlays(si.applicationInfo, userId);
4557                }
4558                return si;
4559            }
4560        }
4561        return null;
4562    }
4563
4564    @Override
4565    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4566        if (!sUserManager.exists(userId)) return null;
4567        final int callingUid = Binder.getCallingUid();
4568        flags = updateFlagsForComponent(flags, userId, component);
4569        enforceCrossUserPermission(callingUid, userId,
4570                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4571        synchronized (mPackages) {
4572            PackageParser.Provider p = mProviders.mProviders.get(component);
4573            if (DEBUG_PACKAGE_INFO) Log.v(
4574                TAG, "getProviderInfo " + component + ": " + p);
4575            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4576                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4577                if (ps == null) return null;
4578                final boolean visibleToInstantApp =
4579                        (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4580                if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) {
4581                    return null;
4582                }
4583                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4584                        ps.readUserState(userId), userId);
4585                if (pi != null) {
4586                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4587                }
4588                return pi;
4589            }
4590        }
4591        return null;
4592    }
4593
4594    @Override
4595    public String[] getSystemSharedLibraryNames() {
4596        synchronized (mPackages) {
4597            Set<String> libs = null;
4598            final int libCount = mSharedLibraries.size();
4599            for (int i = 0; i < libCount; i++) {
4600                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4601                if (versionedLib == null) {
4602                    continue;
4603                }
4604                final int versionCount = versionedLib.size();
4605                for (int j = 0; j < versionCount; j++) {
4606                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4607                    if (!libEntry.info.isStatic()) {
4608                        if (libs == null) {
4609                            libs = new ArraySet<>();
4610                        }
4611                        libs.add(libEntry.info.getName());
4612                        break;
4613                    }
4614                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4615                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4616                            UserHandle.getUserId(Binder.getCallingUid()),
4617                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4618                        if (libs == null) {
4619                            libs = new ArraySet<>();
4620                        }
4621                        libs.add(libEntry.info.getName());
4622                        break;
4623                    }
4624                }
4625            }
4626
4627            if (libs != null) {
4628                String[] libsArray = new String[libs.size()];
4629                libs.toArray(libsArray);
4630                return libsArray;
4631            }
4632
4633            return null;
4634        }
4635    }
4636
4637    @Override
4638    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4639        synchronized (mPackages) {
4640            return mServicesSystemSharedLibraryPackageName;
4641        }
4642    }
4643
4644    @Override
4645    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4646        synchronized (mPackages) {
4647            return mSharedSystemSharedLibraryPackageName;
4648        }
4649    }
4650
4651    private void updateSequenceNumberLP(String packageName, int[] userList) {
4652        for (int i = userList.length - 1; i >= 0; --i) {
4653            final int userId = userList[i];
4654            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4655            if (changedPackages == null) {
4656                changedPackages = new SparseArray<>();
4657                mChangedPackages.put(userId, changedPackages);
4658            }
4659            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4660            if (sequenceNumbers == null) {
4661                sequenceNumbers = new HashMap<>();
4662                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4663            }
4664            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4665            if (sequenceNumber != null) {
4666                changedPackages.remove(sequenceNumber);
4667            }
4668            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4669            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4670        }
4671        mChangedPackagesSequenceNumber++;
4672    }
4673
4674    @Override
4675    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4676        synchronized (mPackages) {
4677            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4678                return null;
4679            }
4680            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4681            if (changedPackages == null) {
4682                return null;
4683            }
4684            final List<String> packageNames =
4685                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4686            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4687                final String packageName = changedPackages.get(i);
4688                if (packageName != null) {
4689                    packageNames.add(packageName);
4690                }
4691            }
4692            return packageNames.isEmpty()
4693                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4694        }
4695    }
4696
4697    @Override
4698    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4699        ArrayList<FeatureInfo> res;
4700        synchronized (mAvailableFeatures) {
4701            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4702            res.addAll(mAvailableFeatures.values());
4703        }
4704        final FeatureInfo fi = new FeatureInfo();
4705        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4706                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4707        res.add(fi);
4708
4709        return new ParceledListSlice<>(res);
4710    }
4711
4712    @Override
4713    public boolean hasSystemFeature(String name, int version) {
4714        synchronized (mAvailableFeatures) {
4715            final FeatureInfo feat = mAvailableFeatures.get(name);
4716            if (feat == null) {
4717                return false;
4718            } else {
4719                return feat.version >= version;
4720            }
4721        }
4722    }
4723
4724    @Override
4725    public int checkPermission(String permName, String pkgName, int userId) {
4726        if (!sUserManager.exists(userId)) {
4727            return PackageManager.PERMISSION_DENIED;
4728        }
4729
4730        synchronized (mPackages) {
4731            final PackageParser.Package p = mPackages.get(pkgName);
4732            if (p != null && p.mExtras != null) {
4733                final PackageSetting ps = (PackageSetting) p.mExtras;
4734                final PermissionsState permissionsState = ps.getPermissionsState();
4735                if (permissionsState.hasPermission(permName, userId)) {
4736                    return PackageManager.PERMISSION_GRANTED;
4737                }
4738                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4739                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4740                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4741                    return PackageManager.PERMISSION_GRANTED;
4742                }
4743            }
4744        }
4745
4746        return PackageManager.PERMISSION_DENIED;
4747    }
4748
4749    @Override
4750    public int checkUidPermission(String permName, int uid) {
4751        final int userId = UserHandle.getUserId(uid);
4752
4753        if (!sUserManager.exists(userId)) {
4754            return PackageManager.PERMISSION_DENIED;
4755        }
4756
4757        synchronized (mPackages) {
4758            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4759            if (obj != null) {
4760                final SettingBase ps = (SettingBase) obj;
4761                final PermissionsState permissionsState = ps.getPermissionsState();
4762                if (permissionsState.hasPermission(permName, userId)) {
4763                    return PackageManager.PERMISSION_GRANTED;
4764                }
4765                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4766                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4767                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4768                    return PackageManager.PERMISSION_GRANTED;
4769                }
4770            } else {
4771                ArraySet<String> perms = mSystemPermissions.get(uid);
4772                if (perms != null) {
4773                    if (perms.contains(permName)) {
4774                        return PackageManager.PERMISSION_GRANTED;
4775                    }
4776                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4777                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4778                        return PackageManager.PERMISSION_GRANTED;
4779                    }
4780                }
4781            }
4782        }
4783
4784        return PackageManager.PERMISSION_DENIED;
4785    }
4786
4787    @Override
4788    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4789        if (UserHandle.getCallingUserId() != userId) {
4790            mContext.enforceCallingPermission(
4791                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4792                    "isPermissionRevokedByPolicy for user " + userId);
4793        }
4794
4795        if (checkPermission(permission, packageName, userId)
4796                == PackageManager.PERMISSION_GRANTED) {
4797            return false;
4798        }
4799
4800        final long identity = Binder.clearCallingIdentity();
4801        try {
4802            final int flags = getPermissionFlags(permission, packageName, userId);
4803            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4804        } finally {
4805            Binder.restoreCallingIdentity(identity);
4806        }
4807    }
4808
4809    @Override
4810    public String getPermissionControllerPackageName() {
4811        synchronized (mPackages) {
4812            return mRequiredInstallerPackage;
4813        }
4814    }
4815
4816    /**
4817     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4818     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4819     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4820     * @param message the message to log on security exception
4821     */
4822    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4823            boolean checkShell, String message) {
4824        if (userId < 0) {
4825            throw new IllegalArgumentException("Invalid userId " + userId);
4826        }
4827        if (checkShell) {
4828            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4829        }
4830        if (userId == UserHandle.getUserId(callingUid)) return;
4831        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4832            if (requireFullPermission) {
4833                mContext.enforceCallingOrSelfPermission(
4834                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4835            } else {
4836                try {
4837                    mContext.enforceCallingOrSelfPermission(
4838                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4839                } catch (SecurityException se) {
4840                    mContext.enforceCallingOrSelfPermission(
4841                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
4842                }
4843            }
4844        }
4845    }
4846
4847    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
4848        if (callingUid == Process.SHELL_UID) {
4849            if (userHandle >= 0
4850                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
4851                throw new SecurityException("Shell does not have permission to access user "
4852                        + userHandle);
4853            } else if (userHandle < 0) {
4854                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
4855                        + Debug.getCallers(3));
4856            }
4857        }
4858    }
4859
4860    private BasePermission findPermissionTreeLP(String permName) {
4861        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
4862            if (permName.startsWith(bp.name) &&
4863                    permName.length() > bp.name.length() &&
4864                    permName.charAt(bp.name.length()) == '.') {
4865                return bp;
4866            }
4867        }
4868        return null;
4869    }
4870
4871    private BasePermission checkPermissionTreeLP(String permName) {
4872        if (permName != null) {
4873            BasePermission bp = findPermissionTreeLP(permName);
4874            if (bp != null) {
4875                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
4876                    return bp;
4877                }
4878                throw new SecurityException("Calling uid "
4879                        + Binder.getCallingUid()
4880                        + " is not allowed to add to permission tree "
4881                        + bp.name + " owned by uid " + bp.uid);
4882            }
4883        }
4884        throw new SecurityException("No permission tree found for " + permName);
4885    }
4886
4887    static boolean compareStrings(CharSequence s1, CharSequence s2) {
4888        if (s1 == null) {
4889            return s2 == null;
4890        }
4891        if (s2 == null) {
4892            return false;
4893        }
4894        if (s1.getClass() != s2.getClass()) {
4895            return false;
4896        }
4897        return s1.equals(s2);
4898    }
4899
4900    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
4901        if (pi1.icon != pi2.icon) return false;
4902        if (pi1.logo != pi2.logo) return false;
4903        if (pi1.protectionLevel != pi2.protectionLevel) return false;
4904        if (!compareStrings(pi1.name, pi2.name)) return false;
4905        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
4906        // We'll take care of setting this one.
4907        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
4908        // These are not currently stored in settings.
4909        //if (!compareStrings(pi1.group, pi2.group)) return false;
4910        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
4911        //if (pi1.labelRes != pi2.labelRes) return false;
4912        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
4913        return true;
4914    }
4915
4916    int permissionInfoFootprint(PermissionInfo info) {
4917        int size = info.name.length();
4918        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
4919        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
4920        return size;
4921    }
4922
4923    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4924        int size = 0;
4925        for (BasePermission perm : mSettings.mPermissions.values()) {
4926            if (perm.uid == tree.uid) {
4927                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
4928            }
4929        }
4930        return size;
4931    }
4932
4933    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4934        // We calculate the max size of permissions defined by this uid and throw
4935        // if that plus the size of 'info' would exceed our stated maximum.
4936        if (tree.uid != Process.SYSTEM_UID) {
4937            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4938            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
4939                throw new SecurityException("Permission tree size cap exceeded");
4940            }
4941        }
4942    }
4943
4944    boolean addPermissionLocked(PermissionInfo info, boolean async) {
4945        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
4946            throw new SecurityException("Label must be specified in permission");
4947        }
4948        BasePermission tree = checkPermissionTreeLP(info.name);
4949        BasePermission bp = mSettings.mPermissions.get(info.name);
4950        boolean added = bp == null;
4951        boolean changed = true;
4952        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
4953        if (added) {
4954            enforcePermissionCapLocked(info, tree);
4955            bp = new BasePermission(info.name, tree.sourcePackage,
4956                    BasePermission.TYPE_DYNAMIC);
4957        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
4958            throw new SecurityException(
4959                    "Not allowed to modify non-dynamic permission "
4960                    + info.name);
4961        } else {
4962            if (bp.protectionLevel == fixedLevel
4963                    && bp.perm.owner.equals(tree.perm.owner)
4964                    && bp.uid == tree.uid
4965                    && comparePermissionInfos(bp.perm.info, info)) {
4966                changed = false;
4967            }
4968        }
4969        bp.protectionLevel = fixedLevel;
4970        info = new PermissionInfo(info);
4971        info.protectionLevel = fixedLevel;
4972        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
4973        bp.perm.info.packageName = tree.perm.info.packageName;
4974        bp.uid = tree.uid;
4975        if (added) {
4976            mSettings.mPermissions.put(info.name, bp);
4977        }
4978        if (changed) {
4979            if (!async) {
4980                mSettings.writeLPr();
4981            } else {
4982                scheduleWriteSettingsLocked();
4983            }
4984        }
4985        return added;
4986    }
4987
4988    @Override
4989    public boolean addPermission(PermissionInfo info) {
4990        synchronized (mPackages) {
4991            return addPermissionLocked(info, false);
4992        }
4993    }
4994
4995    @Override
4996    public boolean addPermissionAsync(PermissionInfo info) {
4997        synchronized (mPackages) {
4998            return addPermissionLocked(info, true);
4999        }
5000    }
5001
5002    @Override
5003    public void removePermission(String name) {
5004        synchronized (mPackages) {
5005            checkPermissionTreeLP(name);
5006            BasePermission bp = mSettings.mPermissions.get(name);
5007            if (bp != null) {
5008                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5009                    throw new SecurityException(
5010                            "Not allowed to modify non-dynamic permission "
5011                            + name);
5012                }
5013                mSettings.mPermissions.remove(name);
5014                mSettings.writeLPr();
5015            }
5016        }
5017    }
5018
5019    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
5020            BasePermission bp) {
5021        int index = pkg.requestedPermissions.indexOf(bp.name);
5022        if (index == -1) {
5023            throw new SecurityException("Package " + pkg.packageName
5024                    + " has not requested permission " + bp.name);
5025        }
5026        if (!bp.isRuntime() && !bp.isDevelopment()) {
5027            throw new SecurityException("Permission " + bp.name
5028                    + " is not a changeable permission type");
5029        }
5030    }
5031
5032    @Override
5033    public void grantRuntimePermission(String packageName, String name, final int userId) {
5034        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5035    }
5036
5037    private void grantRuntimePermission(String packageName, String name, final int userId,
5038            boolean overridePolicy) {
5039        if (!sUserManager.exists(userId)) {
5040            Log.e(TAG, "No such user:" + userId);
5041            return;
5042        }
5043
5044        mContext.enforceCallingOrSelfPermission(
5045                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5046                "grantRuntimePermission");
5047
5048        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5049                true /* requireFullPermission */, true /* checkShell */,
5050                "grantRuntimePermission");
5051
5052        final int uid;
5053        final SettingBase sb;
5054
5055        synchronized (mPackages) {
5056            final PackageParser.Package pkg = mPackages.get(packageName);
5057            if (pkg == null) {
5058                throw new IllegalArgumentException("Unknown package: " + packageName);
5059            }
5060
5061            final BasePermission bp = mSettings.mPermissions.get(name);
5062            if (bp == null) {
5063                throw new IllegalArgumentException("Unknown permission: " + name);
5064            }
5065
5066            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5067
5068            // If a permission review is required for legacy apps we represent
5069            // their permissions as always granted runtime ones since we need
5070            // to keep the review required permission flag per user while an
5071            // install permission's state is shared across all users.
5072            if (mPermissionReviewRequired
5073                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5074                    && bp.isRuntime()) {
5075                return;
5076            }
5077
5078            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5079            sb = (SettingBase) pkg.mExtras;
5080            if (sb == null) {
5081                throw new IllegalArgumentException("Unknown package: " + packageName);
5082            }
5083
5084            final PermissionsState permissionsState = sb.getPermissionsState();
5085
5086            final int flags = permissionsState.getPermissionFlags(name, userId);
5087            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5088                throw new SecurityException("Cannot grant system fixed permission "
5089                        + name + " for package " + packageName);
5090            }
5091            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5092                throw new SecurityException("Cannot grant policy fixed permission "
5093                        + name + " for package " + packageName);
5094            }
5095
5096            if (bp.isDevelopment()) {
5097                // Development permissions must be handled specially, since they are not
5098                // normal runtime permissions.  For now they apply to all users.
5099                if (permissionsState.grantInstallPermission(bp) !=
5100                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5101                    scheduleWriteSettingsLocked();
5102                }
5103                return;
5104            }
5105
5106            final PackageSetting ps = mSettings.mPackages.get(packageName);
5107            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5108                throw new SecurityException("Cannot grant non-ephemeral permission"
5109                        + name + " for package " + packageName);
5110            }
5111
5112            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5113                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5114                return;
5115            }
5116
5117            final int result = permissionsState.grantRuntimePermission(bp, userId);
5118            switch (result) {
5119                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5120                    return;
5121                }
5122
5123                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5124                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5125                    mHandler.post(new Runnable() {
5126                        @Override
5127                        public void run() {
5128                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5129                        }
5130                    });
5131                }
5132                break;
5133            }
5134
5135            if (bp.isRuntime()) {
5136                logPermissionGranted(mContext, name, packageName);
5137            }
5138
5139            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5140
5141            // Not critical if that is lost - app has to request again.
5142            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5143        }
5144
5145        // Only need to do this if user is initialized. Otherwise it's a new user
5146        // and there are no processes running as the user yet and there's no need
5147        // to make an expensive call to remount processes for the changed permissions.
5148        if (READ_EXTERNAL_STORAGE.equals(name)
5149                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5150            final long token = Binder.clearCallingIdentity();
5151            try {
5152                if (sUserManager.isInitialized(userId)) {
5153                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5154                            StorageManagerInternal.class);
5155                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5156                }
5157            } finally {
5158                Binder.restoreCallingIdentity(token);
5159            }
5160        }
5161    }
5162
5163    @Override
5164    public void revokeRuntimePermission(String packageName, String name, int userId) {
5165        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5166    }
5167
5168    private void revokeRuntimePermission(String packageName, String name, int userId,
5169            boolean overridePolicy) {
5170        if (!sUserManager.exists(userId)) {
5171            Log.e(TAG, "No such user:" + userId);
5172            return;
5173        }
5174
5175        mContext.enforceCallingOrSelfPermission(
5176                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5177                "revokeRuntimePermission");
5178
5179        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5180                true /* requireFullPermission */, true /* checkShell */,
5181                "revokeRuntimePermission");
5182
5183        final int appId;
5184
5185        synchronized (mPackages) {
5186            final PackageParser.Package pkg = mPackages.get(packageName);
5187            if (pkg == null) {
5188                throw new IllegalArgumentException("Unknown package: " + packageName);
5189            }
5190
5191            final BasePermission bp = mSettings.mPermissions.get(name);
5192            if (bp == null) {
5193                throw new IllegalArgumentException("Unknown permission: " + name);
5194            }
5195
5196            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5197
5198            // If a permission review is required for legacy apps we represent
5199            // their permissions as always granted runtime ones since we need
5200            // to keep the review required permission flag per user while an
5201            // install permission's state is shared across all users.
5202            if (mPermissionReviewRequired
5203                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5204                    && bp.isRuntime()) {
5205                return;
5206            }
5207
5208            SettingBase sb = (SettingBase) pkg.mExtras;
5209            if (sb == null) {
5210                throw new IllegalArgumentException("Unknown package: " + packageName);
5211            }
5212
5213            final PermissionsState permissionsState = sb.getPermissionsState();
5214
5215            final int flags = permissionsState.getPermissionFlags(name, userId);
5216            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5217                throw new SecurityException("Cannot revoke system fixed permission "
5218                        + name + " for package " + packageName);
5219            }
5220            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5221                throw new SecurityException("Cannot revoke policy fixed permission "
5222                        + name + " for package " + packageName);
5223            }
5224
5225            if (bp.isDevelopment()) {
5226                // Development permissions must be handled specially, since they are not
5227                // normal runtime permissions.  For now they apply to all users.
5228                if (permissionsState.revokeInstallPermission(bp) !=
5229                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5230                    scheduleWriteSettingsLocked();
5231                }
5232                return;
5233            }
5234
5235            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5236                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5237                return;
5238            }
5239
5240            if (bp.isRuntime()) {
5241                logPermissionRevoked(mContext, name, packageName);
5242            }
5243
5244            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5245
5246            // Critical, after this call app should never have the permission.
5247            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5248
5249            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5250        }
5251
5252        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5253    }
5254
5255    /**
5256     * Get the first event id for the permission.
5257     *
5258     * <p>There are four events for each permission: <ul>
5259     *     <li>Request permission: first id + 0</li>
5260     *     <li>Grant permission: first id + 1</li>
5261     *     <li>Request for permission denied: first id + 2</li>
5262     *     <li>Revoke permission: first id + 3</li>
5263     * </ul></p>
5264     *
5265     * @param name name of the permission
5266     *
5267     * @return The first event id for the permission
5268     */
5269    private static int getBaseEventId(@NonNull String name) {
5270        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5271
5272        if (eventIdIndex == -1) {
5273            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5274                    || "user".equals(Build.TYPE)) {
5275                Log.i(TAG, "Unknown permission " + name);
5276
5277                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5278            } else {
5279                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5280                //
5281                // Also update
5282                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5283                // - metrics_constants.proto
5284                throw new IllegalStateException("Unknown permission " + name);
5285            }
5286        }
5287
5288        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5289    }
5290
5291    /**
5292     * Log that a permission was revoked.
5293     *
5294     * @param context Context of the caller
5295     * @param name name of the permission
5296     * @param packageName package permission if for
5297     */
5298    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5299            @NonNull String packageName) {
5300        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5301    }
5302
5303    /**
5304     * Log that a permission request was granted.
5305     *
5306     * @param context Context of the caller
5307     * @param name name of the permission
5308     * @param packageName package permission if for
5309     */
5310    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5311            @NonNull String packageName) {
5312        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5313    }
5314
5315    @Override
5316    public void resetRuntimePermissions() {
5317        mContext.enforceCallingOrSelfPermission(
5318                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5319                "revokeRuntimePermission");
5320
5321        int callingUid = Binder.getCallingUid();
5322        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5323            mContext.enforceCallingOrSelfPermission(
5324                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5325                    "resetRuntimePermissions");
5326        }
5327
5328        synchronized (mPackages) {
5329            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5330            for (int userId : UserManagerService.getInstance().getUserIds()) {
5331                final int packageCount = mPackages.size();
5332                for (int i = 0; i < packageCount; i++) {
5333                    PackageParser.Package pkg = mPackages.valueAt(i);
5334                    if (!(pkg.mExtras instanceof PackageSetting)) {
5335                        continue;
5336                    }
5337                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5338                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5339                }
5340            }
5341        }
5342    }
5343
5344    @Override
5345    public int getPermissionFlags(String name, String packageName, int userId) {
5346        if (!sUserManager.exists(userId)) {
5347            return 0;
5348        }
5349
5350        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5351
5352        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5353                true /* requireFullPermission */, false /* checkShell */,
5354                "getPermissionFlags");
5355
5356        synchronized (mPackages) {
5357            final PackageParser.Package pkg = mPackages.get(packageName);
5358            if (pkg == null) {
5359                return 0;
5360            }
5361
5362            final BasePermission bp = mSettings.mPermissions.get(name);
5363            if (bp == null) {
5364                return 0;
5365            }
5366
5367            SettingBase sb = (SettingBase) pkg.mExtras;
5368            if (sb == null) {
5369                return 0;
5370            }
5371
5372            PermissionsState permissionsState = sb.getPermissionsState();
5373            return permissionsState.getPermissionFlags(name, userId);
5374        }
5375    }
5376
5377    @Override
5378    public void updatePermissionFlags(String name, String packageName, int flagMask,
5379            int flagValues, int userId) {
5380        if (!sUserManager.exists(userId)) {
5381            return;
5382        }
5383
5384        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5385
5386        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5387                true /* requireFullPermission */, true /* checkShell */,
5388                "updatePermissionFlags");
5389
5390        // Only the system can change these flags and nothing else.
5391        if (getCallingUid() != Process.SYSTEM_UID) {
5392            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5393            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5394            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5395            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5396            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5397        }
5398
5399        synchronized (mPackages) {
5400            final PackageParser.Package pkg = mPackages.get(packageName);
5401            if (pkg == null) {
5402                throw new IllegalArgumentException("Unknown package: " + packageName);
5403            }
5404
5405            final BasePermission bp = mSettings.mPermissions.get(name);
5406            if (bp == null) {
5407                throw new IllegalArgumentException("Unknown permission: " + name);
5408            }
5409
5410            SettingBase sb = (SettingBase) pkg.mExtras;
5411            if (sb == null) {
5412                throw new IllegalArgumentException("Unknown package: " + packageName);
5413            }
5414
5415            PermissionsState permissionsState = sb.getPermissionsState();
5416
5417            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5418
5419            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5420                // Install and runtime permissions are stored in different places,
5421                // so figure out what permission changed and persist the change.
5422                if (permissionsState.getInstallPermissionState(name) != null) {
5423                    scheduleWriteSettingsLocked();
5424                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5425                        || hadState) {
5426                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5427                }
5428            }
5429        }
5430    }
5431
5432    /**
5433     * Update the permission flags for all packages and runtime permissions of a user in order
5434     * to allow device or profile owner to remove POLICY_FIXED.
5435     */
5436    @Override
5437    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5438        if (!sUserManager.exists(userId)) {
5439            return;
5440        }
5441
5442        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5443
5444        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5445                true /* requireFullPermission */, true /* checkShell */,
5446                "updatePermissionFlagsForAllApps");
5447
5448        // Only the system can change system fixed flags.
5449        if (getCallingUid() != Process.SYSTEM_UID) {
5450            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5451            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5452        }
5453
5454        synchronized (mPackages) {
5455            boolean changed = false;
5456            final int packageCount = mPackages.size();
5457            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5458                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5459                SettingBase sb = (SettingBase) pkg.mExtras;
5460                if (sb == null) {
5461                    continue;
5462                }
5463                PermissionsState permissionsState = sb.getPermissionsState();
5464                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5465                        userId, flagMask, flagValues);
5466            }
5467            if (changed) {
5468                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5469            }
5470        }
5471    }
5472
5473    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5474        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5475                != PackageManager.PERMISSION_GRANTED
5476            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5477                != PackageManager.PERMISSION_GRANTED) {
5478            throw new SecurityException(message + " requires "
5479                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5480                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5481        }
5482    }
5483
5484    @Override
5485    public boolean shouldShowRequestPermissionRationale(String permissionName,
5486            String packageName, int userId) {
5487        if (UserHandle.getCallingUserId() != userId) {
5488            mContext.enforceCallingPermission(
5489                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5490                    "canShowRequestPermissionRationale for user " + userId);
5491        }
5492
5493        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5494        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5495            return false;
5496        }
5497
5498        if (checkPermission(permissionName, packageName, userId)
5499                == PackageManager.PERMISSION_GRANTED) {
5500            return false;
5501        }
5502
5503        final int flags;
5504
5505        final long identity = Binder.clearCallingIdentity();
5506        try {
5507            flags = getPermissionFlags(permissionName,
5508                    packageName, userId);
5509        } finally {
5510            Binder.restoreCallingIdentity(identity);
5511        }
5512
5513        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5514                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5515                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5516
5517        if ((flags & fixedFlags) != 0) {
5518            return false;
5519        }
5520
5521        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5522    }
5523
5524    @Override
5525    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5526        mContext.enforceCallingOrSelfPermission(
5527                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5528                "addOnPermissionsChangeListener");
5529
5530        synchronized (mPackages) {
5531            mOnPermissionChangeListeners.addListenerLocked(listener);
5532        }
5533    }
5534
5535    @Override
5536    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5537        synchronized (mPackages) {
5538            mOnPermissionChangeListeners.removeListenerLocked(listener);
5539        }
5540    }
5541
5542    @Override
5543    public boolean isProtectedBroadcast(String actionName) {
5544        synchronized (mPackages) {
5545            if (mProtectedBroadcasts.contains(actionName)) {
5546                return true;
5547            } else if (actionName != null) {
5548                // TODO: remove these terrible hacks
5549                if (actionName.startsWith("android.net.netmon.lingerExpired")
5550                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5551                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5552                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5553                    return true;
5554                }
5555            }
5556        }
5557        return false;
5558    }
5559
5560    @Override
5561    public int checkSignatures(String pkg1, String pkg2) {
5562        synchronized (mPackages) {
5563            final PackageParser.Package p1 = mPackages.get(pkg1);
5564            final PackageParser.Package p2 = mPackages.get(pkg2);
5565            if (p1 == null || p1.mExtras == null
5566                    || p2 == null || p2.mExtras == null) {
5567                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5568            }
5569            return compareSignatures(p1.mSignatures, p2.mSignatures);
5570        }
5571    }
5572
5573    @Override
5574    public int checkUidSignatures(int uid1, int uid2) {
5575        // Map to base uids.
5576        uid1 = UserHandle.getAppId(uid1);
5577        uid2 = UserHandle.getAppId(uid2);
5578        // reader
5579        synchronized (mPackages) {
5580            Signature[] s1;
5581            Signature[] s2;
5582            Object obj = mSettings.getUserIdLPr(uid1);
5583            if (obj != null) {
5584                if (obj instanceof SharedUserSetting) {
5585                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5586                } else if (obj instanceof PackageSetting) {
5587                    s1 = ((PackageSetting)obj).signatures.mSignatures;
5588                } else {
5589                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5590                }
5591            } else {
5592                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5593            }
5594            obj = mSettings.getUserIdLPr(uid2);
5595            if (obj != null) {
5596                if (obj instanceof SharedUserSetting) {
5597                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5598                } else if (obj instanceof PackageSetting) {
5599                    s2 = ((PackageSetting)obj).signatures.mSignatures;
5600                } else {
5601                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5602                }
5603            } else {
5604                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5605            }
5606            return compareSignatures(s1, s2);
5607        }
5608    }
5609
5610    /**
5611     * This method should typically only be used when granting or revoking
5612     * permissions, since the app may immediately restart after this call.
5613     * <p>
5614     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5615     * guard your work against the app being relaunched.
5616     */
5617    private void killUid(int appId, int userId, String reason) {
5618        final long identity = Binder.clearCallingIdentity();
5619        try {
5620            IActivityManager am = ActivityManager.getService();
5621            if (am != null) {
5622                try {
5623                    am.killUid(appId, userId, reason);
5624                } catch (RemoteException e) {
5625                    /* ignore - same process */
5626                }
5627            }
5628        } finally {
5629            Binder.restoreCallingIdentity(identity);
5630        }
5631    }
5632
5633    /**
5634     * Compares two sets of signatures. Returns:
5635     * <br />
5636     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5637     * <br />
5638     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5639     * <br />
5640     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5641     * <br />
5642     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5643     * <br />
5644     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5645     */
5646    static int compareSignatures(Signature[] s1, Signature[] s2) {
5647        if (s1 == null) {
5648            return s2 == null
5649                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5650                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5651        }
5652
5653        if (s2 == null) {
5654            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5655        }
5656
5657        if (s1.length != s2.length) {
5658            return PackageManager.SIGNATURE_NO_MATCH;
5659        }
5660
5661        // Since both signature sets are of size 1, we can compare without HashSets.
5662        if (s1.length == 1) {
5663            return s1[0].equals(s2[0]) ?
5664                    PackageManager.SIGNATURE_MATCH :
5665                    PackageManager.SIGNATURE_NO_MATCH;
5666        }
5667
5668        ArraySet<Signature> set1 = new ArraySet<Signature>();
5669        for (Signature sig : s1) {
5670            set1.add(sig);
5671        }
5672        ArraySet<Signature> set2 = new ArraySet<Signature>();
5673        for (Signature sig : s2) {
5674            set2.add(sig);
5675        }
5676        // Make sure s2 contains all signatures in s1.
5677        if (set1.equals(set2)) {
5678            return PackageManager.SIGNATURE_MATCH;
5679        }
5680        return PackageManager.SIGNATURE_NO_MATCH;
5681    }
5682
5683    /**
5684     * If the database version for this type of package (internal storage or
5685     * external storage) is less than the version where package signatures
5686     * were updated, return true.
5687     */
5688    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5689        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5690        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5691    }
5692
5693    /**
5694     * Used for backward compatibility to make sure any packages with
5695     * certificate chains get upgraded to the new style. {@code existingSigs}
5696     * will be in the old format (since they were stored on disk from before the
5697     * system upgrade) and {@code scannedSigs} will be in the newer format.
5698     */
5699    private int compareSignaturesCompat(PackageSignatures existingSigs,
5700            PackageParser.Package scannedPkg) {
5701        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5702            return PackageManager.SIGNATURE_NO_MATCH;
5703        }
5704
5705        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5706        for (Signature sig : existingSigs.mSignatures) {
5707            existingSet.add(sig);
5708        }
5709        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5710        for (Signature sig : scannedPkg.mSignatures) {
5711            try {
5712                Signature[] chainSignatures = sig.getChainSignatures();
5713                for (Signature chainSig : chainSignatures) {
5714                    scannedCompatSet.add(chainSig);
5715                }
5716            } catch (CertificateEncodingException e) {
5717                scannedCompatSet.add(sig);
5718            }
5719        }
5720        /*
5721         * Make sure the expanded scanned set contains all signatures in the
5722         * existing one.
5723         */
5724        if (scannedCompatSet.equals(existingSet)) {
5725            // Migrate the old signatures to the new scheme.
5726            existingSigs.assignSignatures(scannedPkg.mSignatures);
5727            // The new KeySets will be re-added later in the scanning process.
5728            synchronized (mPackages) {
5729                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5730            }
5731            return PackageManager.SIGNATURE_MATCH;
5732        }
5733        return PackageManager.SIGNATURE_NO_MATCH;
5734    }
5735
5736    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5737        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5738        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5739    }
5740
5741    private int compareSignaturesRecover(PackageSignatures existingSigs,
5742            PackageParser.Package scannedPkg) {
5743        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5744            return PackageManager.SIGNATURE_NO_MATCH;
5745        }
5746
5747        String msg = null;
5748        try {
5749            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5750                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5751                        + scannedPkg.packageName);
5752                return PackageManager.SIGNATURE_MATCH;
5753            }
5754        } catch (CertificateException e) {
5755            msg = e.getMessage();
5756        }
5757
5758        logCriticalInfo(Log.INFO,
5759                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5760        return PackageManager.SIGNATURE_NO_MATCH;
5761    }
5762
5763    @Override
5764    public List<String> getAllPackages() {
5765        synchronized (mPackages) {
5766            return new ArrayList<String>(mPackages.keySet());
5767        }
5768    }
5769
5770    @Override
5771    public String[] getPackagesForUid(int uid) {
5772        final int userId = UserHandle.getUserId(uid);
5773        uid = UserHandle.getAppId(uid);
5774        // reader
5775        synchronized (mPackages) {
5776            Object obj = mSettings.getUserIdLPr(uid);
5777            if (obj instanceof SharedUserSetting) {
5778                final SharedUserSetting sus = (SharedUserSetting) obj;
5779                final int N = sus.packages.size();
5780                String[] res = new String[N];
5781                final Iterator<PackageSetting> it = sus.packages.iterator();
5782                int i = 0;
5783                while (it.hasNext()) {
5784                    PackageSetting ps = it.next();
5785                    if (ps.getInstalled(userId)) {
5786                        res[i++] = ps.name;
5787                    } else {
5788                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5789                    }
5790                }
5791                return res;
5792            } else if (obj instanceof PackageSetting) {
5793                final PackageSetting ps = (PackageSetting) obj;
5794                if (ps.getInstalled(userId)) {
5795                    return new String[]{ps.name};
5796                }
5797            }
5798        }
5799        return null;
5800    }
5801
5802    @Override
5803    public String getNameForUid(int uid) {
5804        // reader
5805        synchronized (mPackages) {
5806            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5807            if (obj instanceof SharedUserSetting) {
5808                final SharedUserSetting sus = (SharedUserSetting) obj;
5809                return sus.name + ":" + sus.userId;
5810            } else if (obj instanceof PackageSetting) {
5811                final PackageSetting ps = (PackageSetting) obj;
5812                return ps.name;
5813            }
5814        }
5815        return null;
5816    }
5817
5818    @Override
5819    public int getUidForSharedUser(String sharedUserName) {
5820        if(sharedUserName == null) {
5821            return -1;
5822        }
5823        // reader
5824        synchronized (mPackages) {
5825            SharedUserSetting suid;
5826            try {
5827                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5828                if (suid != null) {
5829                    return suid.userId;
5830                }
5831            } catch (PackageManagerException ignore) {
5832                // can't happen, but, still need to catch it
5833            }
5834            return -1;
5835        }
5836    }
5837
5838    @Override
5839    public int getFlagsForUid(int uid) {
5840        synchronized (mPackages) {
5841            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5842            if (obj instanceof SharedUserSetting) {
5843                final SharedUserSetting sus = (SharedUserSetting) obj;
5844                return sus.pkgFlags;
5845            } else if (obj instanceof PackageSetting) {
5846                final PackageSetting ps = (PackageSetting) obj;
5847                return ps.pkgFlags;
5848            }
5849        }
5850        return 0;
5851    }
5852
5853    @Override
5854    public int getPrivateFlagsForUid(int uid) {
5855        synchronized (mPackages) {
5856            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5857            if (obj instanceof SharedUserSetting) {
5858                final SharedUserSetting sus = (SharedUserSetting) obj;
5859                return sus.pkgPrivateFlags;
5860            } else if (obj instanceof PackageSetting) {
5861                final PackageSetting ps = (PackageSetting) obj;
5862                return ps.pkgPrivateFlags;
5863            }
5864        }
5865        return 0;
5866    }
5867
5868    @Override
5869    public boolean isUidPrivileged(int uid) {
5870        uid = UserHandle.getAppId(uid);
5871        // reader
5872        synchronized (mPackages) {
5873            Object obj = mSettings.getUserIdLPr(uid);
5874            if (obj instanceof SharedUserSetting) {
5875                final SharedUserSetting sus = (SharedUserSetting) obj;
5876                final Iterator<PackageSetting> it = sus.packages.iterator();
5877                while (it.hasNext()) {
5878                    if (it.next().isPrivileged()) {
5879                        return true;
5880                    }
5881                }
5882            } else if (obj instanceof PackageSetting) {
5883                final PackageSetting ps = (PackageSetting) obj;
5884                return ps.isPrivileged();
5885            }
5886        }
5887        return false;
5888    }
5889
5890    @Override
5891    public String[] getAppOpPermissionPackages(String permissionName) {
5892        synchronized (mPackages) {
5893            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
5894            if (pkgs == null) {
5895                return null;
5896            }
5897            return pkgs.toArray(new String[pkgs.size()]);
5898        }
5899    }
5900
5901    @Override
5902    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5903            int flags, int userId) {
5904        return resolveIntentInternal(
5905                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
5906    }
5907
5908    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5909            int flags, int userId, boolean resolveForStart) {
5910        try {
5911            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5912
5913            if (!sUserManager.exists(userId)) return null;
5914            final int callingUid = Binder.getCallingUid();
5915            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5916            enforceCrossUserPermission(callingUid, userId,
5917                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5918
5919            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5920            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5921                    flags, userId, resolveForStart);
5922            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5923
5924            final ResolveInfo bestChoice =
5925                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5926            return bestChoice;
5927        } finally {
5928            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5929        }
5930    }
5931
5932    @Override
5933    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5934        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5935            throw new SecurityException(
5936                    "findPersistentPreferredActivity can only be run by the system");
5937        }
5938        if (!sUserManager.exists(userId)) {
5939            return null;
5940        }
5941        final int callingUid = Binder.getCallingUid();
5942        intent = updateIntentForResolve(intent);
5943        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5944        final int flags = updateFlagsForResolve(
5945                0, userId, intent, callingUid, false /*includeInstantApps*/);
5946        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5947                userId);
5948        synchronized (mPackages) {
5949            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5950                    userId);
5951        }
5952    }
5953
5954    @Override
5955    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5956            IntentFilter filter, int match, ComponentName activity) {
5957        final int userId = UserHandle.getCallingUserId();
5958        if (DEBUG_PREFERRED) {
5959            Log.v(TAG, "setLastChosenActivity intent=" + intent
5960                + " resolvedType=" + resolvedType
5961                + " flags=" + flags
5962                + " filter=" + filter
5963                + " match=" + match
5964                + " activity=" + activity);
5965            filter.dump(new PrintStreamPrinter(System.out), "    ");
5966        }
5967        intent.setComponent(null);
5968        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5969                userId);
5970        // Find any earlier preferred or last chosen entries and nuke them
5971        findPreferredActivity(intent, resolvedType,
5972                flags, query, 0, false, true, false, userId);
5973        // Add the new activity as the last chosen for this filter
5974        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5975                "Setting last chosen");
5976    }
5977
5978    @Override
5979    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5980        final int userId = UserHandle.getCallingUserId();
5981        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5982        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5983                userId);
5984        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5985                false, false, false, userId);
5986    }
5987
5988    /**
5989     * Returns whether or not instant apps have been disabled remotely.
5990     */
5991    private boolean isEphemeralDisabled() {
5992        return mEphemeralAppsDisabled;
5993    }
5994
5995    private boolean isInstantAppAllowed(
5996            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5997            boolean skipPackageCheck) {
5998        if (mInstantAppResolverConnection == null) {
5999            return false;
6000        }
6001        if (mInstantAppInstallerActivity == null) {
6002            return false;
6003        }
6004        if (intent.getComponent() != null) {
6005            return false;
6006        }
6007        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6008            return false;
6009        }
6010        if (!skipPackageCheck && intent.getPackage() != null) {
6011            return false;
6012        }
6013        final boolean isWebUri = hasWebURI(intent);
6014        if (!isWebUri || intent.getData().getHost() == null) {
6015            return false;
6016        }
6017        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6018        // Or if there's already an ephemeral app installed that handles the action
6019        synchronized (mPackages) {
6020            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6021            for (int n = 0; n < count; n++) {
6022                final ResolveInfo info = resolvedActivities.get(n);
6023                final String packageName = info.activityInfo.packageName;
6024                final PackageSetting ps = mSettings.mPackages.get(packageName);
6025                if (ps != null) {
6026                    // only check domain verification status if the app is not a browser
6027                    if (!info.handleAllWebDataURI) {
6028                        // Try to get the status from User settings first
6029                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6030                        final int status = (int) (packedStatus >> 32);
6031                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6032                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6033                            if (DEBUG_EPHEMERAL) {
6034                                Slog.v(TAG, "DENY instant app;"
6035                                    + " pkg: " + packageName + ", status: " + status);
6036                            }
6037                            return false;
6038                        }
6039                    }
6040                    if (ps.getInstantApp(userId)) {
6041                        if (DEBUG_EPHEMERAL) {
6042                            Slog.v(TAG, "DENY instant app installed;"
6043                                    + " pkg: " + packageName);
6044                        }
6045                        return false;
6046                    }
6047                }
6048            }
6049        }
6050        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6051        return true;
6052    }
6053
6054    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6055            Intent origIntent, String resolvedType, String callingPackage,
6056            Bundle verificationBundle, int userId) {
6057        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6058                new InstantAppRequest(responseObj, origIntent, resolvedType,
6059                        callingPackage, userId, verificationBundle));
6060        mHandler.sendMessage(msg);
6061    }
6062
6063    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6064            int flags, List<ResolveInfo> query, int userId) {
6065        if (query != null) {
6066            final int N = query.size();
6067            if (N == 1) {
6068                return query.get(0);
6069            } else if (N > 1) {
6070                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6071                // If there is more than one activity with the same priority,
6072                // then let the user decide between them.
6073                ResolveInfo r0 = query.get(0);
6074                ResolveInfo r1 = query.get(1);
6075                if (DEBUG_INTENT_MATCHING || debug) {
6076                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6077                            + r1.activityInfo.name + "=" + r1.priority);
6078                }
6079                // If the first activity has a higher priority, or a different
6080                // default, then it is always desirable to pick it.
6081                if (r0.priority != r1.priority
6082                        || r0.preferredOrder != r1.preferredOrder
6083                        || r0.isDefault != r1.isDefault) {
6084                    return query.get(0);
6085                }
6086                // If we have saved a preference for a preferred activity for
6087                // this Intent, use that.
6088                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6089                        flags, query, r0.priority, true, false, debug, userId);
6090                if (ri != null) {
6091                    return ri;
6092                }
6093                // If we have an ephemeral app, use it
6094                for (int i = 0; i < N; i++) {
6095                    ri = query.get(i);
6096                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6097                        final String packageName = ri.activityInfo.packageName;
6098                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6099                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6100                        final int status = (int)(packedStatus >> 32);
6101                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6102                            return ri;
6103                        }
6104                    }
6105                }
6106                ri = new ResolveInfo(mResolveInfo);
6107                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6108                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6109                // If all of the options come from the same package, show the application's
6110                // label and icon instead of the generic resolver's.
6111                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6112                // and then throw away the ResolveInfo itself, meaning that the caller loses
6113                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6114                // a fallback for this case; we only set the target package's resources on
6115                // the ResolveInfo, not the ActivityInfo.
6116                final String intentPackage = intent.getPackage();
6117                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6118                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6119                    ri.resolvePackageName = intentPackage;
6120                    if (userNeedsBadging(userId)) {
6121                        ri.noResourceId = true;
6122                    } else {
6123                        ri.icon = appi.icon;
6124                    }
6125                    ri.iconResourceId = appi.icon;
6126                    ri.labelRes = appi.labelRes;
6127                }
6128                ri.activityInfo.applicationInfo = new ApplicationInfo(
6129                        ri.activityInfo.applicationInfo);
6130                if (userId != 0) {
6131                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6132                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6133                }
6134                // Make sure that the resolver is displayable in car mode
6135                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6136                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6137                return ri;
6138            }
6139        }
6140        return null;
6141    }
6142
6143    /**
6144     * Return true if the given list is not empty and all of its contents have
6145     * an activityInfo with the given package name.
6146     */
6147    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6148        if (ArrayUtils.isEmpty(list)) {
6149            return false;
6150        }
6151        for (int i = 0, N = list.size(); i < N; i++) {
6152            final ResolveInfo ri = list.get(i);
6153            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6154            if (ai == null || !packageName.equals(ai.packageName)) {
6155                return false;
6156            }
6157        }
6158        return true;
6159    }
6160
6161    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6162            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6163        final int N = query.size();
6164        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6165                .get(userId);
6166        // Get the list of persistent preferred activities that handle the intent
6167        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6168        List<PersistentPreferredActivity> pprefs = ppir != null
6169                ? ppir.queryIntent(intent, resolvedType,
6170                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6171                        userId)
6172                : null;
6173        if (pprefs != null && pprefs.size() > 0) {
6174            final int M = pprefs.size();
6175            for (int i=0; i<M; i++) {
6176                final PersistentPreferredActivity ppa = pprefs.get(i);
6177                if (DEBUG_PREFERRED || debug) {
6178                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6179                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6180                            + "\n  component=" + ppa.mComponent);
6181                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6182                }
6183                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6184                        flags | MATCH_DISABLED_COMPONENTS, userId);
6185                if (DEBUG_PREFERRED || debug) {
6186                    Slog.v(TAG, "Found persistent preferred activity:");
6187                    if (ai != null) {
6188                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6189                    } else {
6190                        Slog.v(TAG, "  null");
6191                    }
6192                }
6193                if (ai == null) {
6194                    // This previously registered persistent preferred activity
6195                    // component is no longer known. Ignore it and do NOT remove it.
6196                    continue;
6197                }
6198                for (int j=0; j<N; j++) {
6199                    final ResolveInfo ri = query.get(j);
6200                    if (!ri.activityInfo.applicationInfo.packageName
6201                            .equals(ai.applicationInfo.packageName)) {
6202                        continue;
6203                    }
6204                    if (!ri.activityInfo.name.equals(ai.name)) {
6205                        continue;
6206                    }
6207                    //  Found a persistent preference that can handle the intent.
6208                    if (DEBUG_PREFERRED || debug) {
6209                        Slog.v(TAG, "Returning persistent preferred activity: " +
6210                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6211                    }
6212                    return ri;
6213                }
6214            }
6215        }
6216        return null;
6217    }
6218
6219    // TODO: handle preferred activities missing while user has amnesia
6220    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6221            List<ResolveInfo> query, int priority, boolean always,
6222            boolean removeMatches, boolean debug, int userId) {
6223        if (!sUserManager.exists(userId)) return null;
6224        final int callingUid = Binder.getCallingUid();
6225        flags = updateFlagsForResolve(
6226                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6227        intent = updateIntentForResolve(intent);
6228        // writer
6229        synchronized (mPackages) {
6230            // Try to find a matching persistent preferred activity.
6231            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6232                    debug, userId);
6233
6234            // If a persistent preferred activity matched, use it.
6235            if (pri != null) {
6236                return pri;
6237            }
6238
6239            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6240            // Get the list of preferred activities that handle the intent
6241            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6242            List<PreferredActivity> prefs = pir != null
6243                    ? pir.queryIntent(intent, resolvedType,
6244                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6245                            userId)
6246                    : null;
6247            if (prefs != null && prefs.size() > 0) {
6248                boolean changed = false;
6249                try {
6250                    // First figure out how good the original match set is.
6251                    // We will only allow preferred activities that came
6252                    // from the same match quality.
6253                    int match = 0;
6254
6255                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6256
6257                    final int N = query.size();
6258                    for (int j=0; j<N; j++) {
6259                        final ResolveInfo ri = query.get(j);
6260                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6261                                + ": 0x" + Integer.toHexString(match));
6262                        if (ri.match > match) {
6263                            match = ri.match;
6264                        }
6265                    }
6266
6267                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6268                            + Integer.toHexString(match));
6269
6270                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6271                    final int M = prefs.size();
6272                    for (int i=0; i<M; i++) {
6273                        final PreferredActivity pa = prefs.get(i);
6274                        if (DEBUG_PREFERRED || debug) {
6275                            Slog.v(TAG, "Checking PreferredActivity ds="
6276                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6277                                    + "\n  component=" + pa.mPref.mComponent);
6278                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6279                        }
6280                        if (pa.mPref.mMatch != match) {
6281                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6282                                    + Integer.toHexString(pa.mPref.mMatch));
6283                            continue;
6284                        }
6285                        // If it's not an "always" type preferred activity and that's what we're
6286                        // looking for, skip it.
6287                        if (always && !pa.mPref.mAlways) {
6288                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6289                            continue;
6290                        }
6291                        final ActivityInfo ai = getActivityInfo(
6292                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6293                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6294                                userId);
6295                        if (DEBUG_PREFERRED || debug) {
6296                            Slog.v(TAG, "Found preferred activity:");
6297                            if (ai != null) {
6298                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6299                            } else {
6300                                Slog.v(TAG, "  null");
6301                            }
6302                        }
6303                        if (ai == null) {
6304                            // This previously registered preferred activity
6305                            // component is no longer known.  Most likely an update
6306                            // to the app was installed and in the new version this
6307                            // component no longer exists.  Clean it up by removing
6308                            // it from the preferred activities list, and skip it.
6309                            Slog.w(TAG, "Removing dangling preferred activity: "
6310                                    + pa.mPref.mComponent);
6311                            pir.removeFilter(pa);
6312                            changed = true;
6313                            continue;
6314                        }
6315                        for (int j=0; j<N; j++) {
6316                            final ResolveInfo ri = query.get(j);
6317                            if (!ri.activityInfo.applicationInfo.packageName
6318                                    .equals(ai.applicationInfo.packageName)) {
6319                                continue;
6320                            }
6321                            if (!ri.activityInfo.name.equals(ai.name)) {
6322                                continue;
6323                            }
6324
6325                            if (removeMatches) {
6326                                pir.removeFilter(pa);
6327                                changed = true;
6328                                if (DEBUG_PREFERRED) {
6329                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6330                                }
6331                                break;
6332                            }
6333
6334                            // Okay we found a previously set preferred or last chosen app.
6335                            // If the result set is different from when this
6336                            // was created, we need to clear it and re-ask the
6337                            // user their preference, if we're looking for an "always" type entry.
6338                            if (always && !pa.mPref.sameSet(query)) {
6339                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6340                                        + intent + " type " + resolvedType);
6341                                if (DEBUG_PREFERRED) {
6342                                    Slog.v(TAG, "Removing preferred activity since set changed "
6343                                            + pa.mPref.mComponent);
6344                                }
6345                                pir.removeFilter(pa);
6346                                // Re-add the filter as a "last chosen" entry (!always)
6347                                PreferredActivity lastChosen = new PreferredActivity(
6348                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6349                                pir.addFilter(lastChosen);
6350                                changed = true;
6351                                return null;
6352                            }
6353
6354                            // Yay! Either the set matched or we're looking for the last chosen
6355                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6356                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6357                            return ri;
6358                        }
6359                    }
6360                } finally {
6361                    if (changed) {
6362                        if (DEBUG_PREFERRED) {
6363                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6364                        }
6365                        scheduleWritePackageRestrictionsLocked(userId);
6366                    }
6367                }
6368            }
6369        }
6370        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6371        return null;
6372    }
6373
6374    /*
6375     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6376     */
6377    @Override
6378    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6379            int targetUserId) {
6380        mContext.enforceCallingOrSelfPermission(
6381                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6382        List<CrossProfileIntentFilter> matches =
6383                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6384        if (matches != null) {
6385            int size = matches.size();
6386            for (int i = 0; i < size; i++) {
6387                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6388            }
6389        }
6390        if (hasWebURI(intent)) {
6391            // cross-profile app linking works only towards the parent.
6392            final int callingUid = Binder.getCallingUid();
6393            final UserInfo parent = getProfileParent(sourceUserId);
6394            synchronized(mPackages) {
6395                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6396                        false /*includeInstantApps*/);
6397                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6398                        intent, resolvedType, flags, sourceUserId, parent.id);
6399                return xpDomainInfo != null;
6400            }
6401        }
6402        return false;
6403    }
6404
6405    private UserInfo getProfileParent(int userId) {
6406        final long identity = Binder.clearCallingIdentity();
6407        try {
6408            return sUserManager.getProfileParent(userId);
6409        } finally {
6410            Binder.restoreCallingIdentity(identity);
6411        }
6412    }
6413
6414    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6415            String resolvedType, int userId) {
6416        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6417        if (resolver != null) {
6418            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6419        }
6420        return null;
6421    }
6422
6423    @Override
6424    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6425            String resolvedType, int flags, int userId) {
6426        try {
6427            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6428
6429            return new ParceledListSlice<>(
6430                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6431        } finally {
6432            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6433        }
6434    }
6435
6436    /**
6437     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6438     * instant, returns {@code null}.
6439     */
6440    private String getInstantAppPackageName(int callingUid) {
6441        // If the caller is an isolated app use the owner's uid for the lookup.
6442        if (Process.isIsolated(callingUid)) {
6443            callingUid = mIsolatedOwners.get(callingUid);
6444        }
6445        final int appId = UserHandle.getAppId(callingUid);
6446        synchronized (mPackages) {
6447            final Object obj = mSettings.getUserIdLPr(appId);
6448            if (obj instanceof PackageSetting) {
6449                final PackageSetting ps = (PackageSetting) obj;
6450                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6451                return isInstantApp ? ps.pkg.packageName : null;
6452            }
6453        }
6454        return null;
6455    }
6456
6457    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6458            String resolvedType, int flags, int userId) {
6459        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6460    }
6461
6462    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6463            String resolvedType, int flags, int userId, boolean resolveForStart) {
6464        if (!sUserManager.exists(userId)) return Collections.emptyList();
6465        final int callingUid = Binder.getCallingUid();
6466        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6467        enforceCrossUserPermission(callingUid, userId,
6468                false /* requireFullPermission */, false /* checkShell */,
6469                "query intent activities");
6470        final String pkgName = intent.getPackage();
6471        ComponentName comp = intent.getComponent();
6472        if (comp == null) {
6473            if (intent.getSelector() != null) {
6474                intent = intent.getSelector();
6475                comp = intent.getComponent();
6476            }
6477        }
6478
6479        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
6480                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6481        if (comp != null) {
6482            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6483            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6484            if (ai != null) {
6485                // When specifying an explicit component, we prevent the activity from being
6486                // used when either 1) the calling package is normal and the activity is within
6487                // an ephemeral application or 2) the calling package is ephemeral and the
6488                // activity is not visible to ephemeral applications.
6489                final boolean matchInstantApp =
6490                        (flags & PackageManager.MATCH_INSTANT) != 0;
6491                final boolean matchVisibleToInstantAppOnly =
6492                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6493                final boolean matchExplicitlyVisibleOnly =
6494                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6495                final boolean isCallerInstantApp =
6496                        instantAppPkgName != null;
6497                final boolean isTargetSameInstantApp =
6498                        comp.getPackageName().equals(instantAppPkgName);
6499                final boolean isTargetInstantApp =
6500                        (ai.applicationInfo.privateFlags
6501                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6502                final boolean isTargetVisibleToInstantApp =
6503                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6504                final boolean isTargetExplicitlyVisibleToInstantApp =
6505                        isTargetVisibleToInstantApp
6506                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6507                final boolean isTargetHiddenFromInstantApp =
6508                        !isTargetVisibleToInstantApp
6509                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6510                final boolean blockResolution =
6511                        !isTargetSameInstantApp
6512                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6513                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6514                                        && isTargetHiddenFromInstantApp));
6515                if (!blockResolution) {
6516                    final ResolveInfo ri = new ResolveInfo();
6517                    ri.activityInfo = ai;
6518                    list.add(ri);
6519                }
6520            }
6521            return applyPostResolutionFilter(list, instantAppPkgName);
6522        }
6523
6524        // reader
6525        boolean sortResult = false;
6526        boolean addEphemeral = false;
6527        List<ResolveInfo> result;
6528        final boolean ephemeralDisabled = isEphemeralDisabled();
6529        synchronized (mPackages) {
6530            if (pkgName == null) {
6531                List<CrossProfileIntentFilter> matchingFilters =
6532                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6533                // Check for results that need to skip the current profile.
6534                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6535                        resolvedType, flags, userId);
6536                if (xpResolveInfo != null) {
6537                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6538                    xpResult.add(xpResolveInfo);
6539                    return applyPostResolutionFilter(
6540                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6541                }
6542
6543                // Check for results in the current profile.
6544                result = filterIfNotSystemUser(mActivities.queryIntent(
6545                        intent, resolvedType, flags, userId), userId);
6546                addEphemeral = !ephemeralDisabled
6547                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6548                // Check for cross profile results.
6549                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6550                xpResolveInfo = queryCrossProfileIntents(
6551                        matchingFilters, intent, resolvedType, flags, userId,
6552                        hasNonNegativePriorityResult);
6553                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6554                    boolean isVisibleToUser = filterIfNotSystemUser(
6555                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6556                    if (isVisibleToUser) {
6557                        result.add(xpResolveInfo);
6558                        sortResult = true;
6559                    }
6560                }
6561                if (hasWebURI(intent)) {
6562                    CrossProfileDomainInfo xpDomainInfo = null;
6563                    final UserInfo parent = getProfileParent(userId);
6564                    if (parent != null) {
6565                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6566                                flags, userId, parent.id);
6567                    }
6568                    if (xpDomainInfo != null) {
6569                        if (xpResolveInfo != null) {
6570                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6571                            // in the result.
6572                            result.remove(xpResolveInfo);
6573                        }
6574                        if (result.size() == 0 && !addEphemeral) {
6575                            // No result in current profile, but found candidate in parent user.
6576                            // And we are not going to add emphemeral app, so we can return the
6577                            // result straight away.
6578                            result.add(xpDomainInfo.resolveInfo);
6579                            return applyPostResolutionFilter(result, instantAppPkgName);
6580                        }
6581                    } else if (result.size() <= 1 && !addEphemeral) {
6582                        // No result in parent user and <= 1 result in current profile, and we
6583                        // are not going to add emphemeral app, so we can return the result without
6584                        // further processing.
6585                        return applyPostResolutionFilter(result, instantAppPkgName);
6586                    }
6587                    // We have more than one candidate (combining results from current and parent
6588                    // profile), so we need filtering and sorting.
6589                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6590                            intent, flags, result, xpDomainInfo, userId);
6591                    sortResult = true;
6592                }
6593            } else {
6594                final PackageParser.Package pkg = mPackages.get(pkgName);
6595                result = null;
6596                if (pkg != null) {
6597                    result = filterIfNotSystemUser(
6598                            mActivities.queryIntentForPackage(
6599                                    intent, resolvedType, flags, pkg.activities, userId),
6600                            userId);
6601                }
6602                if (result == null || result.size() == 0) {
6603                    // the caller wants to resolve for a particular package; however, there
6604                    // were no installed results, so, try to find an ephemeral result
6605                    addEphemeral = !ephemeralDisabled
6606                            && isInstantAppAllowed(
6607                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6608                    if (result == null) {
6609                        result = new ArrayList<>();
6610                    }
6611                }
6612            }
6613        }
6614        if (addEphemeral) {
6615            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
6616        }
6617        if (sortResult) {
6618            Collections.sort(result, mResolvePrioritySorter);
6619        }
6620        return applyPostResolutionFilter(result, instantAppPkgName);
6621    }
6622
6623    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6624            String resolvedType, int flags, int userId) {
6625        // first, check to see if we've got an instant app already installed
6626        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6627        ResolveInfo localInstantApp = null;
6628        boolean blockResolution = false;
6629        if (!alreadyResolvedLocally) {
6630            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6631                    flags
6632                        | PackageManager.GET_RESOLVED_FILTER
6633                        | PackageManager.MATCH_INSTANT
6634                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6635                    userId);
6636            for (int i = instantApps.size() - 1; i >= 0; --i) {
6637                final ResolveInfo info = instantApps.get(i);
6638                final String packageName = info.activityInfo.packageName;
6639                final PackageSetting ps = mSettings.mPackages.get(packageName);
6640                if (ps.getInstantApp(userId)) {
6641                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6642                    final int status = (int)(packedStatus >> 32);
6643                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6644                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6645                        // there's a local instant application installed, but, the user has
6646                        // chosen to never use it; skip resolution and don't acknowledge
6647                        // an instant application is even available
6648                        if (DEBUG_EPHEMERAL) {
6649                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6650                        }
6651                        blockResolution = true;
6652                        break;
6653                    } else {
6654                        // we have a locally installed instant application; skip resolution
6655                        // but acknowledge there's an instant application available
6656                        if (DEBUG_EPHEMERAL) {
6657                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6658                        }
6659                        localInstantApp = info;
6660                        break;
6661                    }
6662                }
6663            }
6664        }
6665        // no app installed, let's see if one's available
6666        AuxiliaryResolveInfo auxiliaryResponse = null;
6667        if (!blockResolution) {
6668            if (localInstantApp == null) {
6669                // we don't have an instant app locally, resolve externally
6670                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6671                final InstantAppRequest requestObject = new InstantAppRequest(
6672                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6673                        null /*callingPackage*/, userId, null /*verificationBundle*/);
6674                auxiliaryResponse =
6675                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6676                                mContext, mInstantAppResolverConnection, requestObject);
6677                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6678            } else {
6679                // we have an instant application locally, but, we can't admit that since
6680                // callers shouldn't be able to determine prior browsing. create a dummy
6681                // auxiliary response so the downstream code behaves as if there's an
6682                // instant application available externally. when it comes time to start
6683                // the instant application, we'll do the right thing.
6684                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6685                auxiliaryResponse = new AuxiliaryResolveInfo(
6686                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
6687            }
6688        }
6689        if (auxiliaryResponse != null) {
6690            if (DEBUG_EPHEMERAL) {
6691                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6692            }
6693            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6694            final PackageSetting ps =
6695                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6696            if (ps != null) {
6697                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6698                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6699                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6700                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6701                // make sure this resolver is the default
6702                ephemeralInstaller.isDefault = true;
6703                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6704                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6705                // add a non-generic filter
6706                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6707                ephemeralInstaller.filter.addDataPath(
6708                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6709                ephemeralInstaller.isInstantAppAvailable = true;
6710                result.add(ephemeralInstaller);
6711            }
6712        }
6713        return result;
6714    }
6715
6716    private static class CrossProfileDomainInfo {
6717        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6718        ResolveInfo resolveInfo;
6719        /* Best domain verification status of the activities found in the other profile */
6720        int bestDomainVerificationStatus;
6721    }
6722
6723    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6724            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6725        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6726                sourceUserId)) {
6727            return null;
6728        }
6729        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6730                resolvedType, flags, parentUserId);
6731
6732        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6733            return null;
6734        }
6735        CrossProfileDomainInfo result = null;
6736        int size = resultTargetUser.size();
6737        for (int i = 0; i < size; i++) {
6738            ResolveInfo riTargetUser = resultTargetUser.get(i);
6739            // Intent filter verification is only for filters that specify a host. So don't return
6740            // those that handle all web uris.
6741            if (riTargetUser.handleAllWebDataURI) {
6742                continue;
6743            }
6744            String packageName = riTargetUser.activityInfo.packageName;
6745            PackageSetting ps = mSettings.mPackages.get(packageName);
6746            if (ps == null) {
6747                continue;
6748            }
6749            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6750            int status = (int)(verificationState >> 32);
6751            if (result == null) {
6752                result = new CrossProfileDomainInfo();
6753                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6754                        sourceUserId, parentUserId);
6755                result.bestDomainVerificationStatus = status;
6756            } else {
6757                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6758                        result.bestDomainVerificationStatus);
6759            }
6760        }
6761        // Don't consider matches with status NEVER across profiles.
6762        if (result != null && result.bestDomainVerificationStatus
6763                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6764            return null;
6765        }
6766        return result;
6767    }
6768
6769    /**
6770     * Verification statuses are ordered from the worse to the best, except for
6771     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6772     */
6773    private int bestDomainVerificationStatus(int status1, int status2) {
6774        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6775            return status2;
6776        }
6777        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6778            return status1;
6779        }
6780        return (int) MathUtils.max(status1, status2);
6781    }
6782
6783    private boolean isUserEnabled(int userId) {
6784        long callingId = Binder.clearCallingIdentity();
6785        try {
6786            UserInfo userInfo = sUserManager.getUserInfo(userId);
6787            return userInfo != null && userInfo.isEnabled();
6788        } finally {
6789            Binder.restoreCallingIdentity(callingId);
6790        }
6791    }
6792
6793    /**
6794     * Filter out activities with systemUserOnly flag set, when current user is not System.
6795     *
6796     * @return filtered list
6797     */
6798    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6799        if (userId == UserHandle.USER_SYSTEM) {
6800            return resolveInfos;
6801        }
6802        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6803            ResolveInfo info = resolveInfos.get(i);
6804            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6805                resolveInfos.remove(i);
6806            }
6807        }
6808        return resolveInfos;
6809    }
6810
6811    /**
6812     * Filters out ephemeral activities.
6813     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6814     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6815     *
6816     * @param resolveInfos The pre-filtered list of resolved activities
6817     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6818     *          is performed.
6819     * @return A filtered list of resolved activities.
6820     */
6821    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6822            String ephemeralPkgName) {
6823        // TODO: When adding on-demand split support for non-instant apps, remove this check
6824        // and always apply post filtering
6825        if (ephemeralPkgName == null) {
6826            return resolveInfos;
6827        }
6828        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6829            final ResolveInfo info = resolveInfos.get(i);
6830            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6831            // allow activities that are defined in the provided package
6832            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
6833                if (info.activityInfo.splitName != null
6834                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6835                                info.activityInfo.splitName)) {
6836                    // requested activity is defined in a split that hasn't been installed yet.
6837                    // add the installer to the resolve list
6838                    if (DEBUG_EPHEMERAL) {
6839                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6840                    }
6841                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6842                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6843                            info.activityInfo.packageName, info.activityInfo.splitName,
6844                            info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
6845                    // make sure this resolver is the default
6846                    installerInfo.isDefault = true;
6847                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6848                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6849                    // add a non-generic filter
6850                    installerInfo.filter = new IntentFilter();
6851                    // load resources from the correct package
6852                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6853                    resolveInfos.set(i, installerInfo);
6854                }
6855                continue;
6856            }
6857            // allow activities that have been explicitly exposed to ephemeral apps
6858            if (!isEphemeralApp
6859                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6860                continue;
6861            }
6862            resolveInfos.remove(i);
6863        }
6864        return resolveInfos;
6865    }
6866
6867    /**
6868     * @param resolveInfos list of resolve infos in descending priority order
6869     * @return if the list contains a resolve info with non-negative priority
6870     */
6871    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6872        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6873    }
6874
6875    private static boolean hasWebURI(Intent intent) {
6876        if (intent.getData() == null) {
6877            return false;
6878        }
6879        final String scheme = intent.getScheme();
6880        if (TextUtils.isEmpty(scheme)) {
6881            return false;
6882        }
6883        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6884    }
6885
6886    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6887            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6888            int userId) {
6889        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6890
6891        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6892            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6893                    candidates.size());
6894        }
6895
6896        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6897        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6898        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6899        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6900        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6901        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6902
6903        synchronized (mPackages) {
6904            final int count = candidates.size();
6905            // First, try to use linked apps. Partition the candidates into four lists:
6906            // one for the final results, one for the "do not use ever", one for "undefined status"
6907            // and finally one for "browser app type".
6908            for (int n=0; n<count; n++) {
6909                ResolveInfo info = candidates.get(n);
6910                String packageName = info.activityInfo.packageName;
6911                PackageSetting ps = mSettings.mPackages.get(packageName);
6912                if (ps != null) {
6913                    // Add to the special match all list (Browser use case)
6914                    if (info.handleAllWebDataURI) {
6915                        matchAllList.add(info);
6916                        continue;
6917                    }
6918                    // Try to get the status from User settings first
6919                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6920                    int status = (int)(packedStatus >> 32);
6921                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6922                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6923                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6924                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6925                                    + " : linkgen=" + linkGeneration);
6926                        }
6927                        // Use link-enabled generation as preferredOrder, i.e.
6928                        // prefer newly-enabled over earlier-enabled.
6929                        info.preferredOrder = linkGeneration;
6930                        alwaysList.add(info);
6931                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6932                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6933                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6934                        }
6935                        neverList.add(info);
6936                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6937                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6938                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6939                        }
6940                        alwaysAskList.add(info);
6941                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6942                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6943                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6944                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6945                        }
6946                        undefinedList.add(info);
6947                    }
6948                }
6949            }
6950
6951            // We'll want to include browser possibilities in a few cases
6952            boolean includeBrowser = false;
6953
6954            // First try to add the "always" resolution(s) for the current user, if any
6955            if (alwaysList.size() > 0) {
6956                result.addAll(alwaysList);
6957            } else {
6958                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6959                result.addAll(undefinedList);
6960                // Maybe add one for the other profile.
6961                if (xpDomainInfo != null && (
6962                        xpDomainInfo.bestDomainVerificationStatus
6963                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6964                    result.add(xpDomainInfo.resolveInfo);
6965                }
6966                includeBrowser = true;
6967            }
6968
6969            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6970            // If there were 'always' entries their preferred order has been set, so we also
6971            // back that off to make the alternatives equivalent
6972            if (alwaysAskList.size() > 0) {
6973                for (ResolveInfo i : result) {
6974                    i.preferredOrder = 0;
6975                }
6976                result.addAll(alwaysAskList);
6977                includeBrowser = true;
6978            }
6979
6980            if (includeBrowser) {
6981                // Also add browsers (all of them or only the default one)
6982                if (DEBUG_DOMAIN_VERIFICATION) {
6983                    Slog.v(TAG, "   ...including browsers in candidate set");
6984                }
6985                if ((matchFlags & MATCH_ALL) != 0) {
6986                    result.addAll(matchAllList);
6987                } else {
6988                    // Browser/generic handling case.  If there's a default browser, go straight
6989                    // to that (but only if there is no other higher-priority match).
6990                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6991                    int maxMatchPrio = 0;
6992                    ResolveInfo defaultBrowserMatch = null;
6993                    final int numCandidates = matchAllList.size();
6994                    for (int n = 0; n < numCandidates; n++) {
6995                        ResolveInfo info = matchAllList.get(n);
6996                        // track the highest overall match priority...
6997                        if (info.priority > maxMatchPrio) {
6998                            maxMatchPrio = info.priority;
6999                        }
7000                        // ...and the highest-priority default browser match
7001                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7002                            if (defaultBrowserMatch == null
7003                                    || (defaultBrowserMatch.priority < info.priority)) {
7004                                if (debug) {
7005                                    Slog.v(TAG, "Considering default browser match " + info);
7006                                }
7007                                defaultBrowserMatch = info;
7008                            }
7009                        }
7010                    }
7011                    if (defaultBrowserMatch != null
7012                            && defaultBrowserMatch.priority >= maxMatchPrio
7013                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7014                    {
7015                        if (debug) {
7016                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7017                        }
7018                        result.add(defaultBrowserMatch);
7019                    } else {
7020                        result.addAll(matchAllList);
7021                    }
7022                }
7023
7024                // If there is nothing selected, add all candidates and remove the ones that the user
7025                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7026                if (result.size() == 0) {
7027                    result.addAll(candidates);
7028                    result.removeAll(neverList);
7029                }
7030            }
7031        }
7032        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7033            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7034                    result.size());
7035            for (ResolveInfo info : result) {
7036                Slog.v(TAG, "  + " + info.activityInfo);
7037            }
7038        }
7039        return result;
7040    }
7041
7042    // Returns a packed value as a long:
7043    //
7044    // high 'int'-sized word: link status: undefined/ask/never/always.
7045    // low 'int'-sized word: relative priority among 'always' results.
7046    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7047        long result = ps.getDomainVerificationStatusForUser(userId);
7048        // if none available, get the master status
7049        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7050            if (ps.getIntentFilterVerificationInfo() != null) {
7051                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7052            }
7053        }
7054        return result;
7055    }
7056
7057    private ResolveInfo querySkipCurrentProfileIntents(
7058            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7059            int flags, int sourceUserId) {
7060        if (matchingFilters != null) {
7061            int size = matchingFilters.size();
7062            for (int i = 0; i < size; i ++) {
7063                CrossProfileIntentFilter filter = matchingFilters.get(i);
7064                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7065                    // Checking if there are activities in the target user that can handle the
7066                    // intent.
7067                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7068                            resolvedType, flags, sourceUserId);
7069                    if (resolveInfo != null) {
7070                        return resolveInfo;
7071                    }
7072                }
7073            }
7074        }
7075        return null;
7076    }
7077
7078    // Return matching ResolveInfo in target user if any.
7079    private ResolveInfo queryCrossProfileIntents(
7080            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7081            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7082        if (matchingFilters != null) {
7083            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7084            // match the same intent. For performance reasons, it is better not to
7085            // run queryIntent twice for the same userId
7086            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7087            int size = matchingFilters.size();
7088            for (int i = 0; i < size; i++) {
7089                CrossProfileIntentFilter filter = matchingFilters.get(i);
7090                int targetUserId = filter.getTargetUserId();
7091                boolean skipCurrentProfile =
7092                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7093                boolean skipCurrentProfileIfNoMatchFound =
7094                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7095                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7096                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7097                    // Checking if there are activities in the target user that can handle the
7098                    // intent.
7099                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7100                            resolvedType, flags, sourceUserId);
7101                    if (resolveInfo != null) return resolveInfo;
7102                    alreadyTriedUserIds.put(targetUserId, true);
7103                }
7104            }
7105        }
7106        return null;
7107    }
7108
7109    /**
7110     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7111     * will forward the intent to the filter's target user.
7112     * Otherwise, returns null.
7113     */
7114    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7115            String resolvedType, int flags, int sourceUserId) {
7116        int targetUserId = filter.getTargetUserId();
7117        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7118                resolvedType, flags, targetUserId);
7119        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7120            // If all the matches in the target profile are suspended, return null.
7121            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7122                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7123                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7124                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7125                            targetUserId);
7126                }
7127            }
7128        }
7129        return null;
7130    }
7131
7132    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7133            int sourceUserId, int targetUserId) {
7134        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7135        long ident = Binder.clearCallingIdentity();
7136        boolean targetIsProfile;
7137        try {
7138            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7139        } finally {
7140            Binder.restoreCallingIdentity(ident);
7141        }
7142        String className;
7143        if (targetIsProfile) {
7144            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7145        } else {
7146            className = FORWARD_INTENT_TO_PARENT;
7147        }
7148        ComponentName forwardingActivityComponentName = new ComponentName(
7149                mAndroidApplication.packageName, className);
7150        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7151                sourceUserId);
7152        if (!targetIsProfile) {
7153            forwardingActivityInfo.showUserIcon = targetUserId;
7154            forwardingResolveInfo.noResourceId = true;
7155        }
7156        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7157        forwardingResolveInfo.priority = 0;
7158        forwardingResolveInfo.preferredOrder = 0;
7159        forwardingResolveInfo.match = 0;
7160        forwardingResolveInfo.isDefault = true;
7161        forwardingResolveInfo.filter = filter;
7162        forwardingResolveInfo.targetUserId = targetUserId;
7163        return forwardingResolveInfo;
7164    }
7165
7166    @Override
7167    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7168            Intent[] specifics, String[] specificTypes, Intent intent,
7169            String resolvedType, int flags, int userId) {
7170        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7171                specificTypes, intent, resolvedType, flags, userId));
7172    }
7173
7174    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7175            Intent[] specifics, String[] specificTypes, Intent intent,
7176            String resolvedType, int flags, int userId) {
7177        if (!sUserManager.exists(userId)) return Collections.emptyList();
7178        final int callingUid = Binder.getCallingUid();
7179        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7180                false /*includeInstantApps*/);
7181        enforceCrossUserPermission(callingUid, userId,
7182                false /*requireFullPermission*/, false /*checkShell*/,
7183                "query intent activity options");
7184        final String resultsAction = intent.getAction();
7185
7186        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7187                | PackageManager.GET_RESOLVED_FILTER, userId);
7188
7189        if (DEBUG_INTENT_MATCHING) {
7190            Log.v(TAG, "Query " + intent + ": " + results);
7191        }
7192
7193        int specificsPos = 0;
7194        int N;
7195
7196        // todo: note that the algorithm used here is O(N^2).  This
7197        // isn't a problem in our current environment, but if we start running
7198        // into situations where we have more than 5 or 10 matches then this
7199        // should probably be changed to something smarter...
7200
7201        // First we go through and resolve each of the specific items
7202        // that were supplied, taking care of removing any corresponding
7203        // duplicate items in the generic resolve list.
7204        if (specifics != null) {
7205            for (int i=0; i<specifics.length; i++) {
7206                final Intent sintent = specifics[i];
7207                if (sintent == null) {
7208                    continue;
7209                }
7210
7211                if (DEBUG_INTENT_MATCHING) {
7212                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7213                }
7214
7215                String action = sintent.getAction();
7216                if (resultsAction != null && resultsAction.equals(action)) {
7217                    // If this action was explicitly requested, then don't
7218                    // remove things that have it.
7219                    action = null;
7220                }
7221
7222                ResolveInfo ri = null;
7223                ActivityInfo ai = null;
7224
7225                ComponentName comp = sintent.getComponent();
7226                if (comp == null) {
7227                    ri = resolveIntent(
7228                        sintent,
7229                        specificTypes != null ? specificTypes[i] : null,
7230                            flags, userId);
7231                    if (ri == null) {
7232                        continue;
7233                    }
7234                    if (ri == mResolveInfo) {
7235                        // ACK!  Must do something better with this.
7236                    }
7237                    ai = ri.activityInfo;
7238                    comp = new ComponentName(ai.applicationInfo.packageName,
7239                            ai.name);
7240                } else {
7241                    ai = getActivityInfo(comp, flags, userId);
7242                    if (ai == null) {
7243                        continue;
7244                    }
7245                }
7246
7247                // Look for any generic query activities that are duplicates
7248                // of this specific one, and remove them from the results.
7249                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7250                N = results.size();
7251                int j;
7252                for (j=specificsPos; j<N; j++) {
7253                    ResolveInfo sri = results.get(j);
7254                    if ((sri.activityInfo.name.equals(comp.getClassName())
7255                            && sri.activityInfo.applicationInfo.packageName.equals(
7256                                    comp.getPackageName()))
7257                        || (action != null && sri.filter.matchAction(action))) {
7258                        results.remove(j);
7259                        if (DEBUG_INTENT_MATCHING) Log.v(
7260                            TAG, "Removing duplicate item from " + j
7261                            + " due to specific " + specificsPos);
7262                        if (ri == null) {
7263                            ri = sri;
7264                        }
7265                        j--;
7266                        N--;
7267                    }
7268                }
7269
7270                // Add this specific item to its proper place.
7271                if (ri == null) {
7272                    ri = new ResolveInfo();
7273                    ri.activityInfo = ai;
7274                }
7275                results.add(specificsPos, ri);
7276                ri.specificIndex = i;
7277                specificsPos++;
7278            }
7279        }
7280
7281        // Now we go through the remaining generic results and remove any
7282        // duplicate actions that are found here.
7283        N = results.size();
7284        for (int i=specificsPos; i<N-1; i++) {
7285            final ResolveInfo rii = results.get(i);
7286            if (rii.filter == null) {
7287                continue;
7288            }
7289
7290            // Iterate over all of the actions of this result's intent
7291            // filter...  typically this should be just one.
7292            final Iterator<String> it = rii.filter.actionsIterator();
7293            if (it == null) {
7294                continue;
7295            }
7296            while (it.hasNext()) {
7297                final String action = it.next();
7298                if (resultsAction != null && resultsAction.equals(action)) {
7299                    // If this action was explicitly requested, then don't
7300                    // remove things that have it.
7301                    continue;
7302                }
7303                for (int j=i+1; j<N; j++) {
7304                    final ResolveInfo rij = results.get(j);
7305                    if (rij.filter != null && rij.filter.hasAction(action)) {
7306                        results.remove(j);
7307                        if (DEBUG_INTENT_MATCHING) Log.v(
7308                            TAG, "Removing duplicate item from " + j
7309                            + " due to action " + action + " at " + i);
7310                        j--;
7311                        N--;
7312                    }
7313                }
7314            }
7315
7316            // If the caller didn't request filter information, drop it now
7317            // so we don't have to marshall/unmarshall it.
7318            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7319                rii.filter = null;
7320            }
7321        }
7322
7323        // Filter out the caller activity if so requested.
7324        if (caller != null) {
7325            N = results.size();
7326            for (int i=0; i<N; i++) {
7327                ActivityInfo ainfo = results.get(i).activityInfo;
7328                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7329                        && caller.getClassName().equals(ainfo.name)) {
7330                    results.remove(i);
7331                    break;
7332                }
7333            }
7334        }
7335
7336        // If the caller didn't request filter information,
7337        // drop them now so we don't have to
7338        // marshall/unmarshall it.
7339        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7340            N = results.size();
7341            for (int i=0; i<N; i++) {
7342                results.get(i).filter = null;
7343            }
7344        }
7345
7346        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7347        return results;
7348    }
7349
7350    @Override
7351    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7352            String resolvedType, int flags, int userId) {
7353        return new ParceledListSlice<>(
7354                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7355    }
7356
7357    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7358            String resolvedType, int flags, int userId) {
7359        if (!sUserManager.exists(userId)) return Collections.emptyList();
7360        final int callingUid = Binder.getCallingUid();
7361        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7362                false /*includeInstantApps*/);
7363        ComponentName comp = intent.getComponent();
7364        if (comp == null) {
7365            if (intent.getSelector() != null) {
7366                intent = intent.getSelector();
7367                comp = intent.getComponent();
7368            }
7369        }
7370        if (comp != null) {
7371            List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7372            ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7373            if (ai != null) {
7374                ResolveInfo ri = new ResolveInfo();
7375                ri.activityInfo = ai;
7376                list.add(ri);
7377            }
7378            return list;
7379        }
7380
7381        // reader
7382        synchronized (mPackages) {
7383            String pkgName = intent.getPackage();
7384            if (pkgName == null) {
7385                return mReceivers.queryIntent(intent, resolvedType, flags, userId);
7386            }
7387            final PackageParser.Package pkg = mPackages.get(pkgName);
7388            if (pkg != null) {
7389                return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
7390                        userId);
7391            }
7392            return Collections.emptyList();
7393        }
7394    }
7395
7396    @Override
7397    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7398        final int callingUid = Binder.getCallingUid();
7399        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7400    }
7401
7402    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7403            int userId, int callingUid) {
7404        if (!sUserManager.exists(userId)) return null;
7405        flags = updateFlagsForResolve(
7406                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7407        List<ResolveInfo> query = queryIntentServicesInternal(
7408                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7409        if (query != null) {
7410            if (query.size() >= 1) {
7411                // If there is more than one service with the same priority,
7412                // just arbitrarily pick the first one.
7413                return query.get(0);
7414            }
7415        }
7416        return null;
7417    }
7418
7419    @Override
7420    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7421            String resolvedType, int flags, int userId) {
7422        final int callingUid = Binder.getCallingUid();
7423        return new ParceledListSlice<>(queryIntentServicesInternal(
7424                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7425    }
7426
7427    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7428            String resolvedType, int flags, int userId, int callingUid,
7429            boolean includeInstantApps) {
7430        if (!sUserManager.exists(userId)) return Collections.emptyList();
7431        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7432        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7433        ComponentName comp = intent.getComponent();
7434        if (comp == null) {
7435            if (intent.getSelector() != null) {
7436                intent = intent.getSelector();
7437                comp = intent.getComponent();
7438            }
7439        }
7440        if (comp != null) {
7441            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7442            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7443            if (si != null) {
7444                // When specifying an explicit component, we prevent the service from being
7445                // used when either 1) the service is in an instant application and the
7446                // caller is not the same instant application or 2) the calling package is
7447                // ephemeral and the activity is not visible to ephemeral applications.
7448                final boolean matchInstantApp =
7449                        (flags & PackageManager.MATCH_INSTANT) != 0;
7450                final boolean matchVisibleToInstantAppOnly =
7451                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7452                final boolean isCallerInstantApp =
7453                        instantAppPkgName != null;
7454                final boolean isTargetSameInstantApp =
7455                        comp.getPackageName().equals(instantAppPkgName);
7456                final boolean isTargetInstantApp =
7457                        (si.applicationInfo.privateFlags
7458                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7459                final boolean isTargetHiddenFromInstantApp =
7460                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7461                final boolean blockResolution =
7462                        !isTargetSameInstantApp
7463                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7464                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7465                                        && isTargetHiddenFromInstantApp));
7466                if (!blockResolution) {
7467                    final ResolveInfo ri = new ResolveInfo();
7468                    ri.serviceInfo = si;
7469                    list.add(ri);
7470                }
7471            }
7472            return list;
7473        }
7474
7475        // reader
7476        synchronized (mPackages) {
7477            String pkgName = intent.getPackage();
7478            if (pkgName == null) {
7479                return applyPostServiceResolutionFilter(
7480                        mServices.queryIntent(intent, resolvedType, flags, userId),
7481                        instantAppPkgName);
7482            }
7483            final PackageParser.Package pkg = mPackages.get(pkgName);
7484            if (pkg != null) {
7485                return applyPostServiceResolutionFilter(
7486                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7487                                userId),
7488                        instantAppPkgName);
7489            }
7490            return Collections.emptyList();
7491        }
7492    }
7493
7494    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7495            String instantAppPkgName) {
7496        // TODO: When adding on-demand split support for non-instant apps, remove this check
7497        // and always apply post filtering
7498        if (instantAppPkgName == null) {
7499            return resolveInfos;
7500        }
7501        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7502            final ResolveInfo info = resolveInfos.get(i);
7503            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7504            // allow services that are defined in the provided package
7505            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7506                if (info.serviceInfo.splitName != null
7507                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7508                                info.serviceInfo.splitName)) {
7509                    // requested service is defined in a split that hasn't been installed yet.
7510                    // add the installer to the resolve list
7511                    if (DEBUG_EPHEMERAL) {
7512                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7513                    }
7514                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7515                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7516                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7517                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
7518                    // make sure this resolver is the default
7519                    installerInfo.isDefault = true;
7520                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7521                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7522                    // add a non-generic filter
7523                    installerInfo.filter = new IntentFilter();
7524                    // load resources from the correct package
7525                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7526                    resolveInfos.set(i, installerInfo);
7527                }
7528                continue;
7529            }
7530            // allow services that have been explicitly exposed to ephemeral apps
7531            if (!isEphemeralApp
7532                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7533                continue;
7534            }
7535            resolveInfos.remove(i);
7536        }
7537        return resolveInfos;
7538    }
7539
7540    @Override
7541    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7542            String resolvedType, int flags, int userId) {
7543        return new ParceledListSlice<>(
7544                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7545    }
7546
7547    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7548            Intent intent, String resolvedType, int flags, int userId) {
7549        if (!sUserManager.exists(userId)) return Collections.emptyList();
7550        final int callingUid = Binder.getCallingUid();
7551        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7552        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7553                false /*includeInstantApps*/);
7554        ComponentName comp = intent.getComponent();
7555        if (comp == null) {
7556            if (intent.getSelector() != null) {
7557                intent = intent.getSelector();
7558                comp = intent.getComponent();
7559            }
7560        }
7561        if (comp != null) {
7562            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7563            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7564            if (pi != null) {
7565                // When specifying an explicit component, we prevent the provider from being
7566                // used when either 1) the provider is in an instant application and the
7567                // caller is not the same instant application or 2) the calling package is an
7568                // instant application and the provider is not visible to instant applications.
7569                final boolean matchInstantApp =
7570                        (flags & PackageManager.MATCH_INSTANT) != 0;
7571                final boolean matchVisibleToInstantAppOnly =
7572                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7573                final boolean isCallerInstantApp =
7574                        instantAppPkgName != null;
7575                final boolean isTargetSameInstantApp =
7576                        comp.getPackageName().equals(instantAppPkgName);
7577                final boolean isTargetInstantApp =
7578                        (pi.applicationInfo.privateFlags
7579                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7580                final boolean isTargetHiddenFromInstantApp =
7581                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7582                final boolean blockResolution =
7583                        !isTargetSameInstantApp
7584                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7585                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7586                                        && isTargetHiddenFromInstantApp));
7587                if (!blockResolution) {
7588                    final ResolveInfo ri = new ResolveInfo();
7589                    ri.providerInfo = pi;
7590                    list.add(ri);
7591                }
7592            }
7593            return list;
7594        }
7595
7596        // reader
7597        synchronized (mPackages) {
7598            String pkgName = intent.getPackage();
7599            if (pkgName == null) {
7600                return applyPostContentProviderResolutionFilter(
7601                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7602                        instantAppPkgName);
7603            }
7604            final PackageParser.Package pkg = mPackages.get(pkgName);
7605            if (pkg != null) {
7606                return applyPostContentProviderResolutionFilter(
7607                        mProviders.queryIntentForPackage(
7608                        intent, resolvedType, flags, pkg.providers, userId),
7609                        instantAppPkgName);
7610            }
7611            return Collections.emptyList();
7612        }
7613    }
7614
7615    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7616            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7617        // TODO: When adding on-demand split support for non-instant applications, remove
7618        // this check and always apply post filtering
7619        if (instantAppPkgName == null) {
7620            return resolveInfos;
7621        }
7622        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7623            final ResolveInfo info = resolveInfos.get(i);
7624            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7625            // allow providers that are defined in the provided package
7626            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7627                if (info.providerInfo.splitName != null
7628                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7629                                info.providerInfo.splitName)) {
7630                    // requested provider is defined in a split that hasn't been installed yet.
7631                    // add the installer to the resolve list
7632                    if (DEBUG_EPHEMERAL) {
7633                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7634                    }
7635                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7636                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7637                            info.providerInfo.packageName, info.providerInfo.splitName,
7638                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
7639                    // make sure this resolver is the default
7640                    installerInfo.isDefault = true;
7641                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7642                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7643                    // add a non-generic filter
7644                    installerInfo.filter = new IntentFilter();
7645                    // load resources from the correct package
7646                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7647                    resolveInfos.set(i, installerInfo);
7648                }
7649                continue;
7650            }
7651            // allow providers that have been explicitly exposed to instant applications
7652            if (!isEphemeralApp
7653                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7654                continue;
7655            }
7656            resolveInfos.remove(i);
7657        }
7658        return resolveInfos;
7659    }
7660
7661    @Override
7662    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7663        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7664        flags = updateFlagsForPackage(flags, userId, null);
7665        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7666        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7667                true /* requireFullPermission */, false /* checkShell */,
7668                "get installed packages");
7669
7670        // writer
7671        synchronized (mPackages) {
7672            ArrayList<PackageInfo> list;
7673            if (listUninstalled) {
7674                list = new ArrayList<>(mSettings.mPackages.size());
7675                for (PackageSetting ps : mSettings.mPackages.values()) {
7676                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7677                        continue;
7678                    }
7679                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7680                    if (pi != null) {
7681                        list.add(pi);
7682                    }
7683                }
7684            } else {
7685                list = new ArrayList<>(mPackages.size());
7686                for (PackageParser.Package p : mPackages.values()) {
7687                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7688                            Binder.getCallingUid(), userId, flags)) {
7689                        continue;
7690                    }
7691                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7692                            p.mExtras, flags, userId);
7693                    if (pi != null) {
7694                        list.add(pi);
7695                    }
7696                }
7697            }
7698
7699            return new ParceledListSlice<>(list);
7700        }
7701    }
7702
7703    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7704            String[] permissions, boolean[] tmp, int flags, int userId) {
7705        int numMatch = 0;
7706        final PermissionsState permissionsState = ps.getPermissionsState();
7707        for (int i=0; i<permissions.length; i++) {
7708            final String permission = permissions[i];
7709            if (permissionsState.hasPermission(permission, userId)) {
7710                tmp[i] = true;
7711                numMatch++;
7712            } else {
7713                tmp[i] = false;
7714            }
7715        }
7716        if (numMatch == 0) {
7717            return;
7718        }
7719        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7720
7721        // The above might return null in cases of uninstalled apps or install-state
7722        // skew across users/profiles.
7723        if (pi != null) {
7724            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7725                if (numMatch == permissions.length) {
7726                    pi.requestedPermissions = permissions;
7727                } else {
7728                    pi.requestedPermissions = new String[numMatch];
7729                    numMatch = 0;
7730                    for (int i=0; i<permissions.length; i++) {
7731                        if (tmp[i]) {
7732                            pi.requestedPermissions[numMatch] = permissions[i];
7733                            numMatch++;
7734                        }
7735                    }
7736                }
7737            }
7738            list.add(pi);
7739        }
7740    }
7741
7742    @Override
7743    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7744            String[] permissions, int flags, int userId) {
7745        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7746        flags = updateFlagsForPackage(flags, userId, permissions);
7747        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7748                true /* requireFullPermission */, false /* checkShell */,
7749                "get packages holding permissions");
7750        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7751
7752        // writer
7753        synchronized (mPackages) {
7754            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7755            boolean[] tmpBools = new boolean[permissions.length];
7756            if (listUninstalled) {
7757                for (PackageSetting ps : mSettings.mPackages.values()) {
7758                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7759                            userId);
7760                }
7761            } else {
7762                for (PackageParser.Package pkg : mPackages.values()) {
7763                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7764                    if (ps != null) {
7765                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7766                                userId);
7767                    }
7768                }
7769            }
7770
7771            return new ParceledListSlice<PackageInfo>(list);
7772        }
7773    }
7774
7775    @Override
7776    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7777        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7778        flags = updateFlagsForApplication(flags, userId, null);
7779        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7780
7781        // writer
7782        synchronized (mPackages) {
7783            ArrayList<ApplicationInfo> list;
7784            if (listUninstalled) {
7785                list = new ArrayList<>(mSettings.mPackages.size());
7786                for (PackageSetting ps : mSettings.mPackages.values()) {
7787                    ApplicationInfo ai;
7788                    int effectiveFlags = flags;
7789                    if (ps.isSystem()) {
7790                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7791                    }
7792                    if (ps.pkg != null) {
7793                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7794                            continue;
7795                        }
7796                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7797                                ps.readUserState(userId), userId);
7798                        if (ai != null) {
7799                            rebaseEnabledOverlays(ai, userId);
7800                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7801                        }
7802                    } else {
7803                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7804                        // and already converts to externally visible package name
7805                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7806                                Binder.getCallingUid(), effectiveFlags, userId);
7807                    }
7808                    if (ai != null) {
7809                        list.add(ai);
7810                    }
7811                }
7812            } else {
7813                list = new ArrayList<>(mPackages.size());
7814                for (PackageParser.Package p : mPackages.values()) {
7815                    if (p.mExtras != null) {
7816                        PackageSetting ps = (PackageSetting) p.mExtras;
7817                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7818                            continue;
7819                        }
7820                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7821                                ps.readUserState(userId), userId);
7822                        if (ai != null) {
7823                            rebaseEnabledOverlays(ai, userId);
7824                            ai.packageName = resolveExternalPackageNameLPr(p);
7825                            list.add(ai);
7826                        }
7827                    }
7828                }
7829            }
7830
7831            return new ParceledListSlice<>(list);
7832        }
7833    }
7834
7835    @Override
7836    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7837        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7838            return null;
7839        }
7840
7841        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7842                "getEphemeralApplications");
7843        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7844                true /* requireFullPermission */, false /* checkShell */,
7845                "getEphemeralApplications");
7846        synchronized (mPackages) {
7847            List<InstantAppInfo> instantApps = mInstantAppRegistry
7848                    .getInstantAppsLPr(userId);
7849            if (instantApps != null) {
7850                return new ParceledListSlice<>(instantApps);
7851            }
7852        }
7853        return null;
7854    }
7855
7856    @Override
7857    public boolean isInstantApp(String packageName, int userId) {
7858        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7859                true /* requireFullPermission */, false /* checkShell */,
7860                "isInstantApp");
7861        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7862            return false;
7863        }
7864        int uid = Binder.getCallingUid();
7865        if (Process.isIsolated(uid)) {
7866            uid = mIsolatedOwners.get(uid);
7867        }
7868
7869        synchronized (mPackages) {
7870            final PackageSetting ps = mSettings.mPackages.get(packageName);
7871            PackageParser.Package pkg = mPackages.get(packageName);
7872            final boolean returnAllowed =
7873                    ps != null
7874                    && (isCallerSameApp(packageName, uid)
7875                            || mContext.checkCallingOrSelfPermission(
7876                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
7877                                            == PERMISSION_GRANTED
7878                            || mInstantAppRegistry.isInstantAccessGranted(
7879                                    userId, UserHandle.getAppId(uid), ps.appId));
7880            if (returnAllowed) {
7881                return ps.getInstantApp(userId);
7882            }
7883        }
7884        return false;
7885    }
7886
7887    @Override
7888    public byte[] getInstantAppCookie(String packageName, int userId) {
7889        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7890            return null;
7891        }
7892
7893        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7894                true /* requireFullPermission */, false /* checkShell */,
7895                "getInstantAppCookie");
7896        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7897            return null;
7898        }
7899        synchronized (mPackages) {
7900            return mInstantAppRegistry.getInstantAppCookieLPw(
7901                    packageName, userId);
7902        }
7903    }
7904
7905    @Override
7906    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7907        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7908            return true;
7909        }
7910
7911        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7912                true /* requireFullPermission */, true /* checkShell */,
7913                "setInstantAppCookie");
7914        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7915            return false;
7916        }
7917        synchronized (mPackages) {
7918            return mInstantAppRegistry.setInstantAppCookieLPw(
7919                    packageName, cookie, userId);
7920        }
7921    }
7922
7923    @Override
7924    public Bitmap getInstantAppIcon(String packageName, int userId) {
7925        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7926            return null;
7927        }
7928
7929        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7930                "getInstantAppIcon");
7931
7932        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7933                true /* requireFullPermission */, false /* checkShell */,
7934                "getInstantAppIcon");
7935
7936        synchronized (mPackages) {
7937            return mInstantAppRegistry.getInstantAppIconLPw(
7938                    packageName, userId);
7939        }
7940    }
7941
7942    private boolean isCallerSameApp(String packageName, int uid) {
7943        PackageParser.Package pkg = mPackages.get(packageName);
7944        return pkg != null
7945                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7946    }
7947
7948    @Override
7949    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7950        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7951    }
7952
7953    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7954        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7955
7956        // reader
7957        synchronized (mPackages) {
7958            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7959            final int userId = UserHandle.getCallingUserId();
7960            while (i.hasNext()) {
7961                final PackageParser.Package p = i.next();
7962                if (p.applicationInfo == null) continue;
7963
7964                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7965                        && !p.applicationInfo.isDirectBootAware();
7966                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7967                        && p.applicationInfo.isDirectBootAware();
7968
7969                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7970                        && (!mSafeMode || isSystemApp(p))
7971                        && (matchesUnaware || matchesAware)) {
7972                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7973                    if (ps != null) {
7974                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7975                                ps.readUserState(userId), userId);
7976                        if (ai != null) {
7977                            rebaseEnabledOverlays(ai, userId);
7978                            finalList.add(ai);
7979                        }
7980                    }
7981                }
7982            }
7983        }
7984
7985        return finalList;
7986    }
7987
7988    @Override
7989    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7990        if (!sUserManager.exists(userId)) return null;
7991        flags = updateFlagsForComponent(flags, userId, name);
7992        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7993        // reader
7994        synchronized (mPackages) {
7995            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7996            PackageSetting ps = provider != null
7997                    ? mSettings.mPackages.get(provider.owner.packageName)
7998                    : null;
7999            if (ps != null) {
8000                final boolean isInstantApp = ps.getInstantApp(userId);
8001                // normal application; filter out instant application provider
8002                if (instantAppPkgName == null && isInstantApp) {
8003                    return null;
8004                }
8005                // instant application; filter out other instant applications
8006                if (instantAppPkgName != null
8007                        && isInstantApp
8008                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8009                    return null;
8010                }
8011                // instant application; filter out non-exposed provider
8012                if (instantAppPkgName != null
8013                        && !isInstantApp
8014                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8015                    return null;
8016                }
8017                // provider not enabled
8018                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8019                    return null;
8020                }
8021                return PackageParser.generateProviderInfo(
8022                        provider, flags, ps.readUserState(userId), userId);
8023            }
8024            return null;
8025        }
8026    }
8027
8028    /**
8029     * @deprecated
8030     */
8031    @Deprecated
8032    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8033        // reader
8034        synchronized (mPackages) {
8035            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8036                    .entrySet().iterator();
8037            final int userId = UserHandle.getCallingUserId();
8038            while (i.hasNext()) {
8039                Map.Entry<String, PackageParser.Provider> entry = i.next();
8040                PackageParser.Provider p = entry.getValue();
8041                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8042
8043                if (ps != null && p.syncable
8044                        && (!mSafeMode || (p.info.applicationInfo.flags
8045                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8046                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8047                            ps.readUserState(userId), userId);
8048                    if (info != null) {
8049                        outNames.add(entry.getKey());
8050                        outInfo.add(info);
8051                    }
8052                }
8053            }
8054        }
8055    }
8056
8057    @Override
8058    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8059            int uid, int flags, String metaDataKey) {
8060        final int userId = processName != null ? UserHandle.getUserId(uid)
8061                : UserHandle.getCallingUserId();
8062        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8063        flags = updateFlagsForComponent(flags, userId, processName);
8064
8065        ArrayList<ProviderInfo> finalList = null;
8066        // reader
8067        synchronized (mPackages) {
8068            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8069            while (i.hasNext()) {
8070                final PackageParser.Provider p = i.next();
8071                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8072                if (ps != null && p.info.authority != null
8073                        && (processName == null
8074                                || (p.info.processName.equals(processName)
8075                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8076                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8077
8078                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8079                    // parameter.
8080                    if (metaDataKey != null
8081                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8082                        continue;
8083                    }
8084
8085                    if (finalList == null) {
8086                        finalList = new ArrayList<ProviderInfo>(3);
8087                    }
8088                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8089                            ps.readUserState(userId), userId);
8090                    if (info != null) {
8091                        finalList.add(info);
8092                    }
8093                }
8094            }
8095        }
8096
8097        if (finalList != null) {
8098            Collections.sort(finalList, mProviderInitOrderSorter);
8099            return new ParceledListSlice<ProviderInfo>(finalList);
8100        }
8101
8102        return ParceledListSlice.emptyList();
8103    }
8104
8105    @Override
8106    public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) {
8107        // reader
8108        synchronized (mPackages) {
8109            final PackageParser.Instrumentation i = mInstrumentation.get(name);
8110            return PackageParser.generateInstrumentationInfo(i, flags);
8111        }
8112    }
8113
8114    @Override
8115    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8116            String targetPackage, int flags) {
8117        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8118    }
8119
8120    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8121            int flags) {
8122        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8123
8124        // reader
8125        synchronized (mPackages) {
8126            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8127            while (i.hasNext()) {
8128                final PackageParser.Instrumentation p = i.next();
8129                if (targetPackage == null
8130                        || targetPackage.equals(p.info.targetPackage)) {
8131                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8132                            flags);
8133                    if (ii != null) {
8134                        finalList.add(ii);
8135                    }
8136                }
8137            }
8138        }
8139
8140        return finalList;
8141    }
8142
8143    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8144        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8145        try {
8146            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8147        } finally {
8148            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8149        }
8150    }
8151
8152    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8153        final File[] files = dir.listFiles();
8154        if (ArrayUtils.isEmpty(files)) {
8155            Log.d(TAG, "No files in app dir " + dir);
8156            return;
8157        }
8158
8159        if (DEBUG_PACKAGE_SCANNING) {
8160            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8161                    + " flags=0x" + Integer.toHexString(parseFlags));
8162        }
8163        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8164                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8165                mParallelPackageParserCallback);
8166
8167        // Submit files for parsing in parallel
8168        int fileCount = 0;
8169        for (File file : files) {
8170            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8171                    && !PackageInstallerService.isStageName(file.getName());
8172            if (!isPackage) {
8173                // Ignore entries which are not packages
8174                continue;
8175            }
8176            parallelPackageParser.submit(file, parseFlags);
8177            fileCount++;
8178        }
8179
8180        // Process results one by one
8181        for (; fileCount > 0; fileCount--) {
8182            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8183            Throwable throwable = parseResult.throwable;
8184            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8185
8186            if (throwable == null) {
8187                // Static shared libraries have synthetic package names
8188                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8189                    renameStaticSharedLibraryPackage(parseResult.pkg);
8190                }
8191                try {
8192                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8193                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8194                                currentTime, null);
8195                    }
8196                } catch (PackageManagerException e) {
8197                    errorCode = e.error;
8198                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8199                }
8200            } else if (throwable instanceof PackageParser.PackageParserException) {
8201                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8202                        throwable;
8203                errorCode = e.error;
8204                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8205            } else {
8206                throw new IllegalStateException("Unexpected exception occurred while parsing "
8207                        + parseResult.scanFile, throwable);
8208            }
8209
8210            // Delete invalid userdata apps
8211            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8212                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8213                logCriticalInfo(Log.WARN,
8214                        "Deleting invalid package at " + parseResult.scanFile);
8215                removeCodePathLI(parseResult.scanFile);
8216            }
8217        }
8218        parallelPackageParser.close();
8219    }
8220
8221    private static File getSettingsProblemFile() {
8222        File dataDir = Environment.getDataDirectory();
8223        File systemDir = new File(dataDir, "system");
8224        File fname = new File(systemDir, "uiderrors.txt");
8225        return fname;
8226    }
8227
8228    static void reportSettingsProblem(int priority, String msg) {
8229        logCriticalInfo(priority, msg);
8230    }
8231
8232    public static void logCriticalInfo(int priority, String msg) {
8233        Slog.println(priority, TAG, msg);
8234        EventLogTags.writePmCriticalInfo(msg);
8235        try {
8236            File fname = getSettingsProblemFile();
8237            FileOutputStream out = new FileOutputStream(fname, true);
8238            PrintWriter pw = new FastPrintWriter(out);
8239            SimpleDateFormat formatter = new SimpleDateFormat();
8240            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8241            pw.println(dateString + ": " + msg);
8242            pw.close();
8243            FileUtils.setPermissions(
8244                    fname.toString(),
8245                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8246                    -1, -1);
8247        } catch (java.io.IOException e) {
8248        }
8249    }
8250
8251    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8252        if (srcFile.isDirectory()) {
8253            final File baseFile = new File(pkg.baseCodePath);
8254            long maxModifiedTime = baseFile.lastModified();
8255            if (pkg.splitCodePaths != null) {
8256                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8257                    final File splitFile = new File(pkg.splitCodePaths[i]);
8258                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8259                }
8260            }
8261            return maxModifiedTime;
8262        }
8263        return srcFile.lastModified();
8264    }
8265
8266    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8267            final int policyFlags) throws PackageManagerException {
8268        // When upgrading from pre-N MR1, verify the package time stamp using the package
8269        // directory and not the APK file.
8270        final long lastModifiedTime = mIsPreNMR1Upgrade
8271                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8272        if (ps != null
8273                && ps.codePath.equals(srcFile)
8274                && ps.timeStamp == lastModifiedTime
8275                && !isCompatSignatureUpdateNeeded(pkg)
8276                && !isRecoverSignatureUpdateNeeded(pkg)) {
8277            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8278            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8279            ArraySet<PublicKey> signingKs;
8280            synchronized (mPackages) {
8281                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8282            }
8283            if (ps.signatures.mSignatures != null
8284                    && ps.signatures.mSignatures.length != 0
8285                    && signingKs != null) {
8286                // Optimization: reuse the existing cached certificates
8287                // if the package appears to be unchanged.
8288                pkg.mSignatures = ps.signatures.mSignatures;
8289                pkg.mSigningKeys = signingKs;
8290                return;
8291            }
8292
8293            Slog.w(TAG, "PackageSetting for " + ps.name
8294                    + " is missing signatures.  Collecting certs again to recover them.");
8295        } else {
8296            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
8297        }
8298
8299        try {
8300            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8301            PackageParser.collectCertificates(pkg, policyFlags);
8302        } catch (PackageParserException e) {
8303            throw PackageManagerException.from(e);
8304        } finally {
8305            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8306        }
8307    }
8308
8309    /**
8310     *  Traces a package scan.
8311     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8312     */
8313    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8314            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8315        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8316        try {
8317            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8318        } finally {
8319            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8320        }
8321    }
8322
8323    /**
8324     *  Scans a package and returns the newly parsed package.
8325     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8326     */
8327    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8328            long currentTime, UserHandle user) throws PackageManagerException {
8329        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8330        PackageParser pp = new PackageParser();
8331        pp.setSeparateProcesses(mSeparateProcesses);
8332        pp.setOnlyCoreApps(mOnlyCore);
8333        pp.setDisplayMetrics(mMetrics);
8334        pp.setCallback(mPackageParserCallback);
8335
8336        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8337            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8338        }
8339
8340        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8341        final PackageParser.Package pkg;
8342        try {
8343            pkg = pp.parsePackage(scanFile, parseFlags);
8344        } catch (PackageParserException e) {
8345            throw PackageManagerException.from(e);
8346        } finally {
8347            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8348        }
8349
8350        // Static shared libraries have synthetic package names
8351        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8352            renameStaticSharedLibraryPackage(pkg);
8353        }
8354
8355        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8356    }
8357
8358    /**
8359     *  Scans a package and returns the newly parsed package.
8360     *  @throws PackageManagerException on a parse error.
8361     */
8362    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8363            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8364            throws PackageManagerException {
8365        // If the package has children and this is the first dive in the function
8366        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8367        // packages (parent and children) would be successfully scanned before the
8368        // actual scan since scanning mutates internal state and we want to atomically
8369        // install the package and its children.
8370        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8371            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8372                scanFlags |= SCAN_CHECK_ONLY;
8373            }
8374        } else {
8375            scanFlags &= ~SCAN_CHECK_ONLY;
8376        }
8377
8378        // Scan the parent
8379        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8380                scanFlags, currentTime, user);
8381
8382        // Scan the children
8383        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8384        for (int i = 0; i < childCount; i++) {
8385            PackageParser.Package childPackage = pkg.childPackages.get(i);
8386            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8387                    currentTime, user);
8388        }
8389
8390
8391        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8392            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8393        }
8394
8395        return scannedPkg;
8396    }
8397
8398    /**
8399     *  Scans a package and returns the newly parsed package.
8400     *  @throws PackageManagerException on a parse error.
8401     */
8402    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8403            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8404            throws PackageManagerException {
8405        PackageSetting ps = null;
8406        PackageSetting updatedPkg;
8407        // reader
8408        synchronized (mPackages) {
8409            // Look to see if we already know about this package.
8410            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8411            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8412                // This package has been renamed to its original name.  Let's
8413                // use that.
8414                ps = mSettings.getPackageLPr(oldName);
8415            }
8416            // If there was no original package, see one for the real package name.
8417            if (ps == null) {
8418                ps = mSettings.getPackageLPr(pkg.packageName);
8419            }
8420            // Check to see if this package could be hiding/updating a system
8421            // package.  Must look for it either under the original or real
8422            // package name depending on our state.
8423            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8424            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8425
8426            // If this is a package we don't know about on the system partition, we
8427            // may need to remove disabled child packages on the system partition
8428            // or may need to not add child packages if the parent apk is updated
8429            // on the data partition and no longer defines this child package.
8430            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8431                // If this is a parent package for an updated system app and this system
8432                // app got an OTA update which no longer defines some of the child packages
8433                // we have to prune them from the disabled system packages.
8434                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8435                if (disabledPs != null) {
8436                    final int scannedChildCount = (pkg.childPackages != null)
8437                            ? pkg.childPackages.size() : 0;
8438                    final int disabledChildCount = disabledPs.childPackageNames != null
8439                            ? disabledPs.childPackageNames.size() : 0;
8440                    for (int i = 0; i < disabledChildCount; i++) {
8441                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8442                        boolean disabledPackageAvailable = false;
8443                        for (int j = 0; j < scannedChildCount; j++) {
8444                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8445                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8446                                disabledPackageAvailable = true;
8447                                break;
8448                            }
8449                         }
8450                         if (!disabledPackageAvailable) {
8451                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8452                         }
8453                    }
8454                }
8455            }
8456        }
8457
8458        boolean updatedPkgBetter = false;
8459        // First check if this is a system package that may involve an update
8460        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8461            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8462            // it needs to drop FLAG_PRIVILEGED.
8463            if (locationIsPrivileged(scanFile)) {
8464                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8465            } else {
8466                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8467            }
8468
8469            if (ps != null && !ps.codePath.equals(scanFile)) {
8470                // The path has changed from what was last scanned...  check the
8471                // version of the new path against what we have stored to determine
8472                // what to do.
8473                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8474                if (pkg.mVersionCode <= ps.versionCode) {
8475                    // The system package has been updated and the code path does not match
8476                    // Ignore entry. Skip it.
8477                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8478                            + " ignored: updated version " + ps.versionCode
8479                            + " better than this " + pkg.mVersionCode);
8480                    if (!updatedPkg.codePath.equals(scanFile)) {
8481                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8482                                + ps.name + " changing from " + updatedPkg.codePathString
8483                                + " to " + scanFile);
8484                        updatedPkg.codePath = scanFile;
8485                        updatedPkg.codePathString = scanFile.toString();
8486                        updatedPkg.resourcePath = scanFile;
8487                        updatedPkg.resourcePathString = scanFile.toString();
8488                    }
8489                    updatedPkg.pkg = pkg;
8490                    updatedPkg.versionCode = pkg.mVersionCode;
8491
8492                    // Update the disabled system child packages to point to the package too.
8493                    final int childCount = updatedPkg.childPackageNames != null
8494                            ? updatedPkg.childPackageNames.size() : 0;
8495                    for (int i = 0; i < childCount; i++) {
8496                        String childPackageName = updatedPkg.childPackageNames.get(i);
8497                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8498                                childPackageName);
8499                        if (updatedChildPkg != null) {
8500                            updatedChildPkg.pkg = pkg;
8501                            updatedChildPkg.versionCode = pkg.mVersionCode;
8502                        }
8503                    }
8504
8505                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8506                            + scanFile + " ignored: updated version " + ps.versionCode
8507                            + " better than this " + pkg.mVersionCode);
8508                } else {
8509                    // The current app on the system partition is better than
8510                    // what we have updated to on the data partition; switch
8511                    // back to the system partition version.
8512                    // At this point, its safely assumed that package installation for
8513                    // apps in system partition will go through. If not there won't be a working
8514                    // version of the app
8515                    // writer
8516                    synchronized (mPackages) {
8517                        // Just remove the loaded entries from package lists.
8518                        mPackages.remove(ps.name);
8519                    }
8520
8521                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8522                            + " reverting from " + ps.codePathString
8523                            + ": new version " + pkg.mVersionCode
8524                            + " better than installed " + ps.versionCode);
8525
8526                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8527                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8528                    synchronized (mInstallLock) {
8529                        args.cleanUpResourcesLI();
8530                    }
8531                    synchronized (mPackages) {
8532                        mSettings.enableSystemPackageLPw(ps.name);
8533                    }
8534                    updatedPkgBetter = true;
8535                }
8536            }
8537        }
8538
8539        if (updatedPkg != null) {
8540            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8541            // initially
8542            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8543
8544            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8545            // flag set initially
8546            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8547                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8548            }
8549        }
8550
8551        // Verify certificates against what was last scanned
8552        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8553
8554        /*
8555         * A new system app appeared, but we already had a non-system one of the
8556         * same name installed earlier.
8557         */
8558        boolean shouldHideSystemApp = false;
8559        if (updatedPkg == null && ps != null
8560                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8561            /*
8562             * Check to make sure the signatures match first. If they don't,
8563             * wipe the installed application and its data.
8564             */
8565            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8566                    != PackageManager.SIGNATURE_MATCH) {
8567                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8568                        + " signatures don't match existing userdata copy; removing");
8569                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8570                        "scanPackageInternalLI")) {
8571                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8572                }
8573                ps = null;
8574            } else {
8575                /*
8576                 * If the newly-added system app is an older version than the
8577                 * already installed version, hide it. It will be scanned later
8578                 * and re-added like an update.
8579                 */
8580                if (pkg.mVersionCode <= ps.versionCode) {
8581                    shouldHideSystemApp = true;
8582                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8583                            + " but new version " + pkg.mVersionCode + " better than installed "
8584                            + ps.versionCode + "; hiding system");
8585                } else {
8586                    /*
8587                     * The newly found system app is a newer version that the
8588                     * one previously installed. Simply remove the
8589                     * already-installed application and replace it with our own
8590                     * while keeping the application data.
8591                     */
8592                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8593                            + " reverting from " + ps.codePathString + ": new version "
8594                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8595                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8596                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8597                    synchronized (mInstallLock) {
8598                        args.cleanUpResourcesLI();
8599                    }
8600                }
8601            }
8602        }
8603
8604        // The apk is forward locked (not public) if its code and resources
8605        // are kept in different files. (except for app in either system or
8606        // vendor path).
8607        // TODO grab this value from PackageSettings
8608        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8609            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8610                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8611            }
8612        }
8613
8614        // TODO: extend to support forward-locked splits
8615        String resourcePath = null;
8616        String baseResourcePath = null;
8617        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8618            if (ps != null && ps.resourcePathString != null) {
8619                resourcePath = ps.resourcePathString;
8620                baseResourcePath = ps.resourcePathString;
8621            } else {
8622                // Should not happen at all. Just log an error.
8623                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8624            }
8625        } else {
8626            resourcePath = pkg.codePath;
8627            baseResourcePath = pkg.baseCodePath;
8628        }
8629
8630        // Set application objects path explicitly.
8631        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8632        pkg.setApplicationInfoCodePath(pkg.codePath);
8633        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8634        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8635        pkg.setApplicationInfoResourcePath(resourcePath);
8636        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8637        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8638
8639        final int userId = ((user == null) ? 0 : user.getIdentifier());
8640        if (ps != null && ps.getInstantApp(userId)) {
8641            scanFlags |= SCAN_AS_INSTANT_APP;
8642        }
8643
8644        // Note that we invoke the following method only if we are about to unpack an application
8645        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8646                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8647
8648        /*
8649         * If the system app should be overridden by a previously installed
8650         * data, hide the system app now and let the /data/app scan pick it up
8651         * again.
8652         */
8653        if (shouldHideSystemApp) {
8654            synchronized (mPackages) {
8655                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8656            }
8657        }
8658
8659        return scannedPkg;
8660    }
8661
8662    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8663        // Derive the new package synthetic package name
8664        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8665                + pkg.staticSharedLibVersion);
8666    }
8667
8668    private static String fixProcessName(String defProcessName,
8669            String processName) {
8670        if (processName == null) {
8671            return defProcessName;
8672        }
8673        return processName;
8674    }
8675
8676    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8677            throws PackageManagerException {
8678        if (pkgSetting.signatures.mSignatures != null) {
8679            // Already existing package. Make sure signatures match
8680            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
8681                    == PackageManager.SIGNATURE_MATCH;
8682            if (!match) {
8683                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
8684                        == PackageManager.SIGNATURE_MATCH;
8685            }
8686            if (!match) {
8687                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
8688                        == PackageManager.SIGNATURE_MATCH;
8689            }
8690            if (!match) {
8691                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
8692                        + pkg.packageName + " signatures do not match the "
8693                        + "previously installed version; ignoring!");
8694            }
8695        }
8696
8697        // Check for shared user signatures
8698        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
8699            // Already existing package. Make sure signatures match
8700            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
8701                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
8702            if (!match) {
8703                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
8704                        == PackageManager.SIGNATURE_MATCH;
8705            }
8706            if (!match) {
8707                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
8708                        == PackageManager.SIGNATURE_MATCH;
8709            }
8710            if (!match) {
8711                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
8712                        "Package " + pkg.packageName
8713                        + " has no signatures that match those in shared user "
8714                        + pkgSetting.sharedUser.name + "; ignoring!");
8715            }
8716        }
8717    }
8718
8719    /**
8720     * Enforces that only the system UID or root's UID can call a method exposed
8721     * via Binder.
8722     *
8723     * @param message used as message if SecurityException is thrown
8724     * @throws SecurityException if the caller is not system or root
8725     */
8726    private static final void enforceSystemOrRoot(String message) {
8727        final int uid = Binder.getCallingUid();
8728        if (uid != Process.SYSTEM_UID && uid != 0) {
8729            throw new SecurityException(message);
8730        }
8731    }
8732
8733    @Override
8734    public void performFstrimIfNeeded() {
8735        enforceSystemOrRoot("Only the system can request fstrim");
8736
8737        // Before everything else, see whether we need to fstrim.
8738        try {
8739            IStorageManager sm = PackageHelper.getStorageManager();
8740            if (sm != null) {
8741                boolean doTrim = false;
8742                final long interval = android.provider.Settings.Global.getLong(
8743                        mContext.getContentResolver(),
8744                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8745                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8746                if (interval > 0) {
8747                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8748                    if (timeSinceLast > interval) {
8749                        doTrim = true;
8750                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8751                                + "; running immediately");
8752                    }
8753                }
8754                if (doTrim) {
8755                    final boolean dexOptDialogShown;
8756                    synchronized (mPackages) {
8757                        dexOptDialogShown = mDexOptDialogShown;
8758                    }
8759                    if (!isFirstBoot() && dexOptDialogShown) {
8760                        try {
8761                            ActivityManager.getService().showBootMessage(
8762                                    mContext.getResources().getString(
8763                                            R.string.android_upgrading_fstrim), true);
8764                        } catch (RemoteException e) {
8765                        }
8766                    }
8767                    sm.runMaintenance();
8768                }
8769            } else {
8770                Slog.e(TAG, "storageManager service unavailable!");
8771            }
8772        } catch (RemoteException e) {
8773            // Can't happen; StorageManagerService is local
8774        }
8775    }
8776
8777    @Override
8778    public void updatePackagesIfNeeded() {
8779        enforceSystemOrRoot("Only the system can request package update");
8780
8781        // We need to re-extract after an OTA.
8782        boolean causeUpgrade = isUpgrade();
8783
8784        // First boot or factory reset.
8785        // Note: we also handle devices that are upgrading to N right now as if it is their
8786        //       first boot, as they do not have profile data.
8787        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8788
8789        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8790        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8791
8792        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8793            return;
8794        }
8795
8796        List<PackageParser.Package> pkgs;
8797        synchronized (mPackages) {
8798            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8799        }
8800
8801        final long startTime = System.nanoTime();
8802        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8803                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
8804
8805        final int elapsedTimeSeconds =
8806                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8807
8808        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8809        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8810        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8811        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8812        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8813    }
8814
8815    /**
8816     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8817     * containing statistics about the invocation. The array consists of three elements,
8818     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8819     * and {@code numberOfPackagesFailed}.
8820     */
8821    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8822            String compilerFilter) {
8823
8824        int numberOfPackagesVisited = 0;
8825        int numberOfPackagesOptimized = 0;
8826        int numberOfPackagesSkipped = 0;
8827        int numberOfPackagesFailed = 0;
8828        final int numberOfPackagesToDexopt = pkgs.size();
8829
8830        for (PackageParser.Package pkg : pkgs) {
8831            numberOfPackagesVisited++;
8832
8833            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8834                if (DEBUG_DEXOPT) {
8835                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8836                }
8837                numberOfPackagesSkipped++;
8838                continue;
8839            }
8840
8841            if (DEBUG_DEXOPT) {
8842                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8843                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8844            }
8845
8846            if (showDialog) {
8847                try {
8848                    ActivityManager.getService().showBootMessage(
8849                            mContext.getResources().getString(R.string.android_upgrading_apk,
8850                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8851                } catch (RemoteException e) {
8852                }
8853                synchronized (mPackages) {
8854                    mDexOptDialogShown = true;
8855                }
8856            }
8857
8858            // If the OTA updates a system app which was previously preopted to a non-preopted state
8859            // the app might end up being verified at runtime. That's because by default the apps
8860            // are verify-profile but for preopted apps there's no profile.
8861            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
8862            // that before the OTA the app was preopted) the app gets compiled with a non-profile
8863            // filter (by default 'quicken').
8864            // Note that at this stage unused apps are already filtered.
8865            if (isSystemApp(pkg) &&
8866                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
8867                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
8868                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
8869            }
8870
8871            // checkProfiles is false to avoid merging profiles during boot which
8872            // might interfere with background compilation (b/28612421).
8873            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8874            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8875            // trade-off worth doing to save boot time work.
8876            int dexOptStatus = performDexOptTraced(pkg.packageName,
8877                    false /* checkProfiles */,
8878                    compilerFilter,
8879                    false /* force */);
8880            switch (dexOptStatus) {
8881                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8882                    numberOfPackagesOptimized++;
8883                    break;
8884                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8885                    numberOfPackagesSkipped++;
8886                    break;
8887                case PackageDexOptimizer.DEX_OPT_FAILED:
8888                    numberOfPackagesFailed++;
8889                    break;
8890                default:
8891                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
8892                    break;
8893            }
8894        }
8895
8896        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8897                numberOfPackagesFailed };
8898    }
8899
8900    @Override
8901    public void notifyPackageUse(String packageName, int reason) {
8902        synchronized (mPackages) {
8903            PackageParser.Package p = mPackages.get(packageName);
8904            if (p == null) {
8905                return;
8906            }
8907            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8908        }
8909    }
8910
8911    @Override
8912    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
8913        int userId = UserHandle.getCallingUserId();
8914        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8915        if (ai == null) {
8916            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8917                + loadingPackageName + ", user=" + userId);
8918            return;
8919        }
8920        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
8921    }
8922
8923    @Override
8924    public boolean performDexOpt(String packageName,
8925            boolean checkProfiles, int compileReason, boolean force) {
8926        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8927                getCompilerFilterForReason(compileReason), force);
8928        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8929    }
8930
8931    @Override
8932    public boolean performDexOptMode(String packageName,
8933            boolean checkProfiles, String targetCompilerFilter, boolean force) {
8934        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
8935                targetCompilerFilter, force);
8936        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8937    }
8938
8939    private int performDexOptTraced(String packageName,
8940                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8941        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8942        try {
8943            return performDexOptInternal(packageName, checkProfiles,
8944                    targetCompilerFilter, force);
8945        } finally {
8946            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8947        }
8948    }
8949
8950    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8951    // if the package can now be considered up to date for the given filter.
8952    private int performDexOptInternal(String packageName,
8953                boolean checkProfiles, String targetCompilerFilter, boolean force) {
8954        PackageParser.Package p;
8955        synchronized (mPackages) {
8956            p = mPackages.get(packageName);
8957            if (p == null) {
8958                // Package could not be found. Report failure.
8959                return PackageDexOptimizer.DEX_OPT_FAILED;
8960            }
8961            mPackageUsage.maybeWriteAsync(mPackages);
8962            mCompilerStats.maybeWriteAsync();
8963        }
8964        long callingId = Binder.clearCallingIdentity();
8965        try {
8966            synchronized (mInstallLock) {
8967                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
8968                        targetCompilerFilter, force);
8969            }
8970        } finally {
8971            Binder.restoreCallingIdentity(callingId);
8972        }
8973    }
8974
8975    public ArraySet<String> getOptimizablePackages() {
8976        ArraySet<String> pkgs = new ArraySet<String>();
8977        synchronized (mPackages) {
8978            for (PackageParser.Package p : mPackages.values()) {
8979                if (PackageDexOptimizer.canOptimizePackage(p)) {
8980                    pkgs.add(p.packageName);
8981                }
8982            }
8983        }
8984        return pkgs;
8985    }
8986
8987    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
8988            boolean checkProfiles, String targetCompilerFilter,
8989            boolean force) {
8990        // Select the dex optimizer based on the force parameter.
8991        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
8992        //       allocate an object here.
8993        PackageDexOptimizer pdo = force
8994                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
8995                : mPackageDexOptimizer;
8996
8997        // Dexopt all dependencies first. Note: we ignore the return value and march on
8998        // on errors.
8999        // Note that we are going to call performDexOpt on those libraries as many times as
9000        // they are referenced in packages. When we do a batch of performDexOpt (for example
9001        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9002        // and the first package that uses the library will dexopt it. The
9003        // others will see that the compiled code for the library is up to date.
9004        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9005        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9006        if (!deps.isEmpty()) {
9007            for (PackageParser.Package depPackage : deps) {
9008                // TODO: Analyze and investigate if we (should) profile libraries.
9009                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9010                        false /* checkProfiles */,
9011                        targetCompilerFilter,
9012                        getOrCreateCompilerPackageStats(depPackage),
9013                        true /* isUsedByOtherApps */);
9014            }
9015        }
9016        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
9017                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
9018                mDexManager.isUsedByOtherApps(p.packageName));
9019    }
9020
9021    // Performs dexopt on the used secondary dex files belonging to the given package.
9022    // Returns true if all dex files were process successfully (which could mean either dexopt or
9023    // skip). Returns false if any of the files caused errors.
9024    @Override
9025    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9026            boolean force) {
9027        mDexManager.reconcileSecondaryDexFiles(packageName);
9028        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
9029    }
9030
9031    public boolean performDexOptSecondary(String packageName, int compileReason,
9032            boolean force) {
9033        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
9034    }
9035
9036    /**
9037     * Reconcile the information we have about the secondary dex files belonging to
9038     * {@code packagName} and the actual dex files. For all dex files that were
9039     * deleted, update the internal records and delete the generated oat files.
9040     */
9041    @Override
9042    public void reconcileSecondaryDexFiles(String packageName) {
9043        mDexManager.reconcileSecondaryDexFiles(packageName);
9044    }
9045
9046    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9047    // a reference there.
9048    /*package*/ DexManager getDexManager() {
9049        return mDexManager;
9050    }
9051
9052    /**
9053     * Execute the background dexopt job immediately.
9054     */
9055    @Override
9056    public boolean runBackgroundDexoptJob() {
9057        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9058    }
9059
9060    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9061        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9062                || p.usesStaticLibraries != null) {
9063            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9064            Set<String> collectedNames = new HashSet<>();
9065            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9066
9067            retValue.remove(p);
9068
9069            return retValue;
9070        } else {
9071            return Collections.emptyList();
9072        }
9073    }
9074
9075    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9076            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9077        if (!collectedNames.contains(p.packageName)) {
9078            collectedNames.add(p.packageName);
9079            collected.add(p);
9080
9081            if (p.usesLibraries != null) {
9082                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9083                        null, collected, collectedNames);
9084            }
9085            if (p.usesOptionalLibraries != null) {
9086                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9087                        null, collected, collectedNames);
9088            }
9089            if (p.usesStaticLibraries != null) {
9090                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9091                        p.usesStaticLibrariesVersions, collected, collectedNames);
9092            }
9093        }
9094    }
9095
9096    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9097            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9098        final int libNameCount = libs.size();
9099        for (int i = 0; i < libNameCount; i++) {
9100            String libName = libs.get(i);
9101            int version = (versions != null && versions.length == libNameCount)
9102                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9103            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9104            if (libPkg != null) {
9105                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9106            }
9107        }
9108    }
9109
9110    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9111        synchronized (mPackages) {
9112            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9113            if (libEntry != null) {
9114                return mPackages.get(libEntry.apk);
9115            }
9116            return null;
9117        }
9118    }
9119
9120    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9121        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9122        if (versionedLib == null) {
9123            return null;
9124        }
9125        return versionedLib.get(version);
9126    }
9127
9128    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9129        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9130                pkg.staticSharedLibName);
9131        if (versionedLib == null) {
9132            return null;
9133        }
9134        int previousLibVersion = -1;
9135        final int versionCount = versionedLib.size();
9136        for (int i = 0; i < versionCount; i++) {
9137            final int libVersion = versionedLib.keyAt(i);
9138            if (libVersion < pkg.staticSharedLibVersion) {
9139                previousLibVersion = Math.max(previousLibVersion, libVersion);
9140            }
9141        }
9142        if (previousLibVersion >= 0) {
9143            return versionedLib.get(previousLibVersion);
9144        }
9145        return null;
9146    }
9147
9148    public void shutdown() {
9149        mPackageUsage.writeNow(mPackages);
9150        mCompilerStats.writeNow();
9151    }
9152
9153    @Override
9154    public void dumpProfiles(String packageName) {
9155        PackageParser.Package pkg;
9156        synchronized (mPackages) {
9157            pkg = mPackages.get(packageName);
9158            if (pkg == null) {
9159                throw new IllegalArgumentException("Unknown package: " + packageName);
9160            }
9161        }
9162        /* Only the shell, root, or the app user should be able to dump profiles. */
9163        int callingUid = Binder.getCallingUid();
9164        if (callingUid != Process.SHELL_UID &&
9165            callingUid != Process.ROOT_UID &&
9166            callingUid != pkg.applicationInfo.uid) {
9167            throw new SecurityException("dumpProfiles");
9168        }
9169
9170        synchronized (mInstallLock) {
9171            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9172            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9173            try {
9174                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9175                String codePaths = TextUtils.join(";", allCodePaths);
9176                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9177            } catch (InstallerException e) {
9178                Slog.w(TAG, "Failed to dump profiles", e);
9179            }
9180            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9181        }
9182    }
9183
9184    @Override
9185    public void forceDexOpt(String packageName) {
9186        enforceSystemOrRoot("forceDexOpt");
9187
9188        PackageParser.Package pkg;
9189        synchronized (mPackages) {
9190            pkg = mPackages.get(packageName);
9191            if (pkg == null) {
9192                throw new IllegalArgumentException("Unknown package: " + packageName);
9193            }
9194        }
9195
9196        synchronized (mInstallLock) {
9197            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9198
9199            // Whoever is calling forceDexOpt wants a compiled package.
9200            // Don't use profiles since that may cause compilation to be skipped.
9201            final int res = performDexOptInternalWithDependenciesLI(pkg,
9202                    false /* checkProfiles */, getDefaultCompilerFilter(),
9203                    true /* force */);
9204
9205            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9206            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9207                throw new IllegalStateException("Failed to dexopt: " + res);
9208            }
9209        }
9210    }
9211
9212    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9213        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9214            Slog.w(TAG, "Unable to update from " + oldPkg.name
9215                    + " to " + newPkg.packageName
9216                    + ": old package not in system partition");
9217            return false;
9218        } else if (mPackages.get(oldPkg.name) != null) {
9219            Slog.w(TAG, "Unable to update from " + oldPkg.name
9220                    + " to " + newPkg.packageName
9221                    + ": old package still exists");
9222            return false;
9223        }
9224        return true;
9225    }
9226
9227    void removeCodePathLI(File codePath) {
9228        if (codePath.isDirectory()) {
9229            try {
9230                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9231            } catch (InstallerException e) {
9232                Slog.w(TAG, "Failed to remove code path", e);
9233            }
9234        } else {
9235            codePath.delete();
9236        }
9237    }
9238
9239    private int[] resolveUserIds(int userId) {
9240        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9241    }
9242
9243    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9244        if (pkg == null) {
9245            Slog.wtf(TAG, "Package was null!", new Throwable());
9246            return;
9247        }
9248        clearAppDataLeafLIF(pkg, userId, flags);
9249        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9250        for (int i = 0; i < childCount; i++) {
9251            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9252        }
9253    }
9254
9255    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9256        final PackageSetting ps;
9257        synchronized (mPackages) {
9258            ps = mSettings.mPackages.get(pkg.packageName);
9259        }
9260        for (int realUserId : resolveUserIds(userId)) {
9261            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9262            try {
9263                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9264                        ceDataInode);
9265            } catch (InstallerException e) {
9266                Slog.w(TAG, String.valueOf(e));
9267            }
9268        }
9269    }
9270
9271    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9272        if (pkg == null) {
9273            Slog.wtf(TAG, "Package was null!", new Throwable());
9274            return;
9275        }
9276        destroyAppDataLeafLIF(pkg, userId, flags);
9277        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9278        for (int i = 0; i < childCount; i++) {
9279            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9280        }
9281    }
9282
9283    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9284        final PackageSetting ps;
9285        synchronized (mPackages) {
9286            ps = mSettings.mPackages.get(pkg.packageName);
9287        }
9288        for (int realUserId : resolveUserIds(userId)) {
9289            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9290            try {
9291                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9292                        ceDataInode);
9293            } catch (InstallerException e) {
9294                Slog.w(TAG, String.valueOf(e));
9295            }
9296            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9297        }
9298    }
9299
9300    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9301        if (pkg == null) {
9302            Slog.wtf(TAG, "Package was null!", new Throwable());
9303            return;
9304        }
9305        destroyAppProfilesLeafLIF(pkg);
9306        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9307        for (int i = 0; i < childCount; i++) {
9308            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9309        }
9310    }
9311
9312    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9313        try {
9314            mInstaller.destroyAppProfiles(pkg.packageName);
9315        } catch (InstallerException e) {
9316            Slog.w(TAG, String.valueOf(e));
9317        }
9318    }
9319
9320    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9321        if (pkg == null) {
9322            Slog.wtf(TAG, "Package was null!", new Throwable());
9323            return;
9324        }
9325        clearAppProfilesLeafLIF(pkg);
9326        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9327        for (int i = 0; i < childCount; i++) {
9328            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9329        }
9330    }
9331
9332    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9333        try {
9334            mInstaller.clearAppProfiles(pkg.packageName);
9335        } catch (InstallerException e) {
9336            Slog.w(TAG, String.valueOf(e));
9337        }
9338    }
9339
9340    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9341            long lastUpdateTime) {
9342        // Set parent install/update time
9343        PackageSetting ps = (PackageSetting) pkg.mExtras;
9344        if (ps != null) {
9345            ps.firstInstallTime = firstInstallTime;
9346            ps.lastUpdateTime = lastUpdateTime;
9347        }
9348        // Set children install/update time
9349        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9350        for (int i = 0; i < childCount; i++) {
9351            PackageParser.Package childPkg = pkg.childPackages.get(i);
9352            ps = (PackageSetting) childPkg.mExtras;
9353            if (ps != null) {
9354                ps.firstInstallTime = firstInstallTime;
9355                ps.lastUpdateTime = lastUpdateTime;
9356            }
9357        }
9358    }
9359
9360    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9361            PackageParser.Package changingLib) {
9362        if (file.path != null) {
9363            usesLibraryFiles.add(file.path);
9364            return;
9365        }
9366        PackageParser.Package p = mPackages.get(file.apk);
9367        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9368            // If we are doing this while in the middle of updating a library apk,
9369            // then we need to make sure to use that new apk for determining the
9370            // dependencies here.  (We haven't yet finished committing the new apk
9371            // to the package manager state.)
9372            if (p == null || p.packageName.equals(changingLib.packageName)) {
9373                p = changingLib;
9374            }
9375        }
9376        if (p != null) {
9377            usesLibraryFiles.addAll(p.getAllCodePaths());
9378            if (p.usesLibraryFiles != null) {
9379                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9380            }
9381        }
9382    }
9383
9384    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9385            PackageParser.Package changingLib) throws PackageManagerException {
9386        if (pkg == null) {
9387            return;
9388        }
9389        ArraySet<String> usesLibraryFiles = null;
9390        if (pkg.usesLibraries != null) {
9391            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9392                    null, null, pkg.packageName, changingLib, true, null);
9393        }
9394        if (pkg.usesStaticLibraries != null) {
9395            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9396                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9397                    pkg.packageName, changingLib, true, usesLibraryFiles);
9398        }
9399        if (pkg.usesOptionalLibraries != null) {
9400            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9401                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9402        }
9403        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9404            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9405        } else {
9406            pkg.usesLibraryFiles = null;
9407        }
9408    }
9409
9410    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9411            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9412            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9413            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9414            throws PackageManagerException {
9415        final int libCount = requestedLibraries.size();
9416        for (int i = 0; i < libCount; i++) {
9417            final String libName = requestedLibraries.get(i);
9418            final int libVersion = requiredVersions != null ? requiredVersions[i]
9419                    : SharedLibraryInfo.VERSION_UNDEFINED;
9420            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9421            if (libEntry == null) {
9422                if (required) {
9423                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9424                            "Package " + packageName + " requires unavailable shared library "
9425                                    + libName + "; failing!");
9426                } else if (DEBUG_SHARED_LIBRARIES) {
9427                    Slog.i(TAG, "Package " + packageName
9428                            + " desires unavailable shared library "
9429                            + libName + "; ignoring!");
9430                }
9431            } else {
9432                if (requiredVersions != null && requiredCertDigests != null) {
9433                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9434                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9435                            "Package " + packageName + " requires unavailable static shared"
9436                                    + " library " + libName + " version "
9437                                    + libEntry.info.getVersion() + "; failing!");
9438                    }
9439
9440                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9441                    if (libPkg == null) {
9442                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9443                                "Package " + packageName + " requires unavailable static shared"
9444                                        + " library; failing!");
9445                    }
9446
9447                    String expectedCertDigest = requiredCertDigests[i];
9448                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9449                                libPkg.mSignatures[0]);
9450                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9451                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9452                                "Package " + packageName + " requires differently signed" +
9453                                        " static shared library; failing!");
9454                    }
9455                }
9456
9457                if (outUsedLibraries == null) {
9458                    outUsedLibraries = new ArraySet<>();
9459                }
9460                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9461            }
9462        }
9463        return outUsedLibraries;
9464    }
9465
9466    private static boolean hasString(List<String> list, List<String> which) {
9467        if (list == null) {
9468            return false;
9469        }
9470        for (int i=list.size()-1; i>=0; i--) {
9471            for (int j=which.size()-1; j>=0; j--) {
9472                if (which.get(j).equals(list.get(i))) {
9473                    return true;
9474                }
9475            }
9476        }
9477        return false;
9478    }
9479
9480    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9481            PackageParser.Package changingPkg) {
9482        ArrayList<PackageParser.Package> res = null;
9483        for (PackageParser.Package pkg : mPackages.values()) {
9484            if (changingPkg != null
9485                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9486                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9487                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9488                            changingPkg.staticSharedLibName)) {
9489                return null;
9490            }
9491            if (res == null) {
9492                res = new ArrayList<>();
9493            }
9494            res.add(pkg);
9495            try {
9496                updateSharedLibrariesLPr(pkg, changingPkg);
9497            } catch (PackageManagerException e) {
9498                // If a system app update or an app and a required lib missing we
9499                // delete the package and for updated system apps keep the data as
9500                // it is better for the user to reinstall than to be in an limbo
9501                // state. Also libs disappearing under an app should never happen
9502                // - just in case.
9503                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9504                    final int flags = pkg.isUpdatedSystemApp()
9505                            ? PackageManager.DELETE_KEEP_DATA : 0;
9506                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9507                            flags , null, true, null);
9508                }
9509                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9510            }
9511        }
9512        return res;
9513    }
9514
9515    /**
9516     * Derive the value of the {@code cpuAbiOverride} based on the provided
9517     * value and an optional stored value from the package settings.
9518     */
9519    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9520        String cpuAbiOverride = null;
9521
9522        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9523            cpuAbiOverride = null;
9524        } else if (abiOverride != null) {
9525            cpuAbiOverride = abiOverride;
9526        } else if (settings != null) {
9527            cpuAbiOverride = settings.cpuAbiOverrideString;
9528        }
9529
9530        return cpuAbiOverride;
9531    }
9532
9533    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9534            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9535                    throws PackageManagerException {
9536        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9537        // If the package has children and this is the first dive in the function
9538        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9539        // whether all packages (parent and children) would be successfully scanned
9540        // before the actual scan since scanning mutates internal state and we want
9541        // to atomically install the package and its children.
9542        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9543            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9544                scanFlags |= SCAN_CHECK_ONLY;
9545            }
9546        } else {
9547            scanFlags &= ~SCAN_CHECK_ONLY;
9548        }
9549
9550        final PackageParser.Package scannedPkg;
9551        try {
9552            // Scan the parent
9553            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9554            // Scan the children
9555            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9556            for (int i = 0; i < childCount; i++) {
9557                PackageParser.Package childPkg = pkg.childPackages.get(i);
9558                scanPackageLI(childPkg, policyFlags,
9559                        scanFlags, currentTime, user);
9560            }
9561        } finally {
9562            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9563        }
9564
9565        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9566            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9567        }
9568
9569        return scannedPkg;
9570    }
9571
9572    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9573            int scanFlags, long currentTime, @Nullable UserHandle user)
9574                    throws PackageManagerException {
9575        boolean success = false;
9576        try {
9577            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9578                    currentTime, user);
9579            success = true;
9580            return res;
9581        } finally {
9582            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9583                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9584                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9585                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9586                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9587            }
9588        }
9589    }
9590
9591    /**
9592     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9593     */
9594    private static boolean apkHasCode(String fileName) {
9595        StrictJarFile jarFile = null;
9596        try {
9597            jarFile = new StrictJarFile(fileName,
9598                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9599            return jarFile.findEntry("classes.dex") != null;
9600        } catch (IOException ignore) {
9601        } finally {
9602            try {
9603                if (jarFile != null) {
9604                    jarFile.close();
9605                }
9606            } catch (IOException ignore) {}
9607        }
9608        return false;
9609    }
9610
9611    /**
9612     * Enforces code policy for the package. This ensures that if an APK has
9613     * declared hasCode="true" in its manifest that the APK actually contains
9614     * code.
9615     *
9616     * @throws PackageManagerException If bytecode could not be found when it should exist
9617     */
9618    private static void assertCodePolicy(PackageParser.Package pkg)
9619            throws PackageManagerException {
9620        final boolean shouldHaveCode =
9621                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9622        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9623            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9624                    "Package " + pkg.baseCodePath + " code is missing");
9625        }
9626
9627        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9628            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9629                final boolean splitShouldHaveCode =
9630                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9631                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9632                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9633                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9634                }
9635            }
9636        }
9637    }
9638
9639    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9640            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9641                    throws PackageManagerException {
9642        if (DEBUG_PACKAGE_SCANNING) {
9643            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9644                Log.d(TAG, "Scanning package " + pkg.packageName);
9645        }
9646
9647        applyPolicy(pkg, policyFlags);
9648
9649        assertPackageIsValid(pkg, policyFlags, scanFlags);
9650
9651        // Initialize package source and resource directories
9652        final File scanFile = new File(pkg.codePath);
9653        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9654        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9655
9656        SharedUserSetting suid = null;
9657        PackageSetting pkgSetting = null;
9658
9659        // Getting the package setting may have a side-effect, so if we
9660        // are only checking if scan would succeed, stash a copy of the
9661        // old setting to restore at the end.
9662        PackageSetting nonMutatedPs = null;
9663
9664        // We keep references to the derived CPU Abis from settings in oder to reuse
9665        // them in the case where we're not upgrading or booting for the first time.
9666        String primaryCpuAbiFromSettings = null;
9667        String secondaryCpuAbiFromSettings = null;
9668
9669        // writer
9670        synchronized (mPackages) {
9671            if (pkg.mSharedUserId != null) {
9672                // SIDE EFFECTS; may potentially allocate a new shared user
9673                suid = mSettings.getSharedUserLPw(
9674                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9675                if (DEBUG_PACKAGE_SCANNING) {
9676                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9677                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9678                                + "): packages=" + suid.packages);
9679                }
9680            }
9681
9682            // Check if we are renaming from an original package name.
9683            PackageSetting origPackage = null;
9684            String realName = null;
9685            if (pkg.mOriginalPackages != null) {
9686                // This package may need to be renamed to a previously
9687                // installed name.  Let's check on that...
9688                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9689                if (pkg.mOriginalPackages.contains(renamed)) {
9690                    // This package had originally been installed as the
9691                    // original name, and we have already taken care of
9692                    // transitioning to the new one.  Just update the new
9693                    // one to continue using the old name.
9694                    realName = pkg.mRealPackage;
9695                    if (!pkg.packageName.equals(renamed)) {
9696                        // Callers into this function may have already taken
9697                        // care of renaming the package; only do it here if
9698                        // it is not already done.
9699                        pkg.setPackageName(renamed);
9700                    }
9701                } else {
9702                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9703                        if ((origPackage = mSettings.getPackageLPr(
9704                                pkg.mOriginalPackages.get(i))) != null) {
9705                            // We do have the package already installed under its
9706                            // original name...  should we use it?
9707                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9708                                // New package is not compatible with original.
9709                                origPackage = null;
9710                                continue;
9711                            } else if (origPackage.sharedUser != null) {
9712                                // Make sure uid is compatible between packages.
9713                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9714                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9715                                            + " to " + pkg.packageName + ": old uid "
9716                                            + origPackage.sharedUser.name
9717                                            + " differs from " + pkg.mSharedUserId);
9718                                    origPackage = null;
9719                                    continue;
9720                                }
9721                                // TODO: Add case when shared user id is added [b/28144775]
9722                            } else {
9723                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9724                                        + pkg.packageName + " to old name " + origPackage.name);
9725                            }
9726                            break;
9727                        }
9728                    }
9729                }
9730            }
9731
9732            if (mTransferedPackages.contains(pkg.packageName)) {
9733                Slog.w(TAG, "Package " + pkg.packageName
9734                        + " was transferred to another, but its .apk remains");
9735            }
9736
9737            // See comments in nonMutatedPs declaration
9738            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9739                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9740                if (foundPs != null) {
9741                    nonMutatedPs = new PackageSetting(foundPs);
9742                }
9743            }
9744
9745            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9746                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9747                if (foundPs != null) {
9748                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9749                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9750                }
9751            }
9752
9753            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9754            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9755                PackageManagerService.reportSettingsProblem(Log.WARN,
9756                        "Package " + pkg.packageName + " shared user changed from "
9757                                + (pkgSetting.sharedUser != null
9758                                        ? pkgSetting.sharedUser.name : "<nothing>")
9759                                + " to "
9760                                + (suid != null ? suid.name : "<nothing>")
9761                                + "; replacing with new");
9762                pkgSetting = null;
9763            }
9764            final PackageSetting oldPkgSetting =
9765                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9766            final PackageSetting disabledPkgSetting =
9767                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9768
9769            String[] usesStaticLibraries = null;
9770            if (pkg.usesStaticLibraries != null) {
9771                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9772                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9773            }
9774
9775            if (pkgSetting == null) {
9776                final String parentPackageName = (pkg.parentPackage != null)
9777                        ? pkg.parentPackage.packageName : null;
9778                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9779                // REMOVE SharedUserSetting from method; update in a separate call
9780                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9781                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9782                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9783                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
9784                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9785                        true /*allowInstall*/, instantApp, parentPackageName,
9786                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
9787                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
9788                // SIDE EFFECTS; updates system state; move elsewhere
9789                if (origPackage != null) {
9790                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9791                }
9792                mSettings.addUserToSettingLPw(pkgSetting);
9793            } else {
9794                // REMOVE SharedUserSetting from method; update in a separate call.
9795                //
9796                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9797                // secondaryCpuAbi are not known at this point so we always update them
9798                // to null here, only to reset them at a later point.
9799                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9800                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9801                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9802                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9803                        UserManagerService.getInstance(), usesStaticLibraries,
9804                        pkg.usesStaticLibrariesVersions);
9805            }
9806            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9807            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9808
9809            // SIDE EFFECTS; modifies system state; move elsewhere
9810            if (pkgSetting.origPackage != null) {
9811                // If we are first transitioning from an original package,
9812                // fix up the new package's name now.  We need to do this after
9813                // looking up the package under its new name, so getPackageLP
9814                // can take care of fiddling things correctly.
9815                pkg.setPackageName(origPackage.name);
9816
9817                // File a report about this.
9818                String msg = "New package " + pkgSetting.realName
9819                        + " renamed to replace old package " + pkgSetting.name;
9820                reportSettingsProblem(Log.WARN, msg);
9821
9822                // Make a note of it.
9823                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9824                    mTransferedPackages.add(origPackage.name);
9825                }
9826
9827                // No longer need to retain this.
9828                pkgSetting.origPackage = null;
9829            }
9830
9831            // SIDE EFFECTS; modifies system state; move elsewhere
9832            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9833                // Make a note of it.
9834                mTransferedPackages.add(pkg.packageName);
9835            }
9836
9837            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9838                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9839            }
9840
9841            if ((scanFlags & SCAN_BOOTING) == 0
9842                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9843                // Check all shared libraries and map to their actual file path.
9844                // We only do this here for apps not on a system dir, because those
9845                // are the only ones that can fail an install due to this.  We
9846                // will take care of the system apps by updating all of their
9847                // library paths after the scan is done. Also during the initial
9848                // scan don't update any libs as we do this wholesale after all
9849                // apps are scanned to avoid dependency based scanning.
9850                updateSharedLibrariesLPr(pkg, null);
9851            }
9852
9853            if (mFoundPolicyFile) {
9854                SELinuxMMAC.assignSeInfoValue(pkg);
9855            }
9856            pkg.applicationInfo.uid = pkgSetting.appId;
9857            pkg.mExtras = pkgSetting;
9858
9859
9860            // Static shared libs have same package with different versions where
9861            // we internally use a synthetic package name to allow multiple versions
9862            // of the same package, therefore we need to compare signatures against
9863            // the package setting for the latest library version.
9864            PackageSetting signatureCheckPs = pkgSetting;
9865            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9866                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9867                if (libraryEntry != null) {
9868                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9869                }
9870            }
9871
9872            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
9873                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
9874                    // We just determined the app is signed correctly, so bring
9875                    // over the latest parsed certs.
9876                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9877                } else {
9878                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9879                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9880                                "Package " + pkg.packageName + " upgrade keys do not match the "
9881                                + "previously installed version");
9882                    } else {
9883                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9884                        String msg = "System package " + pkg.packageName
9885                                + " signature changed; retaining data.";
9886                        reportSettingsProblem(Log.WARN, msg);
9887                    }
9888                }
9889            } else {
9890                try {
9891                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
9892                    verifySignaturesLP(signatureCheckPs, pkg);
9893                    // We just determined the app is signed correctly, so bring
9894                    // over the latest parsed certs.
9895                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9896                } catch (PackageManagerException e) {
9897                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9898                        throw e;
9899                    }
9900                    // The signature has changed, but this package is in the system
9901                    // image...  let's recover!
9902                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9903                    // However...  if this package is part of a shared user, but it
9904                    // doesn't match the signature of the shared user, let's fail.
9905                    // What this means is that you can't change the signatures
9906                    // associated with an overall shared user, which doesn't seem all
9907                    // that unreasonable.
9908                    if (signatureCheckPs.sharedUser != null) {
9909                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9910                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9911                            throw new PackageManagerException(
9912                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9913                                    "Signature mismatch for shared user: "
9914                                            + pkgSetting.sharedUser);
9915                        }
9916                    }
9917                    // File a report about this.
9918                    String msg = "System package " + pkg.packageName
9919                            + " signature changed; retaining data.";
9920                    reportSettingsProblem(Log.WARN, msg);
9921                }
9922            }
9923
9924            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9925                // This package wants to adopt ownership of permissions from
9926                // another package.
9927                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9928                    final String origName = pkg.mAdoptPermissions.get(i);
9929                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9930                    if (orig != null) {
9931                        if (verifyPackageUpdateLPr(orig, pkg)) {
9932                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9933                                    + pkg.packageName);
9934                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9935                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
9936                        }
9937                    }
9938                }
9939            }
9940        }
9941
9942        pkg.applicationInfo.processName = fixProcessName(
9943                pkg.applicationInfo.packageName,
9944                pkg.applicationInfo.processName);
9945
9946        if (pkg != mPlatformPackage) {
9947            // Get all of our default paths setup
9948            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
9949        }
9950
9951        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
9952
9953        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
9954            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9955                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
9956                derivePackageAbi(
9957                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
9958                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9959
9960                // Some system apps still use directory structure for native libraries
9961                // in which case we might end up not detecting abi solely based on apk
9962                // structure. Try to detect abi based on directory structure.
9963                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
9964                        pkg.applicationInfo.primaryCpuAbi == null) {
9965                    setBundledAppAbisAndRoots(pkg, pkgSetting);
9966                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9967                }
9968            } else {
9969                // This is not a first boot or an upgrade, don't bother deriving the
9970                // ABI during the scan. Instead, trust the value that was stored in the
9971                // package setting.
9972                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
9973                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
9974
9975                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9976
9977                if (DEBUG_ABI_SELECTION) {
9978                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
9979                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
9980                        pkg.applicationInfo.secondaryCpuAbi);
9981                }
9982            }
9983        } else {
9984            if ((scanFlags & SCAN_MOVE) != 0) {
9985                // We haven't run dex-opt for this move (since we've moved the compiled output too)
9986                // but we already have this packages package info in the PackageSetting. We just
9987                // use that and derive the native library path based on the new codepath.
9988                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
9989                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
9990            }
9991
9992            // Set native library paths again. For moves, the path will be updated based on the
9993            // ABIs we've determined above. For non-moves, the path will be updated based on the
9994            // ABIs we determined during compilation, but the path will depend on the final
9995            // package path (after the rename away from the stage path).
9996            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
9997        }
9998
9999        // This is a special case for the "system" package, where the ABI is
10000        // dictated by the zygote configuration (and init.rc). We should keep track
10001        // of this ABI so that we can deal with "normal" applications that run under
10002        // the same UID correctly.
10003        if (mPlatformPackage == pkg) {
10004            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10005                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10006        }
10007
10008        // If there's a mismatch between the abi-override in the package setting
10009        // and the abiOverride specified for the install. Warn about this because we
10010        // would've already compiled the app without taking the package setting into
10011        // account.
10012        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10013            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10014                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10015                        " for package " + pkg.packageName);
10016            }
10017        }
10018
10019        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10020        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10021        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10022
10023        // Copy the derived override back to the parsed package, so that we can
10024        // update the package settings accordingly.
10025        pkg.cpuAbiOverride = cpuAbiOverride;
10026
10027        if (DEBUG_ABI_SELECTION) {
10028            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10029                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10030                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10031        }
10032
10033        // Push the derived path down into PackageSettings so we know what to
10034        // clean up at uninstall time.
10035        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10036
10037        if (DEBUG_ABI_SELECTION) {
10038            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10039                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10040                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10041        }
10042
10043        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10044        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10045            // We don't do this here during boot because we can do it all
10046            // at once after scanning all existing packages.
10047            //
10048            // We also do this *before* we perform dexopt on this package, so that
10049            // we can avoid redundant dexopts, and also to make sure we've got the
10050            // code and package path correct.
10051            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10052        }
10053
10054        if (mFactoryTest && pkg.requestedPermissions.contains(
10055                android.Manifest.permission.FACTORY_TEST)) {
10056            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10057        }
10058
10059        if (isSystemApp(pkg)) {
10060            pkgSetting.isOrphaned = true;
10061        }
10062
10063        // Take care of first install / last update times.
10064        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10065        if (currentTime != 0) {
10066            if (pkgSetting.firstInstallTime == 0) {
10067                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10068            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10069                pkgSetting.lastUpdateTime = currentTime;
10070            }
10071        } else if (pkgSetting.firstInstallTime == 0) {
10072            // We need *something*.  Take time time stamp of the file.
10073            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10074        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10075            if (scanFileTime != pkgSetting.timeStamp) {
10076                // A package on the system image has changed; consider this
10077                // to be an update.
10078                pkgSetting.lastUpdateTime = scanFileTime;
10079            }
10080        }
10081        pkgSetting.setTimeStamp(scanFileTime);
10082
10083        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10084            if (nonMutatedPs != null) {
10085                synchronized (mPackages) {
10086                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10087                }
10088            }
10089        } else {
10090            final int userId = user == null ? 0 : user.getIdentifier();
10091            // Modify state for the given package setting
10092            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10093                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10094            if (pkgSetting.getInstantApp(userId)) {
10095                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10096            }
10097        }
10098        return pkg;
10099    }
10100
10101    /**
10102     * Applies policy to the parsed package based upon the given policy flags.
10103     * Ensures the package is in a good state.
10104     * <p>
10105     * Implementation detail: This method must NOT have any side effect. It would
10106     * ideally be static, but, it requires locks to read system state.
10107     */
10108    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10109        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10110            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10111            if (pkg.applicationInfo.isDirectBootAware()) {
10112                // we're direct boot aware; set for all components
10113                for (PackageParser.Service s : pkg.services) {
10114                    s.info.encryptionAware = s.info.directBootAware = true;
10115                }
10116                for (PackageParser.Provider p : pkg.providers) {
10117                    p.info.encryptionAware = p.info.directBootAware = true;
10118                }
10119                for (PackageParser.Activity a : pkg.activities) {
10120                    a.info.encryptionAware = a.info.directBootAware = true;
10121                }
10122                for (PackageParser.Activity r : pkg.receivers) {
10123                    r.info.encryptionAware = r.info.directBootAware = true;
10124                }
10125            }
10126        } else {
10127            // Only allow system apps to be flagged as core apps.
10128            pkg.coreApp = false;
10129            // clear flags not applicable to regular apps
10130            pkg.applicationInfo.privateFlags &=
10131                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10132            pkg.applicationInfo.privateFlags &=
10133                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10134        }
10135        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10136
10137        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10138            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10139        }
10140
10141        if (!isSystemApp(pkg)) {
10142            // Only system apps can use these features.
10143            pkg.mOriginalPackages = null;
10144            pkg.mRealPackage = null;
10145            pkg.mAdoptPermissions = null;
10146        }
10147    }
10148
10149    /**
10150     * Asserts the parsed package is valid according to the given policy. If the
10151     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10152     * <p>
10153     * Implementation detail: This method must NOT have any side effects. It would
10154     * ideally be static, but, it requires locks to read system state.
10155     *
10156     * @throws PackageManagerException If the package fails any of the validation checks
10157     */
10158    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10159            throws PackageManagerException {
10160        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10161            assertCodePolicy(pkg);
10162        }
10163
10164        if (pkg.applicationInfo.getCodePath() == null ||
10165                pkg.applicationInfo.getResourcePath() == null) {
10166            // Bail out. The resource and code paths haven't been set.
10167            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10168                    "Code and resource paths haven't been set correctly");
10169        }
10170
10171        // Make sure we're not adding any bogus keyset info
10172        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10173        ksms.assertScannedPackageValid(pkg);
10174
10175        synchronized (mPackages) {
10176            // The special "android" package can only be defined once
10177            if (pkg.packageName.equals("android")) {
10178                if (mAndroidApplication != null) {
10179                    Slog.w(TAG, "*************************************************");
10180                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10181                    Slog.w(TAG, " codePath=" + pkg.codePath);
10182                    Slog.w(TAG, "*************************************************");
10183                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10184                            "Core android package being redefined.  Skipping.");
10185                }
10186            }
10187
10188            // A package name must be unique; don't allow duplicates
10189            if (mPackages.containsKey(pkg.packageName)) {
10190                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10191                        "Application package " + pkg.packageName
10192                        + " already installed.  Skipping duplicate.");
10193            }
10194
10195            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10196                // Static libs have a synthetic package name containing the version
10197                // but we still want the base name to be unique.
10198                if (mPackages.containsKey(pkg.manifestPackageName)) {
10199                    throw new PackageManagerException(
10200                            "Duplicate static shared lib provider package");
10201                }
10202
10203                // Static shared libraries should have at least O target SDK
10204                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10205                    throw new PackageManagerException(
10206                            "Packages declaring static-shared libs must target O SDK or higher");
10207                }
10208
10209                // Package declaring static a shared lib cannot be instant apps
10210                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10211                    throw new PackageManagerException(
10212                            "Packages declaring static-shared libs cannot be instant apps");
10213                }
10214
10215                // Package declaring static a shared lib cannot be renamed since the package
10216                // name is synthetic and apps can't code around package manager internals.
10217                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10218                    throw new PackageManagerException(
10219                            "Packages declaring static-shared libs cannot be renamed");
10220                }
10221
10222                // Package declaring static a shared lib cannot declare child packages
10223                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10224                    throw new PackageManagerException(
10225                            "Packages declaring static-shared libs cannot have child packages");
10226                }
10227
10228                // Package declaring static a shared lib cannot declare dynamic libs
10229                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10230                    throw new PackageManagerException(
10231                            "Packages declaring static-shared libs cannot declare dynamic libs");
10232                }
10233
10234                // Package declaring static a shared lib cannot declare shared users
10235                if (pkg.mSharedUserId != null) {
10236                    throw new PackageManagerException(
10237                            "Packages declaring static-shared libs cannot declare shared users");
10238                }
10239
10240                // Static shared libs cannot declare activities
10241                if (!pkg.activities.isEmpty()) {
10242                    throw new PackageManagerException(
10243                            "Static shared libs cannot declare activities");
10244                }
10245
10246                // Static shared libs cannot declare services
10247                if (!pkg.services.isEmpty()) {
10248                    throw new PackageManagerException(
10249                            "Static shared libs cannot declare services");
10250                }
10251
10252                // Static shared libs cannot declare providers
10253                if (!pkg.providers.isEmpty()) {
10254                    throw new PackageManagerException(
10255                            "Static shared libs cannot declare content providers");
10256                }
10257
10258                // Static shared libs cannot declare receivers
10259                if (!pkg.receivers.isEmpty()) {
10260                    throw new PackageManagerException(
10261                            "Static shared libs cannot declare broadcast receivers");
10262                }
10263
10264                // Static shared libs cannot declare permission groups
10265                if (!pkg.permissionGroups.isEmpty()) {
10266                    throw new PackageManagerException(
10267                            "Static shared libs cannot declare permission groups");
10268                }
10269
10270                // Static shared libs cannot declare permissions
10271                if (!pkg.permissions.isEmpty()) {
10272                    throw new PackageManagerException(
10273                            "Static shared libs cannot declare permissions");
10274                }
10275
10276                // Static shared libs cannot declare protected broadcasts
10277                if (pkg.protectedBroadcasts != null) {
10278                    throw new PackageManagerException(
10279                            "Static shared libs cannot declare protected broadcasts");
10280                }
10281
10282                // Static shared libs cannot be overlay targets
10283                if (pkg.mOverlayTarget != null) {
10284                    throw new PackageManagerException(
10285                            "Static shared libs cannot be overlay targets");
10286                }
10287
10288                // The version codes must be ordered as lib versions
10289                int minVersionCode = Integer.MIN_VALUE;
10290                int maxVersionCode = Integer.MAX_VALUE;
10291
10292                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10293                        pkg.staticSharedLibName);
10294                if (versionedLib != null) {
10295                    final int versionCount = versionedLib.size();
10296                    for (int i = 0; i < versionCount; i++) {
10297                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10298                        // TODO: We will change version code to long, so in the new API it is long
10299                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
10300                                .getVersionCode();
10301                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
10302                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10303                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
10304                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10305                        } else {
10306                            minVersionCode = maxVersionCode = libVersionCode;
10307                            break;
10308                        }
10309                    }
10310                }
10311                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
10312                    throw new PackageManagerException("Static shared"
10313                            + " lib version codes must be ordered as lib versions");
10314                }
10315            }
10316
10317            // Only privileged apps and updated privileged apps can add child packages.
10318            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10319                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
10320                    throw new PackageManagerException("Only privileged apps can add child "
10321                            + "packages. Ignoring package " + pkg.packageName);
10322                }
10323                final int childCount = pkg.childPackages.size();
10324                for (int i = 0; i < childCount; i++) {
10325                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10326                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10327                            childPkg.packageName)) {
10328                        throw new PackageManagerException("Can't override child of "
10329                                + "another disabled app. Ignoring package " + pkg.packageName);
10330                    }
10331                }
10332            }
10333
10334            // If we're only installing presumed-existing packages, require that the
10335            // scanned APK is both already known and at the path previously established
10336            // for it.  Previously unknown packages we pick up normally, but if we have an
10337            // a priori expectation about this package's install presence, enforce it.
10338            // With a singular exception for new system packages. When an OTA contains
10339            // a new system package, we allow the codepath to change from a system location
10340            // to the user-installed location. If we don't allow this change, any newer,
10341            // user-installed version of the application will be ignored.
10342            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10343                if (mExpectingBetter.containsKey(pkg.packageName)) {
10344                    logCriticalInfo(Log.WARN,
10345                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10346                } else {
10347                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10348                    if (known != null) {
10349                        if (DEBUG_PACKAGE_SCANNING) {
10350                            Log.d(TAG, "Examining " + pkg.codePath
10351                                    + " and requiring known paths " + known.codePathString
10352                                    + " & " + known.resourcePathString);
10353                        }
10354                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10355                                || !pkg.applicationInfo.getResourcePath().equals(
10356                                        known.resourcePathString)) {
10357                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10358                                    "Application package " + pkg.packageName
10359                                    + " found at " + pkg.applicationInfo.getCodePath()
10360                                    + " but expected at " + known.codePathString
10361                                    + "; ignoring.");
10362                        }
10363                    }
10364                }
10365            }
10366
10367            // Verify that this new package doesn't have any content providers
10368            // that conflict with existing packages.  Only do this if the
10369            // package isn't already installed, since we don't want to break
10370            // things that are installed.
10371            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10372                final int N = pkg.providers.size();
10373                int i;
10374                for (i=0; i<N; i++) {
10375                    PackageParser.Provider p = pkg.providers.get(i);
10376                    if (p.info.authority != null) {
10377                        String names[] = p.info.authority.split(";");
10378                        for (int j = 0; j < names.length; j++) {
10379                            if (mProvidersByAuthority.containsKey(names[j])) {
10380                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10381                                final String otherPackageName =
10382                                        ((other != null && other.getComponentName() != null) ?
10383                                                other.getComponentName().getPackageName() : "?");
10384                                throw new PackageManagerException(
10385                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10386                                        "Can't install because provider name " + names[j]
10387                                                + " (in package " + pkg.applicationInfo.packageName
10388                                                + ") is already used by " + otherPackageName);
10389                            }
10390                        }
10391                    }
10392                }
10393            }
10394        }
10395    }
10396
10397    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10398            int type, String declaringPackageName, int declaringVersionCode) {
10399        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10400        if (versionedLib == null) {
10401            versionedLib = new SparseArray<>();
10402            mSharedLibraries.put(name, versionedLib);
10403            if (type == SharedLibraryInfo.TYPE_STATIC) {
10404                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10405            }
10406        } else if (versionedLib.indexOfKey(version) >= 0) {
10407            return false;
10408        }
10409        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10410                version, type, declaringPackageName, declaringVersionCode);
10411        versionedLib.put(version, libEntry);
10412        return true;
10413    }
10414
10415    private boolean removeSharedLibraryLPw(String name, int version) {
10416        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10417        if (versionedLib == null) {
10418            return false;
10419        }
10420        final int libIdx = versionedLib.indexOfKey(version);
10421        if (libIdx < 0) {
10422            return false;
10423        }
10424        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10425        versionedLib.remove(version);
10426        if (versionedLib.size() <= 0) {
10427            mSharedLibraries.remove(name);
10428            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10429                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10430                        .getPackageName());
10431            }
10432        }
10433        return true;
10434    }
10435
10436    /**
10437     * Adds a scanned package to the system. When this method is finished, the package will
10438     * be available for query, resolution, etc...
10439     */
10440    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10441            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10442        final String pkgName = pkg.packageName;
10443        if (mCustomResolverComponentName != null &&
10444                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10445            setUpCustomResolverActivity(pkg);
10446        }
10447
10448        if (pkg.packageName.equals("android")) {
10449            synchronized (mPackages) {
10450                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10451                    // Set up information for our fall-back user intent resolution activity.
10452                    mPlatformPackage = pkg;
10453                    pkg.mVersionCode = mSdkVersion;
10454                    mAndroidApplication = pkg.applicationInfo;
10455                    if (!mResolverReplaced) {
10456                        mResolveActivity.applicationInfo = mAndroidApplication;
10457                        mResolveActivity.name = ResolverActivity.class.getName();
10458                        mResolveActivity.packageName = mAndroidApplication.packageName;
10459                        mResolveActivity.processName = "system:ui";
10460                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10461                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10462                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10463                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10464                        mResolveActivity.exported = true;
10465                        mResolveActivity.enabled = true;
10466                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10467                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10468                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10469                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10470                                | ActivityInfo.CONFIG_ORIENTATION
10471                                | ActivityInfo.CONFIG_KEYBOARD
10472                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10473                        mResolveInfo.activityInfo = mResolveActivity;
10474                        mResolveInfo.priority = 0;
10475                        mResolveInfo.preferredOrder = 0;
10476                        mResolveInfo.match = 0;
10477                        mResolveComponentName = new ComponentName(
10478                                mAndroidApplication.packageName, mResolveActivity.name);
10479                    }
10480                }
10481            }
10482        }
10483
10484        ArrayList<PackageParser.Package> clientLibPkgs = null;
10485        // writer
10486        synchronized (mPackages) {
10487            boolean hasStaticSharedLibs = false;
10488
10489            // Any app can add new static shared libraries
10490            if (pkg.staticSharedLibName != null) {
10491                // Static shared libs don't allow renaming as they have synthetic package
10492                // names to allow install of multiple versions, so use name from manifest.
10493                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10494                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10495                        pkg.manifestPackageName, pkg.mVersionCode)) {
10496                    hasStaticSharedLibs = true;
10497                } else {
10498                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10499                                + pkg.staticSharedLibName + " already exists; skipping");
10500                }
10501                // Static shared libs cannot be updated once installed since they
10502                // use synthetic package name which includes the version code, so
10503                // not need to update other packages's shared lib dependencies.
10504            }
10505
10506            if (!hasStaticSharedLibs
10507                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10508                // Only system apps can add new dynamic shared libraries.
10509                if (pkg.libraryNames != null) {
10510                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10511                        String name = pkg.libraryNames.get(i);
10512                        boolean allowed = false;
10513                        if (pkg.isUpdatedSystemApp()) {
10514                            // New library entries can only be added through the
10515                            // system image.  This is important to get rid of a lot
10516                            // of nasty edge cases: for example if we allowed a non-
10517                            // system update of the app to add a library, then uninstalling
10518                            // the update would make the library go away, and assumptions
10519                            // we made such as through app install filtering would now
10520                            // have allowed apps on the device which aren't compatible
10521                            // with it.  Better to just have the restriction here, be
10522                            // conservative, and create many fewer cases that can negatively
10523                            // impact the user experience.
10524                            final PackageSetting sysPs = mSettings
10525                                    .getDisabledSystemPkgLPr(pkg.packageName);
10526                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10527                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10528                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10529                                        allowed = true;
10530                                        break;
10531                                    }
10532                                }
10533                            }
10534                        } else {
10535                            allowed = true;
10536                        }
10537                        if (allowed) {
10538                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10539                                    SharedLibraryInfo.VERSION_UNDEFINED,
10540                                    SharedLibraryInfo.TYPE_DYNAMIC,
10541                                    pkg.packageName, pkg.mVersionCode)) {
10542                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10543                                        + name + " already exists; skipping");
10544                            }
10545                        } else {
10546                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10547                                    + name + " that is not declared on system image; skipping");
10548                        }
10549                    }
10550
10551                    if ((scanFlags & SCAN_BOOTING) == 0) {
10552                        // If we are not booting, we need to update any applications
10553                        // that are clients of our shared library.  If we are booting,
10554                        // this will all be done once the scan is complete.
10555                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10556                    }
10557                }
10558            }
10559        }
10560
10561        if ((scanFlags & SCAN_BOOTING) != 0) {
10562            // No apps can run during boot scan, so they don't need to be frozen
10563        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10564            // Caller asked to not kill app, so it's probably not frozen
10565        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10566            // Caller asked us to ignore frozen check for some reason; they
10567            // probably didn't know the package name
10568        } else {
10569            // We're doing major surgery on this package, so it better be frozen
10570            // right now to keep it from launching
10571            checkPackageFrozen(pkgName);
10572        }
10573
10574        // Also need to kill any apps that are dependent on the library.
10575        if (clientLibPkgs != null) {
10576            for (int i=0; i<clientLibPkgs.size(); i++) {
10577                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10578                killApplication(clientPkg.applicationInfo.packageName,
10579                        clientPkg.applicationInfo.uid, "update lib");
10580            }
10581        }
10582
10583        // writer
10584        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10585
10586        synchronized (mPackages) {
10587            // We don't expect installation to fail beyond this point
10588
10589            // Add the new setting to mSettings
10590            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10591            // Add the new setting to mPackages
10592            mPackages.put(pkg.applicationInfo.packageName, pkg);
10593            // Make sure we don't accidentally delete its data.
10594            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10595            while (iter.hasNext()) {
10596                PackageCleanItem item = iter.next();
10597                if (pkgName.equals(item.packageName)) {
10598                    iter.remove();
10599                }
10600            }
10601
10602            // Add the package's KeySets to the global KeySetManagerService
10603            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10604            ksms.addScannedPackageLPw(pkg);
10605
10606            int N = pkg.providers.size();
10607            StringBuilder r = null;
10608            int i;
10609            for (i=0; i<N; i++) {
10610                PackageParser.Provider p = pkg.providers.get(i);
10611                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10612                        p.info.processName);
10613                mProviders.addProvider(p);
10614                p.syncable = p.info.isSyncable;
10615                if (p.info.authority != null) {
10616                    String names[] = p.info.authority.split(";");
10617                    p.info.authority = null;
10618                    for (int j = 0; j < names.length; j++) {
10619                        if (j == 1 && p.syncable) {
10620                            // We only want the first authority for a provider to possibly be
10621                            // syncable, so if we already added this provider using a different
10622                            // authority clear the syncable flag. We copy the provider before
10623                            // changing it because the mProviders object contains a reference
10624                            // to a provider that we don't want to change.
10625                            // Only do this for the second authority since the resulting provider
10626                            // object can be the same for all future authorities for this provider.
10627                            p = new PackageParser.Provider(p);
10628                            p.syncable = false;
10629                        }
10630                        if (!mProvidersByAuthority.containsKey(names[j])) {
10631                            mProvidersByAuthority.put(names[j], p);
10632                            if (p.info.authority == null) {
10633                                p.info.authority = names[j];
10634                            } else {
10635                                p.info.authority = p.info.authority + ";" + names[j];
10636                            }
10637                            if (DEBUG_PACKAGE_SCANNING) {
10638                                if (chatty)
10639                                    Log.d(TAG, "Registered content provider: " + names[j]
10640                                            + ", className = " + p.info.name + ", isSyncable = "
10641                                            + p.info.isSyncable);
10642                            }
10643                        } else {
10644                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10645                            Slog.w(TAG, "Skipping provider name " + names[j] +
10646                                    " (in package " + pkg.applicationInfo.packageName +
10647                                    "): name already used by "
10648                                    + ((other != null && other.getComponentName() != null)
10649                                            ? other.getComponentName().getPackageName() : "?"));
10650                        }
10651                    }
10652                }
10653                if (chatty) {
10654                    if (r == null) {
10655                        r = new StringBuilder(256);
10656                    } else {
10657                        r.append(' ');
10658                    }
10659                    r.append(p.info.name);
10660                }
10661            }
10662            if (r != null) {
10663                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10664            }
10665
10666            N = pkg.services.size();
10667            r = null;
10668            for (i=0; i<N; i++) {
10669                PackageParser.Service s = pkg.services.get(i);
10670                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10671                        s.info.processName);
10672                mServices.addService(s);
10673                if (chatty) {
10674                    if (r == null) {
10675                        r = new StringBuilder(256);
10676                    } else {
10677                        r.append(' ');
10678                    }
10679                    r.append(s.info.name);
10680                }
10681            }
10682            if (r != null) {
10683                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10684            }
10685
10686            N = pkg.receivers.size();
10687            r = null;
10688            for (i=0; i<N; i++) {
10689                PackageParser.Activity a = pkg.receivers.get(i);
10690                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10691                        a.info.processName);
10692                mReceivers.addActivity(a, "receiver");
10693                if (chatty) {
10694                    if (r == null) {
10695                        r = new StringBuilder(256);
10696                    } else {
10697                        r.append(' ');
10698                    }
10699                    r.append(a.info.name);
10700                }
10701            }
10702            if (r != null) {
10703                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10704            }
10705
10706            N = pkg.activities.size();
10707            r = null;
10708            for (i=0; i<N; i++) {
10709                PackageParser.Activity a = pkg.activities.get(i);
10710                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10711                        a.info.processName);
10712                mActivities.addActivity(a, "activity");
10713                if (chatty) {
10714                    if (r == null) {
10715                        r = new StringBuilder(256);
10716                    } else {
10717                        r.append(' ');
10718                    }
10719                    r.append(a.info.name);
10720                }
10721            }
10722            if (r != null) {
10723                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10724            }
10725
10726            N = pkg.permissionGroups.size();
10727            r = null;
10728            for (i=0; i<N; i++) {
10729                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
10730                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
10731                final String curPackageName = cur == null ? null : cur.info.packageName;
10732                // Dont allow ephemeral apps to define new permission groups.
10733                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10734                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10735                            + pg.info.packageName
10736                            + " ignored: instant apps cannot define new permission groups.");
10737                    continue;
10738                }
10739                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
10740                if (cur == null || isPackageUpdate) {
10741                    mPermissionGroups.put(pg.info.name, pg);
10742                    if (chatty) {
10743                        if (r == null) {
10744                            r = new StringBuilder(256);
10745                        } else {
10746                            r.append(' ');
10747                        }
10748                        if (isPackageUpdate) {
10749                            r.append("UPD:");
10750                        }
10751                        r.append(pg.info.name);
10752                    }
10753                } else {
10754                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
10755                            + pg.info.packageName + " ignored: original from "
10756                            + cur.info.packageName);
10757                    if (chatty) {
10758                        if (r == null) {
10759                            r = new StringBuilder(256);
10760                        } else {
10761                            r.append(' ');
10762                        }
10763                        r.append("DUP:");
10764                        r.append(pg.info.name);
10765                    }
10766                }
10767            }
10768            if (r != null) {
10769                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
10770            }
10771
10772            N = pkg.permissions.size();
10773            r = null;
10774            for (i=0; i<N; i++) {
10775                PackageParser.Permission p = pkg.permissions.get(i);
10776
10777                // Dont allow ephemeral apps to define new permissions.
10778                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10779                    Slog.w(TAG, "Permission " + p.info.name + " from package "
10780                            + p.info.packageName
10781                            + " ignored: instant apps cannot define new permissions.");
10782                    continue;
10783                }
10784
10785                // Assume by default that we did not install this permission into the system.
10786                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
10787
10788                // Now that permission groups have a special meaning, we ignore permission
10789                // groups for legacy apps to prevent unexpected behavior. In particular,
10790                // permissions for one app being granted to someone just because they happen
10791                // to be in a group defined by another app (before this had no implications).
10792                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
10793                    p.group = mPermissionGroups.get(p.info.group);
10794                    // Warn for a permission in an unknown group.
10795                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
10796                        Slog.i(TAG, "Permission " + p.info.name + " from package "
10797                                + p.info.packageName + " in an unknown group " + p.info.group);
10798                    }
10799                }
10800
10801                ArrayMap<String, BasePermission> permissionMap =
10802                        p.tree ? mSettings.mPermissionTrees
10803                                : mSettings.mPermissions;
10804                BasePermission bp = permissionMap.get(p.info.name);
10805
10806                // Allow system apps to redefine non-system permissions
10807                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
10808                    final boolean currentOwnerIsSystem = (bp.perm != null
10809                            && isSystemApp(bp.perm.owner));
10810                    if (isSystemApp(p.owner)) {
10811                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
10812                            // It's a built-in permission and no owner, take ownership now
10813                            bp.packageSetting = pkgSetting;
10814                            bp.perm = p;
10815                            bp.uid = pkg.applicationInfo.uid;
10816                            bp.sourcePackage = p.info.packageName;
10817                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10818                        } else if (!currentOwnerIsSystem) {
10819                            String msg = "New decl " + p.owner + " of permission  "
10820                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
10821                            reportSettingsProblem(Log.WARN, msg);
10822                            bp = null;
10823                        }
10824                    }
10825                }
10826
10827                if (bp == null) {
10828                    bp = new BasePermission(p.info.name, p.info.packageName,
10829                            BasePermission.TYPE_NORMAL);
10830                    permissionMap.put(p.info.name, bp);
10831                }
10832
10833                if (bp.perm == null) {
10834                    if (bp.sourcePackage == null
10835                            || bp.sourcePackage.equals(p.info.packageName)) {
10836                        BasePermission tree = findPermissionTreeLP(p.info.name);
10837                        if (tree == null
10838                                || tree.sourcePackage.equals(p.info.packageName)) {
10839                            bp.packageSetting = pkgSetting;
10840                            bp.perm = p;
10841                            bp.uid = pkg.applicationInfo.uid;
10842                            bp.sourcePackage = p.info.packageName;
10843                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
10844                            if (chatty) {
10845                                if (r == null) {
10846                                    r = new StringBuilder(256);
10847                                } else {
10848                                    r.append(' ');
10849                                }
10850                                r.append(p.info.name);
10851                            }
10852                        } else {
10853                            Slog.w(TAG, "Permission " + p.info.name + " from package "
10854                                    + p.info.packageName + " ignored: base tree "
10855                                    + tree.name + " is from package "
10856                                    + tree.sourcePackage);
10857                        }
10858                    } else {
10859                        Slog.w(TAG, "Permission " + p.info.name + " from package "
10860                                + p.info.packageName + " ignored: original from "
10861                                + bp.sourcePackage);
10862                    }
10863                } else if (chatty) {
10864                    if (r == null) {
10865                        r = new StringBuilder(256);
10866                    } else {
10867                        r.append(' ');
10868                    }
10869                    r.append("DUP:");
10870                    r.append(p.info.name);
10871                }
10872                if (bp.perm == p) {
10873                    bp.protectionLevel = p.info.protectionLevel;
10874                }
10875            }
10876
10877            if (r != null) {
10878                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
10879            }
10880
10881            N = pkg.instrumentation.size();
10882            r = null;
10883            for (i=0; i<N; i++) {
10884                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10885                a.info.packageName = pkg.applicationInfo.packageName;
10886                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10887                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10888                a.info.splitNames = pkg.splitNames;
10889                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10890                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10891                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10892                a.info.dataDir = pkg.applicationInfo.dataDir;
10893                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10894                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10895                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10896                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10897                mInstrumentation.put(a.getComponentName(), a);
10898                if (chatty) {
10899                    if (r == null) {
10900                        r = new StringBuilder(256);
10901                    } else {
10902                        r.append(' ');
10903                    }
10904                    r.append(a.info.name);
10905                }
10906            }
10907            if (r != null) {
10908                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10909            }
10910
10911            if (pkg.protectedBroadcasts != null) {
10912                N = pkg.protectedBroadcasts.size();
10913                for (i=0; i<N; i++) {
10914                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10915                }
10916            }
10917        }
10918
10919        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10920    }
10921
10922    /**
10923     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10924     * is derived purely on the basis of the contents of {@code scanFile} and
10925     * {@code cpuAbiOverride}.
10926     *
10927     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10928     */
10929    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
10930                                 String cpuAbiOverride, boolean extractLibs,
10931                                 File appLib32InstallDir)
10932            throws PackageManagerException {
10933        // Give ourselves some initial paths; we'll come back for another
10934        // pass once we've determined ABI below.
10935        setNativeLibraryPaths(pkg, appLib32InstallDir);
10936
10937        // We would never need to extract libs for forward-locked and external packages,
10938        // since the container service will do it for us. We shouldn't attempt to
10939        // extract libs from system app when it was not updated.
10940        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10941                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10942            extractLibs = false;
10943        }
10944
10945        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10946        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10947
10948        NativeLibraryHelper.Handle handle = null;
10949        try {
10950            handle = NativeLibraryHelper.Handle.create(pkg);
10951            // TODO(multiArch): This can be null for apps that didn't go through the
10952            // usual installation process. We can calculate it again, like we
10953            // do during install time.
10954            //
10955            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10956            // unnecessary.
10957            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10958
10959            // Null out the abis so that they can be recalculated.
10960            pkg.applicationInfo.primaryCpuAbi = null;
10961            pkg.applicationInfo.secondaryCpuAbi = null;
10962            if (isMultiArch(pkg.applicationInfo)) {
10963                // Warn if we've set an abiOverride for multi-lib packages..
10964                // By definition, we need to copy both 32 and 64 bit libraries for
10965                // such packages.
10966                if (pkg.cpuAbiOverride != null
10967                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10968                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10969                }
10970
10971                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10972                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10973                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10974                    if (extractLibs) {
10975                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10976                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10977                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10978                                useIsaSpecificSubdirs);
10979                    } else {
10980                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10981                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10982                    }
10983                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10984                }
10985
10986                maybeThrowExceptionForMultiArchCopy(
10987                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10988
10989                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10990                    if (extractLibs) {
10991                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10992                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10993                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10994                                useIsaSpecificSubdirs);
10995                    } else {
10996                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10997                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10998                    }
10999                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11000                }
11001
11002                maybeThrowExceptionForMultiArchCopy(
11003                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11004
11005                if (abi64 >= 0) {
11006                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11007                }
11008
11009                if (abi32 >= 0) {
11010                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11011                    if (abi64 >= 0) {
11012                        if (pkg.use32bitAbi) {
11013                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11014                            pkg.applicationInfo.primaryCpuAbi = abi;
11015                        } else {
11016                            pkg.applicationInfo.secondaryCpuAbi = abi;
11017                        }
11018                    } else {
11019                        pkg.applicationInfo.primaryCpuAbi = abi;
11020                    }
11021                }
11022
11023            } else {
11024                String[] abiList = (cpuAbiOverride != null) ?
11025                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11026
11027                // Enable gross and lame hacks for apps that are built with old
11028                // SDK tools. We must scan their APKs for renderscript bitcode and
11029                // not launch them if it's present. Don't bother checking on devices
11030                // that don't have 64 bit support.
11031                boolean needsRenderScriptOverride = false;
11032                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11033                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11034                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11035                    needsRenderScriptOverride = true;
11036                }
11037
11038                final int copyRet;
11039                if (extractLibs) {
11040                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11041                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11042                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11043                } else {
11044                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11045                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11046                }
11047                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11048
11049                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11050                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11051                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11052                }
11053
11054                if (copyRet >= 0) {
11055                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11056                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11057                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11058                } else if (needsRenderScriptOverride) {
11059                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11060                }
11061            }
11062        } catch (IOException ioe) {
11063            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11064        } finally {
11065            IoUtils.closeQuietly(handle);
11066        }
11067
11068        // Now that we've calculated the ABIs and determined if it's an internal app,
11069        // we will go ahead and populate the nativeLibraryPath.
11070        setNativeLibraryPaths(pkg, appLib32InstallDir);
11071    }
11072
11073    /**
11074     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11075     * i.e, so that all packages can be run inside a single process if required.
11076     *
11077     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11078     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11079     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11080     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11081     * updating a package that belongs to a shared user.
11082     *
11083     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11084     * adds unnecessary complexity.
11085     */
11086    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11087            PackageParser.Package scannedPackage) {
11088        String requiredInstructionSet = null;
11089        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11090            requiredInstructionSet = VMRuntime.getInstructionSet(
11091                     scannedPackage.applicationInfo.primaryCpuAbi);
11092        }
11093
11094        PackageSetting requirer = null;
11095        for (PackageSetting ps : packagesForUser) {
11096            // If packagesForUser contains scannedPackage, we skip it. This will happen
11097            // when scannedPackage is an update of an existing package. Without this check,
11098            // we will never be able to change the ABI of any package belonging to a shared
11099            // user, even if it's compatible with other packages.
11100            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11101                if (ps.primaryCpuAbiString == null) {
11102                    continue;
11103                }
11104
11105                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11106                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11107                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11108                    // this but there's not much we can do.
11109                    String errorMessage = "Instruction set mismatch, "
11110                            + ((requirer == null) ? "[caller]" : requirer)
11111                            + " requires " + requiredInstructionSet + " whereas " + ps
11112                            + " requires " + instructionSet;
11113                    Slog.w(TAG, errorMessage);
11114                }
11115
11116                if (requiredInstructionSet == null) {
11117                    requiredInstructionSet = instructionSet;
11118                    requirer = ps;
11119                }
11120            }
11121        }
11122
11123        if (requiredInstructionSet != null) {
11124            String adjustedAbi;
11125            if (requirer != null) {
11126                // requirer != null implies that either scannedPackage was null or that scannedPackage
11127                // did not require an ABI, in which case we have to adjust scannedPackage to match
11128                // the ABI of the set (which is the same as requirer's ABI)
11129                adjustedAbi = requirer.primaryCpuAbiString;
11130                if (scannedPackage != null) {
11131                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11132                }
11133            } else {
11134                // requirer == null implies that we're updating all ABIs in the set to
11135                // match scannedPackage.
11136                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11137            }
11138
11139            for (PackageSetting ps : packagesForUser) {
11140                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11141                    if (ps.primaryCpuAbiString != null) {
11142                        continue;
11143                    }
11144
11145                    ps.primaryCpuAbiString = adjustedAbi;
11146                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11147                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11148                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11149                        if (DEBUG_ABI_SELECTION) {
11150                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11151                                    + " (requirer="
11152                                    + (requirer != null ? requirer.pkg : "null")
11153                                    + ", scannedPackage="
11154                                    + (scannedPackage != null ? scannedPackage : "null")
11155                                    + ")");
11156                        }
11157                        try {
11158                            mInstaller.rmdex(ps.codePathString,
11159                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11160                        } catch (InstallerException ignored) {
11161                        }
11162                    }
11163                }
11164            }
11165        }
11166    }
11167
11168    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11169        synchronized (mPackages) {
11170            mResolverReplaced = true;
11171            // Set up information for custom user intent resolution activity.
11172            mResolveActivity.applicationInfo = pkg.applicationInfo;
11173            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11174            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11175            mResolveActivity.processName = pkg.applicationInfo.packageName;
11176            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11177            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11178                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11179            mResolveActivity.theme = 0;
11180            mResolveActivity.exported = true;
11181            mResolveActivity.enabled = true;
11182            mResolveInfo.activityInfo = mResolveActivity;
11183            mResolveInfo.priority = 0;
11184            mResolveInfo.preferredOrder = 0;
11185            mResolveInfo.match = 0;
11186            mResolveComponentName = mCustomResolverComponentName;
11187            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11188                    mResolveComponentName);
11189        }
11190    }
11191
11192    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11193        if (installerActivity == null) {
11194            if (DEBUG_EPHEMERAL) {
11195                Slog.d(TAG, "Clear ephemeral installer activity");
11196            }
11197            mInstantAppInstallerActivity = null;
11198            return;
11199        }
11200
11201        if (DEBUG_EPHEMERAL) {
11202            Slog.d(TAG, "Set ephemeral installer activity: "
11203                    + installerActivity.getComponentName());
11204        }
11205        // Set up information for ephemeral installer activity
11206        mInstantAppInstallerActivity = installerActivity;
11207        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11208                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11209        mInstantAppInstallerActivity.exported = true;
11210        mInstantAppInstallerActivity.enabled = true;
11211        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11212        mInstantAppInstallerInfo.priority = 0;
11213        mInstantAppInstallerInfo.preferredOrder = 1;
11214        mInstantAppInstallerInfo.isDefault = true;
11215        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11216                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11217    }
11218
11219    private static String calculateBundledApkRoot(final String codePathString) {
11220        final File codePath = new File(codePathString);
11221        final File codeRoot;
11222        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11223            codeRoot = Environment.getRootDirectory();
11224        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11225            codeRoot = Environment.getOemDirectory();
11226        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11227            codeRoot = Environment.getVendorDirectory();
11228        } else {
11229            // Unrecognized code path; take its top real segment as the apk root:
11230            // e.g. /something/app/blah.apk => /something
11231            try {
11232                File f = codePath.getCanonicalFile();
11233                File parent = f.getParentFile();    // non-null because codePath is a file
11234                File tmp;
11235                while ((tmp = parent.getParentFile()) != null) {
11236                    f = parent;
11237                    parent = tmp;
11238                }
11239                codeRoot = f;
11240                Slog.w(TAG, "Unrecognized code path "
11241                        + codePath + " - using " + codeRoot);
11242            } catch (IOException e) {
11243                // Can't canonicalize the code path -- shenanigans?
11244                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11245                return Environment.getRootDirectory().getPath();
11246            }
11247        }
11248        return codeRoot.getPath();
11249    }
11250
11251    /**
11252     * Derive and set the location of native libraries for the given package,
11253     * which varies depending on where and how the package was installed.
11254     */
11255    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11256        final ApplicationInfo info = pkg.applicationInfo;
11257        final String codePath = pkg.codePath;
11258        final File codeFile = new File(codePath);
11259        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11260        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11261
11262        info.nativeLibraryRootDir = null;
11263        info.nativeLibraryRootRequiresIsa = false;
11264        info.nativeLibraryDir = null;
11265        info.secondaryNativeLibraryDir = null;
11266
11267        if (isApkFile(codeFile)) {
11268            // Monolithic install
11269            if (bundledApp) {
11270                // If "/system/lib64/apkname" exists, assume that is the per-package
11271                // native library directory to use; otherwise use "/system/lib/apkname".
11272                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11273                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11274                        getPrimaryInstructionSet(info));
11275
11276                // This is a bundled system app so choose the path based on the ABI.
11277                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11278                // is just the default path.
11279                final String apkName = deriveCodePathName(codePath);
11280                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11281                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11282                        apkName).getAbsolutePath();
11283
11284                if (info.secondaryCpuAbi != null) {
11285                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11286                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11287                            secondaryLibDir, apkName).getAbsolutePath();
11288                }
11289            } else if (asecApp) {
11290                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11291                        .getAbsolutePath();
11292            } else {
11293                final String apkName = deriveCodePathName(codePath);
11294                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11295                        .getAbsolutePath();
11296            }
11297
11298            info.nativeLibraryRootRequiresIsa = false;
11299            info.nativeLibraryDir = info.nativeLibraryRootDir;
11300        } else {
11301            // Cluster install
11302            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11303            info.nativeLibraryRootRequiresIsa = true;
11304
11305            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11306                    getPrimaryInstructionSet(info)).getAbsolutePath();
11307
11308            if (info.secondaryCpuAbi != null) {
11309                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11310                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11311            }
11312        }
11313    }
11314
11315    /**
11316     * Calculate the abis and roots for a bundled app. These can uniquely
11317     * be determined from the contents of the system partition, i.e whether
11318     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11319     * of this information, and instead assume that the system was built
11320     * sensibly.
11321     */
11322    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11323                                           PackageSetting pkgSetting) {
11324        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11325
11326        // If "/system/lib64/apkname" exists, assume that is the per-package
11327        // native library directory to use; otherwise use "/system/lib/apkname".
11328        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11329        setBundledAppAbi(pkg, apkRoot, apkName);
11330        // pkgSetting might be null during rescan following uninstall of updates
11331        // to a bundled app, so accommodate that possibility.  The settings in
11332        // that case will be established later from the parsed package.
11333        //
11334        // If the settings aren't null, sync them up with what we've just derived.
11335        // note that apkRoot isn't stored in the package settings.
11336        if (pkgSetting != null) {
11337            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11338            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11339        }
11340    }
11341
11342    /**
11343     * Deduces the ABI of a bundled app and sets the relevant fields on the
11344     * parsed pkg object.
11345     *
11346     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11347     *        under which system libraries are installed.
11348     * @param apkName the name of the installed package.
11349     */
11350    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11351        final File codeFile = new File(pkg.codePath);
11352
11353        final boolean has64BitLibs;
11354        final boolean has32BitLibs;
11355        if (isApkFile(codeFile)) {
11356            // Monolithic install
11357            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11358            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11359        } else {
11360            // Cluster install
11361            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11362            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11363                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11364                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11365                has64BitLibs = (new File(rootDir, isa)).exists();
11366            } else {
11367                has64BitLibs = false;
11368            }
11369            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11370                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11371                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11372                has32BitLibs = (new File(rootDir, isa)).exists();
11373            } else {
11374                has32BitLibs = false;
11375            }
11376        }
11377
11378        if (has64BitLibs && !has32BitLibs) {
11379            // The package has 64 bit libs, but not 32 bit libs. Its primary
11380            // ABI should be 64 bit. We can safely assume here that the bundled
11381            // native libraries correspond to the most preferred ABI in the list.
11382
11383            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11384            pkg.applicationInfo.secondaryCpuAbi = null;
11385        } else if (has32BitLibs && !has64BitLibs) {
11386            // The package has 32 bit libs but not 64 bit libs. Its primary
11387            // ABI should be 32 bit.
11388
11389            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11390            pkg.applicationInfo.secondaryCpuAbi = null;
11391        } else if (has32BitLibs && has64BitLibs) {
11392            // The application has both 64 and 32 bit bundled libraries. We check
11393            // here that the app declares multiArch support, and warn if it doesn't.
11394            //
11395            // We will be lenient here and record both ABIs. The primary will be the
11396            // ABI that's higher on the list, i.e, a device that's configured to prefer
11397            // 64 bit apps will see a 64 bit primary ABI,
11398
11399            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11400                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11401            }
11402
11403            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11404                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11405                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11406            } else {
11407                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11408                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11409            }
11410        } else {
11411            pkg.applicationInfo.primaryCpuAbi = null;
11412            pkg.applicationInfo.secondaryCpuAbi = null;
11413        }
11414    }
11415
11416    private void killApplication(String pkgName, int appId, String reason) {
11417        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11418    }
11419
11420    private void killApplication(String pkgName, int appId, int userId, String reason) {
11421        // Request the ActivityManager to kill the process(only for existing packages)
11422        // so that we do not end up in a confused state while the user is still using the older
11423        // version of the application while the new one gets installed.
11424        final long token = Binder.clearCallingIdentity();
11425        try {
11426            IActivityManager am = ActivityManager.getService();
11427            if (am != null) {
11428                try {
11429                    am.killApplication(pkgName, appId, userId, reason);
11430                } catch (RemoteException e) {
11431                }
11432            }
11433        } finally {
11434            Binder.restoreCallingIdentity(token);
11435        }
11436    }
11437
11438    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11439        // Remove the parent package setting
11440        PackageSetting ps = (PackageSetting) pkg.mExtras;
11441        if (ps != null) {
11442            removePackageLI(ps, chatty);
11443        }
11444        // Remove the child package setting
11445        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11446        for (int i = 0; i < childCount; i++) {
11447            PackageParser.Package childPkg = pkg.childPackages.get(i);
11448            ps = (PackageSetting) childPkg.mExtras;
11449            if (ps != null) {
11450                removePackageLI(ps, chatty);
11451            }
11452        }
11453    }
11454
11455    void removePackageLI(PackageSetting ps, boolean chatty) {
11456        if (DEBUG_INSTALL) {
11457            if (chatty)
11458                Log.d(TAG, "Removing package " + ps.name);
11459        }
11460
11461        // writer
11462        synchronized (mPackages) {
11463            mPackages.remove(ps.name);
11464            final PackageParser.Package pkg = ps.pkg;
11465            if (pkg != null) {
11466                cleanPackageDataStructuresLILPw(pkg, chatty);
11467            }
11468        }
11469    }
11470
11471    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11472        if (DEBUG_INSTALL) {
11473            if (chatty)
11474                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11475        }
11476
11477        // writer
11478        synchronized (mPackages) {
11479            // Remove the parent package
11480            mPackages.remove(pkg.applicationInfo.packageName);
11481            cleanPackageDataStructuresLILPw(pkg, chatty);
11482
11483            // Remove the child packages
11484            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11485            for (int i = 0; i < childCount; i++) {
11486                PackageParser.Package childPkg = pkg.childPackages.get(i);
11487                mPackages.remove(childPkg.applicationInfo.packageName);
11488                cleanPackageDataStructuresLILPw(childPkg, chatty);
11489            }
11490        }
11491    }
11492
11493    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11494        int N = pkg.providers.size();
11495        StringBuilder r = null;
11496        int i;
11497        for (i=0; i<N; i++) {
11498            PackageParser.Provider p = pkg.providers.get(i);
11499            mProviders.removeProvider(p);
11500            if (p.info.authority == null) {
11501
11502                /* There was another ContentProvider with this authority when
11503                 * this app was installed so this authority is null,
11504                 * Ignore it as we don't have to unregister the provider.
11505                 */
11506                continue;
11507            }
11508            String names[] = p.info.authority.split(";");
11509            for (int j = 0; j < names.length; j++) {
11510                if (mProvidersByAuthority.get(names[j]) == p) {
11511                    mProvidersByAuthority.remove(names[j]);
11512                    if (DEBUG_REMOVE) {
11513                        if (chatty)
11514                            Log.d(TAG, "Unregistered content provider: " + names[j]
11515                                    + ", className = " + p.info.name + ", isSyncable = "
11516                                    + p.info.isSyncable);
11517                    }
11518                }
11519            }
11520            if (DEBUG_REMOVE && chatty) {
11521                if (r == null) {
11522                    r = new StringBuilder(256);
11523                } else {
11524                    r.append(' ');
11525                }
11526                r.append(p.info.name);
11527            }
11528        }
11529        if (r != null) {
11530            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11531        }
11532
11533        N = pkg.services.size();
11534        r = null;
11535        for (i=0; i<N; i++) {
11536            PackageParser.Service s = pkg.services.get(i);
11537            mServices.removeService(s);
11538            if (chatty) {
11539                if (r == null) {
11540                    r = new StringBuilder(256);
11541                } else {
11542                    r.append(' ');
11543                }
11544                r.append(s.info.name);
11545            }
11546        }
11547        if (r != null) {
11548            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11549        }
11550
11551        N = pkg.receivers.size();
11552        r = null;
11553        for (i=0; i<N; i++) {
11554            PackageParser.Activity a = pkg.receivers.get(i);
11555            mReceivers.removeActivity(a, "receiver");
11556            if (DEBUG_REMOVE && chatty) {
11557                if (r == null) {
11558                    r = new StringBuilder(256);
11559                } else {
11560                    r.append(' ');
11561                }
11562                r.append(a.info.name);
11563            }
11564        }
11565        if (r != null) {
11566            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11567        }
11568
11569        N = pkg.activities.size();
11570        r = null;
11571        for (i=0; i<N; i++) {
11572            PackageParser.Activity a = pkg.activities.get(i);
11573            mActivities.removeActivity(a, "activity");
11574            if (DEBUG_REMOVE && chatty) {
11575                if (r == null) {
11576                    r = new StringBuilder(256);
11577                } else {
11578                    r.append(' ');
11579                }
11580                r.append(a.info.name);
11581            }
11582        }
11583        if (r != null) {
11584            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11585        }
11586
11587        N = pkg.permissions.size();
11588        r = null;
11589        for (i=0; i<N; i++) {
11590            PackageParser.Permission p = pkg.permissions.get(i);
11591            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11592            if (bp == null) {
11593                bp = mSettings.mPermissionTrees.get(p.info.name);
11594            }
11595            if (bp != null && bp.perm == p) {
11596                bp.perm = null;
11597                if (DEBUG_REMOVE && chatty) {
11598                    if (r == null) {
11599                        r = new StringBuilder(256);
11600                    } else {
11601                        r.append(' ');
11602                    }
11603                    r.append(p.info.name);
11604                }
11605            }
11606            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11607                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11608                if (appOpPkgs != null) {
11609                    appOpPkgs.remove(pkg.packageName);
11610                }
11611            }
11612        }
11613        if (r != null) {
11614            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11615        }
11616
11617        N = pkg.requestedPermissions.size();
11618        r = null;
11619        for (i=0; i<N; i++) {
11620            String perm = pkg.requestedPermissions.get(i);
11621            BasePermission bp = mSettings.mPermissions.get(perm);
11622            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11623                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11624                if (appOpPkgs != null) {
11625                    appOpPkgs.remove(pkg.packageName);
11626                    if (appOpPkgs.isEmpty()) {
11627                        mAppOpPermissionPackages.remove(perm);
11628                    }
11629                }
11630            }
11631        }
11632        if (r != null) {
11633            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11634        }
11635
11636        N = pkg.instrumentation.size();
11637        r = null;
11638        for (i=0; i<N; i++) {
11639            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11640            mInstrumentation.remove(a.getComponentName());
11641            if (DEBUG_REMOVE && chatty) {
11642                if (r == null) {
11643                    r = new StringBuilder(256);
11644                } else {
11645                    r.append(' ');
11646                }
11647                r.append(a.info.name);
11648            }
11649        }
11650        if (r != null) {
11651            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11652        }
11653
11654        r = null;
11655        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11656            // Only system apps can hold shared libraries.
11657            if (pkg.libraryNames != null) {
11658                for (i = 0; i < pkg.libraryNames.size(); i++) {
11659                    String name = pkg.libraryNames.get(i);
11660                    if (removeSharedLibraryLPw(name, 0)) {
11661                        if (DEBUG_REMOVE && chatty) {
11662                            if (r == null) {
11663                                r = new StringBuilder(256);
11664                            } else {
11665                                r.append(' ');
11666                            }
11667                            r.append(name);
11668                        }
11669                    }
11670                }
11671            }
11672        }
11673
11674        r = null;
11675
11676        // Any package can hold static shared libraries.
11677        if (pkg.staticSharedLibName != null) {
11678            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11679                if (DEBUG_REMOVE && chatty) {
11680                    if (r == null) {
11681                        r = new StringBuilder(256);
11682                    } else {
11683                        r.append(' ');
11684                    }
11685                    r.append(pkg.staticSharedLibName);
11686                }
11687            }
11688        }
11689
11690        if (r != null) {
11691            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11692        }
11693    }
11694
11695    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
11696        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
11697            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
11698                return true;
11699            }
11700        }
11701        return false;
11702    }
11703
11704    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
11705    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
11706    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
11707
11708    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
11709        // Update the parent permissions
11710        updatePermissionsLPw(pkg.packageName, pkg, flags);
11711        // Update the child permissions
11712        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11713        for (int i = 0; i < childCount; i++) {
11714            PackageParser.Package childPkg = pkg.childPackages.get(i);
11715            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
11716        }
11717    }
11718
11719    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
11720            int flags) {
11721        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
11722        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
11723    }
11724
11725    private void updatePermissionsLPw(String changingPkg,
11726            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
11727        // Make sure there are no dangling permission trees.
11728        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
11729        while (it.hasNext()) {
11730            final BasePermission bp = it.next();
11731            if (bp.packageSetting == null) {
11732                // We may not yet have parsed the package, so just see if
11733                // we still know about its settings.
11734                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11735            }
11736            if (bp.packageSetting == null) {
11737                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
11738                        + " from package " + bp.sourcePackage);
11739                it.remove();
11740            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11741                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11742                    Slog.i(TAG, "Removing old permission tree: " + bp.name
11743                            + " from package " + bp.sourcePackage);
11744                    flags |= UPDATE_PERMISSIONS_ALL;
11745                    it.remove();
11746                }
11747            }
11748        }
11749
11750        // Make sure all dynamic permissions have been assigned to a package,
11751        // and make sure there are no dangling permissions.
11752        it = mSettings.mPermissions.values().iterator();
11753        while (it.hasNext()) {
11754            final BasePermission bp = it.next();
11755            if (bp.type == BasePermission.TYPE_DYNAMIC) {
11756                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
11757                        + bp.name + " pkg=" + bp.sourcePackage
11758                        + " info=" + bp.pendingInfo);
11759                if (bp.packageSetting == null && bp.pendingInfo != null) {
11760                    final BasePermission tree = findPermissionTreeLP(bp.name);
11761                    if (tree != null && tree.perm != null) {
11762                        bp.packageSetting = tree.packageSetting;
11763                        bp.perm = new PackageParser.Permission(tree.perm.owner,
11764                                new PermissionInfo(bp.pendingInfo));
11765                        bp.perm.info.packageName = tree.perm.info.packageName;
11766                        bp.perm.info.name = bp.name;
11767                        bp.uid = tree.uid;
11768                    }
11769                }
11770            }
11771            if (bp.packageSetting == null) {
11772                // We may not yet have parsed the package, so just see if
11773                // we still know about its settings.
11774                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
11775            }
11776            if (bp.packageSetting == null) {
11777                Slog.w(TAG, "Removing dangling permission: " + bp.name
11778                        + " from package " + bp.sourcePackage);
11779                it.remove();
11780            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
11781                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
11782                    Slog.i(TAG, "Removing old permission: " + bp.name
11783                            + " from package " + bp.sourcePackage);
11784                    flags |= UPDATE_PERMISSIONS_ALL;
11785                    it.remove();
11786                }
11787            }
11788        }
11789
11790        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
11791        // Now update the permissions for all packages, in particular
11792        // replace the granted permissions of the system packages.
11793        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
11794            for (PackageParser.Package pkg : mPackages.values()) {
11795                if (pkg != pkgInfo) {
11796                    // Only replace for packages on requested volume
11797                    final String volumeUuid = getVolumeUuidForPackage(pkg);
11798                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
11799                            && Objects.equals(replaceVolumeUuid, volumeUuid);
11800                    grantPermissionsLPw(pkg, replace, changingPkg);
11801                }
11802            }
11803        }
11804
11805        if (pkgInfo != null) {
11806            // Only replace for packages on requested volume
11807            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
11808            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
11809                    && Objects.equals(replaceVolumeUuid, volumeUuid);
11810            grantPermissionsLPw(pkgInfo, replace, changingPkg);
11811        }
11812        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11813    }
11814
11815    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
11816            String packageOfInterest) {
11817        // IMPORTANT: There are two types of permissions: install and runtime.
11818        // Install time permissions are granted when the app is installed to
11819        // all device users and users added in the future. Runtime permissions
11820        // are granted at runtime explicitly to specific users. Normal and signature
11821        // protected permissions are install time permissions. Dangerous permissions
11822        // are install permissions if the app's target SDK is Lollipop MR1 or older,
11823        // otherwise they are runtime permissions. This function does not manage
11824        // runtime permissions except for the case an app targeting Lollipop MR1
11825        // being upgraded to target a newer SDK, in which case dangerous permissions
11826        // are transformed from install time to runtime ones.
11827
11828        final PackageSetting ps = (PackageSetting) pkg.mExtras;
11829        if (ps == null) {
11830            return;
11831        }
11832
11833        PermissionsState permissionsState = ps.getPermissionsState();
11834        PermissionsState origPermissions = permissionsState;
11835
11836        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
11837
11838        boolean runtimePermissionsRevoked = false;
11839        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
11840
11841        boolean changedInstallPermission = false;
11842
11843        if (replace) {
11844            ps.installPermissionsFixed = false;
11845            if (!ps.isSharedUser()) {
11846                origPermissions = new PermissionsState(permissionsState);
11847                permissionsState.reset();
11848            } else {
11849                // We need to know only about runtime permission changes since the
11850                // calling code always writes the install permissions state but
11851                // the runtime ones are written only if changed. The only cases of
11852                // changed runtime permissions here are promotion of an install to
11853                // runtime and revocation of a runtime from a shared user.
11854                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
11855                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
11856                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
11857                    runtimePermissionsRevoked = true;
11858                }
11859            }
11860        }
11861
11862        permissionsState.setGlobalGids(mGlobalGids);
11863
11864        final int N = pkg.requestedPermissions.size();
11865        for (int i=0; i<N; i++) {
11866            final String name = pkg.requestedPermissions.get(i);
11867            final BasePermission bp = mSettings.mPermissions.get(name);
11868            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
11869                    >= Build.VERSION_CODES.M;
11870
11871            if (DEBUG_INSTALL) {
11872                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
11873            }
11874
11875            if (bp == null || bp.packageSetting == null) {
11876                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
11877                    if (DEBUG_PERMISSIONS) {
11878                        Slog.i(TAG, "Unknown permission " + name
11879                                + " in package " + pkg.packageName);
11880                    }
11881                }
11882                continue;
11883            }
11884
11885
11886            // Limit ephemeral apps to ephemeral allowed permissions.
11887            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
11888                if (DEBUG_PERMISSIONS) {
11889                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
11890                            + pkg.packageName);
11891                }
11892                continue;
11893            }
11894
11895            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
11896                if (DEBUG_PERMISSIONS) {
11897                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
11898                            + pkg.packageName);
11899                }
11900                continue;
11901            }
11902
11903            final String perm = bp.name;
11904            boolean allowedSig = false;
11905            int grant = GRANT_DENIED;
11906
11907            // Keep track of app op permissions.
11908            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11909                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
11910                if (pkgs == null) {
11911                    pkgs = new ArraySet<>();
11912                    mAppOpPermissionPackages.put(bp.name, pkgs);
11913                }
11914                pkgs.add(pkg.packageName);
11915            }
11916
11917            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
11918            switch (level) {
11919                case PermissionInfo.PROTECTION_NORMAL: {
11920                    // For all apps normal permissions are install time ones.
11921                    grant = GRANT_INSTALL;
11922                } break;
11923
11924                case PermissionInfo.PROTECTION_DANGEROUS: {
11925                    // If a permission review is required for legacy apps we represent
11926                    // their permissions as always granted runtime ones since we need
11927                    // to keep the review required permission flag per user while an
11928                    // install permission's state is shared across all users.
11929                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
11930                        // For legacy apps dangerous permissions are install time ones.
11931                        grant = GRANT_INSTALL;
11932                    } else if (origPermissions.hasInstallPermission(bp.name)) {
11933                        // For legacy apps that became modern, install becomes runtime.
11934                        grant = GRANT_UPGRADE;
11935                    } else if (mPromoteSystemApps
11936                            && isSystemApp(ps)
11937                            && mExistingSystemPackages.contains(ps.name)) {
11938                        // For legacy system apps, install becomes runtime.
11939                        // We cannot check hasInstallPermission() for system apps since those
11940                        // permissions were granted implicitly and not persisted pre-M.
11941                        grant = GRANT_UPGRADE;
11942                    } else {
11943                        // For modern apps keep runtime permissions unchanged.
11944                        grant = GRANT_RUNTIME;
11945                    }
11946                } break;
11947
11948                case PermissionInfo.PROTECTION_SIGNATURE: {
11949                    // For all apps signature permissions are install time ones.
11950                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
11951                    if (allowedSig) {
11952                        grant = GRANT_INSTALL;
11953                    }
11954                } break;
11955            }
11956
11957            if (DEBUG_PERMISSIONS) {
11958                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
11959            }
11960
11961            if (grant != GRANT_DENIED) {
11962                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
11963                    // If this is an existing, non-system package, then
11964                    // we can't add any new permissions to it.
11965                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
11966                        // Except...  if this is a permission that was added
11967                        // to the platform (note: need to only do this when
11968                        // updating the platform).
11969                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
11970                            grant = GRANT_DENIED;
11971                        }
11972                    }
11973                }
11974
11975                switch (grant) {
11976                    case GRANT_INSTALL: {
11977                        // Revoke this as runtime permission to handle the case of
11978                        // a runtime permission being downgraded to an install one.
11979                        // Also in permission review mode we keep dangerous permissions
11980                        // for legacy apps
11981                        for (int userId : UserManagerService.getInstance().getUserIds()) {
11982                            if (origPermissions.getRuntimePermissionState(
11983                                    bp.name, userId) != null) {
11984                                // Revoke the runtime permission and clear the flags.
11985                                origPermissions.revokeRuntimePermission(bp, userId);
11986                                origPermissions.updatePermissionFlags(bp, userId,
11987                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
11988                                // If we revoked a permission permission, we have to write.
11989                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
11990                                        changedRuntimePermissionUserIds, userId);
11991                            }
11992                        }
11993                        // Grant an install permission.
11994                        if (permissionsState.grantInstallPermission(bp) !=
11995                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
11996                            changedInstallPermission = true;
11997                        }
11998                    } break;
11999
12000                    case GRANT_RUNTIME: {
12001                        // Grant previously granted runtime permissions.
12002                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12003                            PermissionState permissionState = origPermissions
12004                                    .getRuntimePermissionState(bp.name, userId);
12005                            int flags = permissionState != null
12006                                    ? permissionState.getFlags() : 0;
12007                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12008                                // Don't propagate the permission in a permission review mode if
12009                                // the former was revoked, i.e. marked to not propagate on upgrade.
12010                                // Note that in a permission review mode install permissions are
12011                                // represented as constantly granted runtime ones since we need to
12012                                // keep a per user state associated with the permission. Also the
12013                                // revoke on upgrade flag is no longer applicable and is reset.
12014                                final boolean revokeOnUpgrade = (flags & PackageManager
12015                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12016                                if (revokeOnUpgrade) {
12017                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12018                                    // Since we changed the flags, we have to write.
12019                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12020                                            changedRuntimePermissionUserIds, userId);
12021                                }
12022                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12023                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12024                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12025                                        // If we cannot put the permission as it was,
12026                                        // we have to write.
12027                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12028                                                changedRuntimePermissionUserIds, userId);
12029                                    }
12030                                }
12031
12032                                // If the app supports runtime permissions no need for a review.
12033                                if (mPermissionReviewRequired
12034                                        && appSupportsRuntimePermissions
12035                                        && (flags & PackageManager
12036                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12037                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12038                                    // Since we changed the flags, we have to write.
12039                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12040                                            changedRuntimePermissionUserIds, userId);
12041                                }
12042                            } else if (mPermissionReviewRequired
12043                                    && !appSupportsRuntimePermissions) {
12044                                // For legacy apps that need a permission review, every new
12045                                // runtime permission is granted but it is pending a review.
12046                                // We also need to review only platform defined runtime
12047                                // permissions as these are the only ones the platform knows
12048                                // how to disable the API to simulate revocation as legacy
12049                                // apps don't expect to run with revoked permissions.
12050                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12051                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12052                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12053                                        // We changed the flags, hence have to write.
12054                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12055                                                changedRuntimePermissionUserIds, userId);
12056                                    }
12057                                }
12058                                if (permissionsState.grantRuntimePermission(bp, userId)
12059                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12060                                    // We changed the permission, hence have to write.
12061                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12062                                            changedRuntimePermissionUserIds, userId);
12063                                }
12064                            }
12065                            // Propagate the permission flags.
12066                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12067                        }
12068                    } break;
12069
12070                    case GRANT_UPGRADE: {
12071                        // Grant runtime permissions for a previously held install permission.
12072                        PermissionState permissionState = origPermissions
12073                                .getInstallPermissionState(bp.name);
12074                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12075
12076                        if (origPermissions.revokeInstallPermission(bp)
12077                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12078                            // We will be transferring the permission flags, so clear them.
12079                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12080                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12081                            changedInstallPermission = true;
12082                        }
12083
12084                        // If the permission is not to be promoted to runtime we ignore it and
12085                        // also its other flags as they are not applicable to install permissions.
12086                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12087                            for (int userId : currentUserIds) {
12088                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12089                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12090                                    // Transfer the permission flags.
12091                                    permissionsState.updatePermissionFlags(bp, userId,
12092                                            flags, flags);
12093                                    // If we granted the permission, we have to write.
12094                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12095                                            changedRuntimePermissionUserIds, userId);
12096                                }
12097                            }
12098                        }
12099                    } break;
12100
12101                    default: {
12102                        if (packageOfInterest == null
12103                                || packageOfInterest.equals(pkg.packageName)) {
12104                            if (DEBUG_PERMISSIONS) {
12105                                Slog.i(TAG, "Not granting permission " + perm
12106                                        + " to package " + pkg.packageName
12107                                        + " because it was previously installed without");
12108                            }
12109                        }
12110                    } break;
12111                }
12112            } else {
12113                if (permissionsState.revokeInstallPermission(bp) !=
12114                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12115                    // Also drop the permission flags.
12116                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12117                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12118                    changedInstallPermission = true;
12119                    Slog.i(TAG, "Un-granting permission " + perm
12120                            + " from package " + pkg.packageName
12121                            + " (protectionLevel=" + bp.protectionLevel
12122                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12123                            + ")");
12124                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12125                    // Don't print warning for app op permissions, since it is fine for them
12126                    // not to be granted, there is a UI for the user to decide.
12127                    if (DEBUG_PERMISSIONS
12128                            && (packageOfInterest == null
12129                                    || packageOfInterest.equals(pkg.packageName))) {
12130                        Slog.i(TAG, "Not granting permission " + perm
12131                                + " to package " + pkg.packageName
12132                                + " (protectionLevel=" + bp.protectionLevel
12133                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12134                                + ")");
12135                    }
12136                }
12137            }
12138        }
12139
12140        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12141                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12142            // This is the first that we have heard about this package, so the
12143            // permissions we have now selected are fixed until explicitly
12144            // changed.
12145            ps.installPermissionsFixed = true;
12146        }
12147
12148        // Persist the runtime permissions state for users with changes. If permissions
12149        // were revoked because no app in the shared user declares them we have to
12150        // write synchronously to avoid losing runtime permissions state.
12151        for (int userId : changedRuntimePermissionUserIds) {
12152            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
12153        }
12154    }
12155
12156    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
12157        boolean allowed = false;
12158        final int NP = PackageParser.NEW_PERMISSIONS.length;
12159        for (int ip=0; ip<NP; ip++) {
12160            final PackageParser.NewPermissionInfo npi
12161                    = PackageParser.NEW_PERMISSIONS[ip];
12162            if (npi.name.equals(perm)
12163                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
12164                allowed = true;
12165                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
12166                        + pkg.packageName);
12167                break;
12168            }
12169        }
12170        return allowed;
12171    }
12172
12173    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
12174            BasePermission bp, PermissionsState origPermissions) {
12175        boolean privilegedPermission = (bp.protectionLevel
12176                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
12177        boolean privappPermissionsDisable =
12178                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
12179        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
12180        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
12181        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
12182                && !platformPackage && platformPermission) {
12183            ArraySet<String> wlPermissions = SystemConfig.getInstance()
12184                    .getPrivAppPermissions(pkg.packageName);
12185            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
12186            if (!whitelisted) {
12187                Slog.w(TAG, "Privileged permission " + perm + " for package "
12188                        + pkg.packageName + " - not in privapp-permissions whitelist");
12189                // Only report violations for apps on system image
12190                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
12191                    if (mPrivappPermissionsViolations == null) {
12192                        mPrivappPermissionsViolations = new ArraySet<>();
12193                    }
12194                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
12195                }
12196                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
12197                    return false;
12198                }
12199            }
12200        }
12201        boolean allowed = (compareSignatures(
12202                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
12203                        == PackageManager.SIGNATURE_MATCH)
12204                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
12205                        == PackageManager.SIGNATURE_MATCH);
12206        if (!allowed && privilegedPermission) {
12207            if (isSystemApp(pkg)) {
12208                // For updated system applications, a system permission
12209                // is granted only if it had been defined by the original application.
12210                if (pkg.isUpdatedSystemApp()) {
12211                    final PackageSetting sysPs = mSettings
12212                            .getDisabledSystemPkgLPr(pkg.packageName);
12213                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
12214                        // If the original was granted this permission, we take
12215                        // that grant decision as read and propagate it to the
12216                        // update.
12217                        if (sysPs.isPrivileged()) {
12218                            allowed = true;
12219                        }
12220                    } else {
12221                        // The system apk may have been updated with an older
12222                        // version of the one on the data partition, but which
12223                        // granted a new system permission that it didn't have
12224                        // before.  In this case we do want to allow the app to
12225                        // now get the new permission if the ancestral apk is
12226                        // privileged to get it.
12227                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
12228                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
12229                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
12230                                    allowed = true;
12231                                    break;
12232                                }
12233                            }
12234                        }
12235                        // Also if a privileged parent package on the system image or any of
12236                        // its children requested a privileged permission, the updated child
12237                        // packages can also get the permission.
12238                        if (pkg.parentPackage != null) {
12239                            final PackageSetting disabledSysParentPs = mSettings
12240                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
12241                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
12242                                    && disabledSysParentPs.isPrivileged()) {
12243                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
12244                                    allowed = true;
12245                                } else if (disabledSysParentPs.pkg.childPackages != null) {
12246                                    final int count = disabledSysParentPs.pkg.childPackages.size();
12247                                    for (int i = 0; i < count; i++) {
12248                                        PackageParser.Package disabledSysChildPkg =
12249                                                disabledSysParentPs.pkg.childPackages.get(i);
12250                                        if (isPackageRequestingPermission(disabledSysChildPkg,
12251                                                perm)) {
12252                                            allowed = true;
12253                                            break;
12254                                        }
12255                                    }
12256                                }
12257                            }
12258                        }
12259                    }
12260                } else {
12261                    allowed = isPrivilegedApp(pkg);
12262                }
12263            }
12264        }
12265        if (!allowed) {
12266            if (!allowed && (bp.protectionLevel
12267                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
12268                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
12269                // If this was a previously normal/dangerous permission that got moved
12270                // to a system permission as part of the runtime permission redesign, then
12271                // we still want to blindly grant it to old apps.
12272                allowed = true;
12273            }
12274            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
12275                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
12276                // If this permission is to be granted to the system installer and
12277                // this app is an installer, then it gets the permission.
12278                allowed = true;
12279            }
12280            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
12281                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
12282                // If this permission is to be granted to the system verifier and
12283                // this app is a verifier, then it gets the permission.
12284                allowed = true;
12285            }
12286            if (!allowed && (bp.protectionLevel
12287                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
12288                    && isSystemApp(pkg)) {
12289                // Any pre-installed system app is allowed to get this permission.
12290                allowed = true;
12291            }
12292            if (!allowed && (bp.protectionLevel
12293                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
12294                // For development permissions, a development permission
12295                // is granted only if it was already granted.
12296                allowed = origPermissions.hasInstallPermission(perm);
12297            }
12298            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
12299                    && pkg.packageName.equals(mSetupWizardPackage)) {
12300                // If this permission is to be granted to the system setup wizard and
12301                // this app is a setup wizard, then it gets the permission.
12302                allowed = true;
12303            }
12304        }
12305        return allowed;
12306    }
12307
12308    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
12309        final int permCount = pkg.requestedPermissions.size();
12310        for (int j = 0; j < permCount; j++) {
12311            String requestedPermission = pkg.requestedPermissions.get(j);
12312            if (permission.equals(requestedPermission)) {
12313                return true;
12314            }
12315        }
12316        return false;
12317    }
12318
12319    final class ActivityIntentResolver
12320            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12321        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12322                boolean defaultOnly, int userId) {
12323            if (!sUserManager.exists(userId)) return null;
12324            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12325            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12326        }
12327
12328        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12329                int userId) {
12330            if (!sUserManager.exists(userId)) return null;
12331            mFlags = flags;
12332            return super.queryIntent(intent, resolvedType,
12333                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12334                    userId);
12335        }
12336
12337        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12338                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12339            if (!sUserManager.exists(userId)) return null;
12340            if (packageActivities == null) {
12341                return null;
12342            }
12343            mFlags = flags;
12344            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12345            final int N = packageActivities.size();
12346            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12347                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12348
12349            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12350            for (int i = 0; i < N; ++i) {
12351                intentFilters = packageActivities.get(i).intents;
12352                if (intentFilters != null && intentFilters.size() > 0) {
12353                    PackageParser.ActivityIntentInfo[] array =
12354                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12355                    intentFilters.toArray(array);
12356                    listCut.add(array);
12357                }
12358            }
12359            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12360        }
12361
12362        /**
12363         * Finds a privileged activity that matches the specified activity names.
12364         */
12365        private PackageParser.Activity findMatchingActivity(
12366                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12367            for (PackageParser.Activity sysActivity : activityList) {
12368                if (sysActivity.info.name.equals(activityInfo.name)) {
12369                    return sysActivity;
12370                }
12371                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12372                    return sysActivity;
12373                }
12374                if (sysActivity.info.targetActivity != null) {
12375                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12376                        return sysActivity;
12377                    }
12378                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12379                        return sysActivity;
12380                    }
12381                }
12382            }
12383            return null;
12384        }
12385
12386        public class IterGenerator<E> {
12387            public Iterator<E> generate(ActivityIntentInfo info) {
12388                return null;
12389            }
12390        }
12391
12392        public class ActionIterGenerator extends IterGenerator<String> {
12393            @Override
12394            public Iterator<String> generate(ActivityIntentInfo info) {
12395                return info.actionsIterator();
12396            }
12397        }
12398
12399        public class CategoriesIterGenerator extends IterGenerator<String> {
12400            @Override
12401            public Iterator<String> generate(ActivityIntentInfo info) {
12402                return info.categoriesIterator();
12403            }
12404        }
12405
12406        public class SchemesIterGenerator extends IterGenerator<String> {
12407            @Override
12408            public Iterator<String> generate(ActivityIntentInfo info) {
12409                return info.schemesIterator();
12410            }
12411        }
12412
12413        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12414            @Override
12415            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12416                return info.authoritiesIterator();
12417            }
12418        }
12419
12420        /**
12421         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12422         * MODIFIED. Do not pass in a list that should not be changed.
12423         */
12424        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12425                IterGenerator<T> generator, Iterator<T> searchIterator) {
12426            // loop through the set of actions; every one must be found in the intent filter
12427            while (searchIterator.hasNext()) {
12428                // we must have at least one filter in the list to consider a match
12429                if (intentList.size() == 0) {
12430                    break;
12431                }
12432
12433                final T searchAction = searchIterator.next();
12434
12435                // loop through the set of intent filters
12436                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12437                while (intentIter.hasNext()) {
12438                    final ActivityIntentInfo intentInfo = intentIter.next();
12439                    boolean selectionFound = false;
12440
12441                    // loop through the intent filter's selection criteria; at least one
12442                    // of them must match the searched criteria
12443                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12444                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12445                        final T intentSelection = intentSelectionIter.next();
12446                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12447                            selectionFound = true;
12448                            break;
12449                        }
12450                    }
12451
12452                    // the selection criteria wasn't found in this filter's set; this filter
12453                    // is not a potential match
12454                    if (!selectionFound) {
12455                        intentIter.remove();
12456                    }
12457                }
12458            }
12459        }
12460
12461        private boolean isProtectedAction(ActivityIntentInfo filter) {
12462            final Iterator<String> actionsIter = filter.actionsIterator();
12463            while (actionsIter != null && actionsIter.hasNext()) {
12464                final String filterAction = actionsIter.next();
12465                if (PROTECTED_ACTIONS.contains(filterAction)) {
12466                    return true;
12467                }
12468            }
12469            return false;
12470        }
12471
12472        /**
12473         * Adjusts the priority of the given intent filter according to policy.
12474         * <p>
12475         * <ul>
12476         * <li>The priority for non privileged applications is capped to '0'</li>
12477         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12478         * <li>The priority for unbundled updates to privileged applications is capped to the
12479         *      priority defined on the system partition</li>
12480         * </ul>
12481         * <p>
12482         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12483         * allowed to obtain any priority on any action.
12484         */
12485        private void adjustPriority(
12486                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12487            // nothing to do; priority is fine as-is
12488            if (intent.getPriority() <= 0) {
12489                return;
12490            }
12491
12492            final ActivityInfo activityInfo = intent.activity.info;
12493            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12494
12495            final boolean privilegedApp =
12496                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12497            if (!privilegedApp) {
12498                // non-privileged applications can never define a priority >0
12499                if (DEBUG_FILTERS) {
12500                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12501                            + " package: " + applicationInfo.packageName
12502                            + " activity: " + intent.activity.className
12503                            + " origPrio: " + intent.getPriority());
12504                }
12505                intent.setPriority(0);
12506                return;
12507            }
12508
12509            if (systemActivities == null) {
12510                // the system package is not disabled; we're parsing the system partition
12511                if (isProtectedAction(intent)) {
12512                    if (mDeferProtectedFilters) {
12513                        // We can't deal with these just yet. No component should ever obtain a
12514                        // >0 priority for a protected actions, with ONE exception -- the setup
12515                        // wizard. The setup wizard, however, cannot be known until we're able to
12516                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12517                        // until all intent filters have been processed. Chicken, meet egg.
12518                        // Let the filter temporarily have a high priority and rectify the
12519                        // priorities after all system packages have been scanned.
12520                        mProtectedFilters.add(intent);
12521                        if (DEBUG_FILTERS) {
12522                            Slog.i(TAG, "Protected action; save for later;"
12523                                    + " package: " + applicationInfo.packageName
12524                                    + " activity: " + intent.activity.className
12525                                    + " origPrio: " + intent.getPriority());
12526                        }
12527                        return;
12528                    } else {
12529                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12530                            Slog.i(TAG, "No setup wizard;"
12531                                + " All protected intents capped to priority 0");
12532                        }
12533                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12534                            if (DEBUG_FILTERS) {
12535                                Slog.i(TAG, "Found setup wizard;"
12536                                    + " allow priority " + intent.getPriority() + ";"
12537                                    + " package: " + intent.activity.info.packageName
12538                                    + " activity: " + intent.activity.className
12539                                    + " priority: " + intent.getPriority());
12540                            }
12541                            // setup wizard gets whatever it wants
12542                            return;
12543                        }
12544                        if (DEBUG_FILTERS) {
12545                            Slog.i(TAG, "Protected action; cap priority to 0;"
12546                                    + " package: " + intent.activity.info.packageName
12547                                    + " activity: " + intent.activity.className
12548                                    + " origPrio: " + intent.getPriority());
12549                        }
12550                        intent.setPriority(0);
12551                        return;
12552                    }
12553                }
12554                // privileged apps on the system image get whatever priority they request
12555                return;
12556            }
12557
12558            // privileged app unbundled update ... try to find the same activity
12559            final PackageParser.Activity foundActivity =
12560                    findMatchingActivity(systemActivities, activityInfo);
12561            if (foundActivity == null) {
12562                // this is a new activity; it cannot obtain >0 priority
12563                if (DEBUG_FILTERS) {
12564                    Slog.i(TAG, "New activity; cap priority to 0;"
12565                            + " package: " + applicationInfo.packageName
12566                            + " activity: " + intent.activity.className
12567                            + " origPrio: " + intent.getPriority());
12568                }
12569                intent.setPriority(0);
12570                return;
12571            }
12572
12573            // found activity, now check for filter equivalence
12574
12575            // a shallow copy is enough; we modify the list, not its contents
12576            final List<ActivityIntentInfo> intentListCopy =
12577                    new ArrayList<>(foundActivity.intents);
12578            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12579
12580            // find matching action subsets
12581            final Iterator<String> actionsIterator = intent.actionsIterator();
12582            if (actionsIterator != null) {
12583                getIntentListSubset(
12584                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12585                if (intentListCopy.size() == 0) {
12586                    // no more intents to match; we're not equivalent
12587                    if (DEBUG_FILTERS) {
12588                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12589                                + " package: " + applicationInfo.packageName
12590                                + " activity: " + intent.activity.className
12591                                + " origPrio: " + intent.getPriority());
12592                    }
12593                    intent.setPriority(0);
12594                    return;
12595                }
12596            }
12597
12598            // find matching category subsets
12599            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12600            if (categoriesIterator != null) {
12601                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12602                        categoriesIterator);
12603                if (intentListCopy.size() == 0) {
12604                    // no more intents to match; we're not equivalent
12605                    if (DEBUG_FILTERS) {
12606                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12607                                + " package: " + applicationInfo.packageName
12608                                + " activity: " + intent.activity.className
12609                                + " origPrio: " + intent.getPriority());
12610                    }
12611                    intent.setPriority(0);
12612                    return;
12613                }
12614            }
12615
12616            // find matching schemes subsets
12617            final Iterator<String> schemesIterator = intent.schemesIterator();
12618            if (schemesIterator != null) {
12619                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12620                        schemesIterator);
12621                if (intentListCopy.size() == 0) {
12622                    // no more intents to match; we're not equivalent
12623                    if (DEBUG_FILTERS) {
12624                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12625                                + " package: " + applicationInfo.packageName
12626                                + " activity: " + intent.activity.className
12627                                + " origPrio: " + intent.getPriority());
12628                    }
12629                    intent.setPriority(0);
12630                    return;
12631                }
12632            }
12633
12634            // find matching authorities subsets
12635            final Iterator<IntentFilter.AuthorityEntry>
12636                    authoritiesIterator = intent.authoritiesIterator();
12637            if (authoritiesIterator != null) {
12638                getIntentListSubset(intentListCopy,
12639                        new AuthoritiesIterGenerator(),
12640                        authoritiesIterator);
12641                if (intentListCopy.size() == 0) {
12642                    // no more intents to match; we're not equivalent
12643                    if (DEBUG_FILTERS) {
12644                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12645                                + " package: " + applicationInfo.packageName
12646                                + " activity: " + intent.activity.className
12647                                + " origPrio: " + intent.getPriority());
12648                    }
12649                    intent.setPriority(0);
12650                    return;
12651                }
12652            }
12653
12654            // we found matching filter(s); app gets the max priority of all intents
12655            int cappedPriority = 0;
12656            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12657                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12658            }
12659            if (intent.getPriority() > cappedPriority) {
12660                if (DEBUG_FILTERS) {
12661                    Slog.i(TAG, "Found matching filter(s);"
12662                            + " cap priority to " + cappedPriority + ";"
12663                            + " package: " + applicationInfo.packageName
12664                            + " activity: " + intent.activity.className
12665                            + " origPrio: " + intent.getPriority());
12666                }
12667                intent.setPriority(cappedPriority);
12668                return;
12669            }
12670            // all this for nothing; the requested priority was <= what was on the system
12671        }
12672
12673        public final void addActivity(PackageParser.Activity a, String type) {
12674            mActivities.put(a.getComponentName(), a);
12675            if (DEBUG_SHOW_INFO)
12676                Log.v(
12677                TAG, "  " + type + " " +
12678                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12679            if (DEBUG_SHOW_INFO)
12680                Log.v(TAG, "    Class=" + a.info.name);
12681            final int NI = a.intents.size();
12682            for (int j=0; j<NI; j++) {
12683                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12684                if ("activity".equals(type)) {
12685                    final PackageSetting ps =
12686                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12687                    final List<PackageParser.Activity> systemActivities =
12688                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12689                    adjustPriority(systemActivities, intent);
12690                }
12691                if (DEBUG_SHOW_INFO) {
12692                    Log.v(TAG, "    IntentFilter:");
12693                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12694                }
12695                if (!intent.debugCheck()) {
12696                    Log.w(TAG, "==> For Activity " + a.info.name);
12697                }
12698                addFilter(intent);
12699            }
12700        }
12701
12702        public final void removeActivity(PackageParser.Activity a, String type) {
12703            mActivities.remove(a.getComponentName());
12704            if (DEBUG_SHOW_INFO) {
12705                Log.v(TAG, "  " + type + " "
12706                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12707                                : a.info.name) + ":");
12708                Log.v(TAG, "    Class=" + a.info.name);
12709            }
12710            final int NI = a.intents.size();
12711            for (int j=0; j<NI; j++) {
12712                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12713                if (DEBUG_SHOW_INFO) {
12714                    Log.v(TAG, "    IntentFilter:");
12715                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12716                }
12717                removeFilter(intent);
12718            }
12719        }
12720
12721        @Override
12722        protected boolean allowFilterResult(
12723                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12724            ActivityInfo filterAi = filter.activity.info;
12725            for (int i=dest.size()-1; i>=0; i--) {
12726                ActivityInfo destAi = dest.get(i).activityInfo;
12727                if (destAi.name == filterAi.name
12728                        && destAi.packageName == filterAi.packageName) {
12729                    return false;
12730                }
12731            }
12732            return true;
12733        }
12734
12735        @Override
12736        protected ActivityIntentInfo[] newArray(int size) {
12737            return new ActivityIntentInfo[size];
12738        }
12739
12740        @Override
12741        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12742            if (!sUserManager.exists(userId)) return true;
12743            PackageParser.Package p = filter.activity.owner;
12744            if (p != null) {
12745                PackageSetting ps = (PackageSetting)p.mExtras;
12746                if (ps != null) {
12747                    // System apps are never considered stopped for purposes of
12748                    // filtering, because there may be no way for the user to
12749                    // actually re-launch them.
12750                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12751                            && ps.getStopped(userId);
12752                }
12753            }
12754            return false;
12755        }
12756
12757        @Override
12758        protected boolean isPackageForFilter(String packageName,
12759                PackageParser.ActivityIntentInfo info) {
12760            return packageName.equals(info.activity.owner.packageName);
12761        }
12762
12763        @Override
12764        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12765                int match, int userId) {
12766            if (!sUserManager.exists(userId)) return null;
12767            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12768                return null;
12769            }
12770            final PackageParser.Activity activity = info.activity;
12771            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12772            if (ps == null) {
12773                return null;
12774            }
12775            final PackageUserState userState = ps.readUserState(userId);
12776            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
12777            if (ai == null) {
12778                return null;
12779            }
12780            final boolean matchExplicitlyVisibleOnly =
12781                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12782            final boolean matchVisibleToInstantApp =
12783                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12784            final boolean componentVisible =
12785                    matchVisibleToInstantApp
12786                    && info.isVisibleToInstantApp()
12787                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12788            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12789            // throw out filters that aren't visible to ephemeral apps
12790            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12791                return null;
12792            }
12793            // throw out instant app filters if we're not explicitly requesting them
12794            if (!matchInstantApp && userState.instantApp) {
12795                return null;
12796            }
12797            // throw out instant app filters if updates are available; will trigger
12798            // instant app resolution
12799            if (userState.instantApp && ps.isUpdateAvailable()) {
12800                return null;
12801            }
12802            final ResolveInfo res = new ResolveInfo();
12803            res.activityInfo = ai;
12804            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12805                res.filter = info;
12806            }
12807            if (info != null) {
12808                res.handleAllWebDataURI = info.handleAllWebDataURI();
12809            }
12810            res.priority = info.getPriority();
12811            res.preferredOrder = activity.owner.mPreferredOrder;
12812            //System.out.println("Result: " + res.activityInfo.className +
12813            //                   " = " + res.priority);
12814            res.match = match;
12815            res.isDefault = info.hasDefault;
12816            res.labelRes = info.labelRes;
12817            res.nonLocalizedLabel = info.nonLocalizedLabel;
12818            if (userNeedsBadging(userId)) {
12819                res.noResourceId = true;
12820            } else {
12821                res.icon = info.icon;
12822            }
12823            res.iconResourceId = info.icon;
12824            res.system = res.activityInfo.applicationInfo.isSystemApp();
12825            res.isInstantAppAvailable = userState.instantApp;
12826            return res;
12827        }
12828
12829        @Override
12830        protected void sortResults(List<ResolveInfo> results) {
12831            Collections.sort(results, mResolvePrioritySorter);
12832        }
12833
12834        @Override
12835        protected void dumpFilter(PrintWriter out, String prefix,
12836                PackageParser.ActivityIntentInfo filter) {
12837            out.print(prefix); out.print(
12838                    Integer.toHexString(System.identityHashCode(filter.activity)));
12839                    out.print(' ');
12840                    filter.activity.printComponentShortName(out);
12841                    out.print(" filter ");
12842                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12843        }
12844
12845        @Override
12846        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12847            return filter.activity;
12848        }
12849
12850        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12851            PackageParser.Activity activity = (PackageParser.Activity)label;
12852            out.print(prefix); out.print(
12853                    Integer.toHexString(System.identityHashCode(activity)));
12854                    out.print(' ');
12855                    activity.printComponentShortName(out);
12856            if (count > 1) {
12857                out.print(" ("); out.print(count); out.print(" filters)");
12858            }
12859            out.println();
12860        }
12861
12862        // Keys are String (activity class name), values are Activity.
12863        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12864                = new ArrayMap<ComponentName, PackageParser.Activity>();
12865        private int mFlags;
12866    }
12867
12868    private final class ServiceIntentResolver
12869            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12870        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12871                boolean defaultOnly, int userId) {
12872            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12873            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12874        }
12875
12876        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12877                int userId) {
12878            if (!sUserManager.exists(userId)) return null;
12879            mFlags = flags;
12880            return super.queryIntent(intent, resolvedType,
12881                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12882                    userId);
12883        }
12884
12885        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12886                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12887            if (!sUserManager.exists(userId)) return null;
12888            if (packageServices == null) {
12889                return null;
12890            }
12891            mFlags = flags;
12892            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12893            final int N = packageServices.size();
12894            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12895                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12896
12897            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12898            for (int i = 0; i < N; ++i) {
12899                intentFilters = packageServices.get(i).intents;
12900                if (intentFilters != null && intentFilters.size() > 0) {
12901                    PackageParser.ServiceIntentInfo[] array =
12902                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12903                    intentFilters.toArray(array);
12904                    listCut.add(array);
12905                }
12906            }
12907            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12908        }
12909
12910        public final void addService(PackageParser.Service s) {
12911            mServices.put(s.getComponentName(), s);
12912            if (DEBUG_SHOW_INFO) {
12913                Log.v(TAG, "  "
12914                        + (s.info.nonLocalizedLabel != null
12915                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12916                Log.v(TAG, "    Class=" + s.info.name);
12917            }
12918            final int NI = s.intents.size();
12919            int j;
12920            for (j=0; j<NI; j++) {
12921                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12922                if (DEBUG_SHOW_INFO) {
12923                    Log.v(TAG, "    IntentFilter:");
12924                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12925                }
12926                if (!intent.debugCheck()) {
12927                    Log.w(TAG, "==> For Service " + s.info.name);
12928                }
12929                addFilter(intent);
12930            }
12931        }
12932
12933        public final void removeService(PackageParser.Service s) {
12934            mServices.remove(s.getComponentName());
12935            if (DEBUG_SHOW_INFO) {
12936                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12937                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12938                Log.v(TAG, "    Class=" + s.info.name);
12939            }
12940            final int NI = s.intents.size();
12941            int j;
12942            for (j=0; j<NI; j++) {
12943                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12944                if (DEBUG_SHOW_INFO) {
12945                    Log.v(TAG, "    IntentFilter:");
12946                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12947                }
12948                removeFilter(intent);
12949            }
12950        }
12951
12952        @Override
12953        protected boolean allowFilterResult(
12954                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12955            ServiceInfo filterSi = filter.service.info;
12956            for (int i=dest.size()-1; i>=0; i--) {
12957                ServiceInfo destAi = dest.get(i).serviceInfo;
12958                if (destAi.name == filterSi.name
12959                        && destAi.packageName == filterSi.packageName) {
12960                    return false;
12961                }
12962            }
12963            return true;
12964        }
12965
12966        @Override
12967        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12968            return new PackageParser.ServiceIntentInfo[size];
12969        }
12970
12971        @Override
12972        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12973            if (!sUserManager.exists(userId)) return true;
12974            PackageParser.Package p = filter.service.owner;
12975            if (p != null) {
12976                PackageSetting ps = (PackageSetting)p.mExtras;
12977                if (ps != null) {
12978                    // System apps are never considered stopped for purposes of
12979                    // filtering, because there may be no way for the user to
12980                    // actually re-launch them.
12981                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12982                            && ps.getStopped(userId);
12983                }
12984            }
12985            return false;
12986        }
12987
12988        @Override
12989        protected boolean isPackageForFilter(String packageName,
12990                PackageParser.ServiceIntentInfo info) {
12991            return packageName.equals(info.service.owner.packageName);
12992        }
12993
12994        @Override
12995        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12996                int match, int userId) {
12997            if (!sUserManager.exists(userId)) return null;
12998            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12999            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13000                return null;
13001            }
13002            final PackageParser.Service service = info.service;
13003            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13004            if (ps == null) {
13005                return null;
13006            }
13007            final PackageUserState userState = ps.readUserState(userId);
13008            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13009                    userState, userId);
13010            if (si == null) {
13011                return null;
13012            }
13013            final boolean matchVisibleToInstantApp =
13014                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13015            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13016            // throw out filters that aren't visible to ephemeral apps
13017            if (matchVisibleToInstantApp
13018                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13019                return null;
13020            }
13021            // throw out ephemeral filters if we're not explicitly requesting them
13022            if (!isInstantApp && userState.instantApp) {
13023                return null;
13024            }
13025            // throw out instant app filters if updates are available; will trigger
13026            // instant app resolution
13027            if (userState.instantApp && ps.isUpdateAvailable()) {
13028                return null;
13029            }
13030            final ResolveInfo res = new ResolveInfo();
13031            res.serviceInfo = si;
13032            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13033                res.filter = filter;
13034            }
13035            res.priority = info.getPriority();
13036            res.preferredOrder = service.owner.mPreferredOrder;
13037            res.match = match;
13038            res.isDefault = info.hasDefault;
13039            res.labelRes = info.labelRes;
13040            res.nonLocalizedLabel = info.nonLocalizedLabel;
13041            res.icon = info.icon;
13042            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13043            return res;
13044        }
13045
13046        @Override
13047        protected void sortResults(List<ResolveInfo> results) {
13048            Collections.sort(results, mResolvePrioritySorter);
13049        }
13050
13051        @Override
13052        protected void dumpFilter(PrintWriter out, String prefix,
13053                PackageParser.ServiceIntentInfo filter) {
13054            out.print(prefix); out.print(
13055                    Integer.toHexString(System.identityHashCode(filter.service)));
13056                    out.print(' ');
13057                    filter.service.printComponentShortName(out);
13058                    out.print(" filter ");
13059                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13060        }
13061
13062        @Override
13063        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13064            return filter.service;
13065        }
13066
13067        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13068            PackageParser.Service service = (PackageParser.Service)label;
13069            out.print(prefix); out.print(
13070                    Integer.toHexString(System.identityHashCode(service)));
13071                    out.print(' ');
13072                    service.printComponentShortName(out);
13073            if (count > 1) {
13074                out.print(" ("); out.print(count); out.print(" filters)");
13075            }
13076            out.println();
13077        }
13078
13079//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13080//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13081//            final List<ResolveInfo> retList = Lists.newArrayList();
13082//            while (i.hasNext()) {
13083//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13084//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13085//                    retList.add(resolveInfo);
13086//                }
13087//            }
13088//            return retList;
13089//        }
13090
13091        // Keys are String (activity class name), values are Activity.
13092        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13093                = new ArrayMap<ComponentName, PackageParser.Service>();
13094        private int mFlags;
13095    }
13096
13097    private final class ProviderIntentResolver
13098            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13099        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13100                boolean defaultOnly, int userId) {
13101            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13102            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13103        }
13104
13105        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13106                int userId) {
13107            if (!sUserManager.exists(userId))
13108                return null;
13109            mFlags = flags;
13110            return super.queryIntent(intent, resolvedType,
13111                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13112                    userId);
13113        }
13114
13115        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13116                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13117            if (!sUserManager.exists(userId))
13118                return null;
13119            if (packageProviders == null) {
13120                return null;
13121            }
13122            mFlags = flags;
13123            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13124            final int N = packageProviders.size();
13125            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13126                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13127
13128            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13129            for (int i = 0; i < N; ++i) {
13130                intentFilters = packageProviders.get(i).intents;
13131                if (intentFilters != null && intentFilters.size() > 0) {
13132                    PackageParser.ProviderIntentInfo[] array =
13133                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13134                    intentFilters.toArray(array);
13135                    listCut.add(array);
13136                }
13137            }
13138            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13139        }
13140
13141        public final void addProvider(PackageParser.Provider p) {
13142            if (mProviders.containsKey(p.getComponentName())) {
13143                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13144                return;
13145            }
13146
13147            mProviders.put(p.getComponentName(), p);
13148            if (DEBUG_SHOW_INFO) {
13149                Log.v(TAG, "  "
13150                        + (p.info.nonLocalizedLabel != null
13151                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13152                Log.v(TAG, "    Class=" + p.info.name);
13153            }
13154            final int NI = p.intents.size();
13155            int j;
13156            for (j = 0; j < NI; j++) {
13157                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13158                if (DEBUG_SHOW_INFO) {
13159                    Log.v(TAG, "    IntentFilter:");
13160                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13161                }
13162                if (!intent.debugCheck()) {
13163                    Log.w(TAG, "==> For Provider " + p.info.name);
13164                }
13165                addFilter(intent);
13166            }
13167        }
13168
13169        public final void removeProvider(PackageParser.Provider p) {
13170            mProviders.remove(p.getComponentName());
13171            if (DEBUG_SHOW_INFO) {
13172                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13173                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13174                Log.v(TAG, "    Class=" + p.info.name);
13175            }
13176            final int NI = p.intents.size();
13177            int j;
13178            for (j = 0; j < NI; j++) {
13179                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13180                if (DEBUG_SHOW_INFO) {
13181                    Log.v(TAG, "    IntentFilter:");
13182                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13183                }
13184                removeFilter(intent);
13185            }
13186        }
13187
13188        @Override
13189        protected boolean allowFilterResult(
13190                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13191            ProviderInfo filterPi = filter.provider.info;
13192            for (int i = dest.size() - 1; i >= 0; i--) {
13193                ProviderInfo destPi = dest.get(i).providerInfo;
13194                if (destPi.name == filterPi.name
13195                        && destPi.packageName == filterPi.packageName) {
13196                    return false;
13197                }
13198            }
13199            return true;
13200        }
13201
13202        @Override
13203        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13204            return new PackageParser.ProviderIntentInfo[size];
13205        }
13206
13207        @Override
13208        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13209            if (!sUserManager.exists(userId))
13210                return true;
13211            PackageParser.Package p = filter.provider.owner;
13212            if (p != null) {
13213                PackageSetting ps = (PackageSetting) p.mExtras;
13214                if (ps != null) {
13215                    // System apps are never considered stopped for purposes of
13216                    // filtering, because there may be no way for the user to
13217                    // actually re-launch them.
13218                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13219                            && ps.getStopped(userId);
13220                }
13221            }
13222            return false;
13223        }
13224
13225        @Override
13226        protected boolean isPackageForFilter(String packageName,
13227                PackageParser.ProviderIntentInfo info) {
13228            return packageName.equals(info.provider.owner.packageName);
13229        }
13230
13231        @Override
13232        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13233                int match, int userId) {
13234            if (!sUserManager.exists(userId))
13235                return null;
13236            final PackageParser.ProviderIntentInfo info = filter;
13237            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13238                return null;
13239            }
13240            final PackageParser.Provider provider = info.provider;
13241            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13242            if (ps == null) {
13243                return null;
13244            }
13245            final PackageUserState userState = ps.readUserState(userId);
13246            final boolean matchVisibleToInstantApp =
13247                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13248            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13249            // throw out filters that aren't visible to instant applications
13250            if (matchVisibleToInstantApp
13251                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13252                return null;
13253            }
13254            // throw out instant application filters if we're not explicitly requesting them
13255            if (!isInstantApp && userState.instantApp) {
13256                return null;
13257            }
13258            // throw out instant application filters if updates are available; will trigger
13259            // instant application resolution
13260            if (userState.instantApp && ps.isUpdateAvailable()) {
13261                return null;
13262            }
13263            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13264                    userState, userId);
13265            if (pi == null) {
13266                return null;
13267            }
13268            final ResolveInfo res = new ResolveInfo();
13269            res.providerInfo = pi;
13270            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13271                res.filter = filter;
13272            }
13273            res.priority = info.getPriority();
13274            res.preferredOrder = provider.owner.mPreferredOrder;
13275            res.match = match;
13276            res.isDefault = info.hasDefault;
13277            res.labelRes = info.labelRes;
13278            res.nonLocalizedLabel = info.nonLocalizedLabel;
13279            res.icon = info.icon;
13280            res.system = res.providerInfo.applicationInfo.isSystemApp();
13281            return res;
13282        }
13283
13284        @Override
13285        protected void sortResults(List<ResolveInfo> results) {
13286            Collections.sort(results, mResolvePrioritySorter);
13287        }
13288
13289        @Override
13290        protected void dumpFilter(PrintWriter out, String prefix,
13291                PackageParser.ProviderIntentInfo filter) {
13292            out.print(prefix);
13293            out.print(
13294                    Integer.toHexString(System.identityHashCode(filter.provider)));
13295            out.print(' ');
13296            filter.provider.printComponentShortName(out);
13297            out.print(" filter ");
13298            out.println(Integer.toHexString(System.identityHashCode(filter)));
13299        }
13300
13301        @Override
13302        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13303            return filter.provider;
13304        }
13305
13306        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13307            PackageParser.Provider provider = (PackageParser.Provider)label;
13308            out.print(prefix); out.print(
13309                    Integer.toHexString(System.identityHashCode(provider)));
13310                    out.print(' ');
13311                    provider.printComponentShortName(out);
13312            if (count > 1) {
13313                out.print(" ("); out.print(count); out.print(" filters)");
13314            }
13315            out.println();
13316        }
13317
13318        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13319                = new ArrayMap<ComponentName, PackageParser.Provider>();
13320        private int mFlags;
13321    }
13322
13323    static final class EphemeralIntentResolver
13324            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
13325        /**
13326         * The result that has the highest defined order. Ordering applies on a
13327         * per-package basis. Mapping is from package name to Pair of order and
13328         * EphemeralResolveInfo.
13329         * <p>
13330         * NOTE: This is implemented as a field variable for convenience and efficiency.
13331         * By having a field variable, we're able to track filter ordering as soon as
13332         * a non-zero order is defined. Otherwise, multiple loops across the result set
13333         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13334         * this needs to be contained entirely within {@link #filterResults}.
13335         */
13336        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13337
13338        @Override
13339        protected AuxiliaryResolveInfo[] newArray(int size) {
13340            return new AuxiliaryResolveInfo[size];
13341        }
13342
13343        @Override
13344        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
13345            return true;
13346        }
13347
13348        @Override
13349        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
13350                int userId) {
13351            if (!sUserManager.exists(userId)) {
13352                return null;
13353            }
13354            final String packageName = responseObj.resolveInfo.getPackageName();
13355            final Integer order = responseObj.getOrder();
13356            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13357                    mOrderResult.get(packageName);
13358            // ordering is enabled and this item's order isn't high enough
13359            if (lastOrderResult != null && lastOrderResult.first >= order) {
13360                return null;
13361            }
13362            final InstantAppResolveInfo res = responseObj.resolveInfo;
13363            if (order > 0) {
13364                // non-zero order, enable ordering
13365                mOrderResult.put(packageName, new Pair<>(order, res));
13366            }
13367            return responseObj;
13368        }
13369
13370        @Override
13371        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13372            // only do work if ordering is enabled [most of the time it won't be]
13373            if (mOrderResult.size() == 0) {
13374                return;
13375            }
13376            int resultSize = results.size();
13377            for (int i = 0; i < resultSize; i++) {
13378                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13379                final String packageName = info.getPackageName();
13380                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13381                if (savedInfo == null) {
13382                    // package doesn't having ordering
13383                    continue;
13384                }
13385                if (savedInfo.second == info) {
13386                    // circled back to the highest ordered item; remove from order list
13387                    mOrderResult.remove(savedInfo);
13388                    if (mOrderResult.size() == 0) {
13389                        // no more ordered items
13390                        break;
13391                    }
13392                    continue;
13393                }
13394                // item has a worse order, remove it from the result list
13395                results.remove(i);
13396                resultSize--;
13397                i--;
13398            }
13399        }
13400    }
13401
13402    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13403            new Comparator<ResolveInfo>() {
13404        public int compare(ResolveInfo r1, ResolveInfo r2) {
13405            int v1 = r1.priority;
13406            int v2 = r2.priority;
13407            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13408            if (v1 != v2) {
13409                return (v1 > v2) ? -1 : 1;
13410            }
13411            v1 = r1.preferredOrder;
13412            v2 = r2.preferredOrder;
13413            if (v1 != v2) {
13414                return (v1 > v2) ? -1 : 1;
13415            }
13416            if (r1.isDefault != r2.isDefault) {
13417                return r1.isDefault ? -1 : 1;
13418            }
13419            v1 = r1.match;
13420            v2 = r2.match;
13421            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13422            if (v1 != v2) {
13423                return (v1 > v2) ? -1 : 1;
13424            }
13425            if (r1.system != r2.system) {
13426                return r1.system ? -1 : 1;
13427            }
13428            if (r1.activityInfo != null) {
13429                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13430            }
13431            if (r1.serviceInfo != null) {
13432                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13433            }
13434            if (r1.providerInfo != null) {
13435                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13436            }
13437            return 0;
13438        }
13439    };
13440
13441    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13442            new Comparator<ProviderInfo>() {
13443        public int compare(ProviderInfo p1, ProviderInfo p2) {
13444            final int v1 = p1.initOrder;
13445            final int v2 = p2.initOrder;
13446            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13447        }
13448    };
13449
13450    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13451            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13452            final int[] userIds) {
13453        mHandler.post(new Runnable() {
13454            @Override
13455            public void run() {
13456                try {
13457                    final IActivityManager am = ActivityManager.getService();
13458                    if (am == null) return;
13459                    final int[] resolvedUserIds;
13460                    if (userIds == null) {
13461                        resolvedUserIds = am.getRunningUserIds();
13462                    } else {
13463                        resolvedUserIds = userIds;
13464                    }
13465                    for (int id : resolvedUserIds) {
13466                        final Intent intent = new Intent(action,
13467                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13468                        if (extras != null) {
13469                            intent.putExtras(extras);
13470                        }
13471                        if (targetPkg != null) {
13472                            intent.setPackage(targetPkg);
13473                        }
13474                        // Modify the UID when posting to other users
13475                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13476                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13477                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13478                            intent.putExtra(Intent.EXTRA_UID, uid);
13479                        }
13480                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13481                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13482                        if (DEBUG_BROADCASTS) {
13483                            RuntimeException here = new RuntimeException("here");
13484                            here.fillInStackTrace();
13485                            Slog.d(TAG, "Sending to user " + id + ": "
13486                                    + intent.toShortString(false, true, false, false)
13487                                    + " " + intent.getExtras(), here);
13488                        }
13489                        am.broadcastIntent(null, intent, null, finishedReceiver,
13490                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13491                                null, finishedReceiver != null, false, id);
13492                    }
13493                } catch (RemoteException ex) {
13494                }
13495            }
13496        });
13497    }
13498
13499    /**
13500     * Check if the external storage media is available. This is true if there
13501     * is a mounted external storage medium or if the external storage is
13502     * emulated.
13503     */
13504    private boolean isExternalMediaAvailable() {
13505        return mMediaMounted || Environment.isExternalStorageEmulated();
13506    }
13507
13508    @Override
13509    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13510        // writer
13511        synchronized (mPackages) {
13512            if (!isExternalMediaAvailable()) {
13513                // If the external storage is no longer mounted at this point,
13514                // the caller may not have been able to delete all of this
13515                // packages files and can not delete any more.  Bail.
13516                return null;
13517            }
13518            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13519            if (lastPackage != null) {
13520                pkgs.remove(lastPackage);
13521            }
13522            if (pkgs.size() > 0) {
13523                return pkgs.get(0);
13524            }
13525        }
13526        return null;
13527    }
13528
13529    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13530        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13531                userId, andCode ? 1 : 0, packageName);
13532        if (mSystemReady) {
13533            msg.sendToTarget();
13534        } else {
13535            if (mPostSystemReadyMessages == null) {
13536                mPostSystemReadyMessages = new ArrayList<>();
13537            }
13538            mPostSystemReadyMessages.add(msg);
13539        }
13540    }
13541
13542    void startCleaningPackages() {
13543        // reader
13544        if (!isExternalMediaAvailable()) {
13545            return;
13546        }
13547        synchronized (mPackages) {
13548            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13549                return;
13550            }
13551        }
13552        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13553        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13554        IActivityManager am = ActivityManager.getService();
13555        if (am != null) {
13556            int dcsUid = -1;
13557            synchronized (mPackages) {
13558                if (!mDefaultContainerWhitelisted) {
13559                    mDefaultContainerWhitelisted = true;
13560                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13561                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13562                }
13563            }
13564            try {
13565                if (dcsUid > 0) {
13566                    am.backgroundWhitelistUid(dcsUid);
13567                }
13568                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13569                        UserHandle.USER_SYSTEM);
13570            } catch (RemoteException e) {
13571            }
13572        }
13573    }
13574
13575    @Override
13576    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13577            int installFlags, String installerPackageName, int userId) {
13578        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13579
13580        final int callingUid = Binder.getCallingUid();
13581        enforceCrossUserPermission(callingUid, userId,
13582                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13583
13584        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13585            try {
13586                if (observer != null) {
13587                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13588                }
13589            } catch (RemoteException re) {
13590            }
13591            return;
13592        }
13593
13594        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13595            installFlags |= PackageManager.INSTALL_FROM_ADB;
13596
13597        } else {
13598            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13599            // about installerPackageName.
13600
13601            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13602            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13603        }
13604
13605        UserHandle user;
13606        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13607            user = UserHandle.ALL;
13608        } else {
13609            user = new UserHandle(userId);
13610        }
13611
13612        // Only system components can circumvent runtime permissions when installing.
13613        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13614                && mContext.checkCallingOrSelfPermission(Manifest.permission
13615                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13616            throw new SecurityException("You need the "
13617                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13618                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13619        }
13620
13621        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13622                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13623            throw new IllegalArgumentException(
13624                    "New installs into ASEC containers no longer supported");
13625        }
13626
13627        final File originFile = new File(originPath);
13628        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13629
13630        final Message msg = mHandler.obtainMessage(INIT_COPY);
13631        final VerificationInfo verificationInfo = new VerificationInfo(
13632                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13633        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13634                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13635                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13636                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13637        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13638        msg.obj = params;
13639
13640        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13641                System.identityHashCode(msg.obj));
13642        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13643                System.identityHashCode(msg.obj));
13644
13645        mHandler.sendMessage(msg);
13646    }
13647
13648
13649    /**
13650     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13651     * it is acting on behalf on an enterprise or the user).
13652     *
13653     * Note that the ordering of the conditionals in this method is important. The checks we perform
13654     * are as follows, in this order:
13655     *
13656     * 1) If the install is being performed by a system app, we can trust the app to have set the
13657     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13658     *    what it is.
13659     * 2) If the install is being performed by a device or profile owner app, the install reason
13660     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13661     *    set the install reason correctly. If the app targets an older SDK version where install
13662     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13663     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13664     * 3) In all other cases, the install is being performed by a regular app that is neither part
13665     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13666     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13667     *    set to enterprise policy and if so, change it to unknown instead.
13668     */
13669    private int fixUpInstallReason(String installerPackageName, int installerUid,
13670            int installReason) {
13671        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13672                == PERMISSION_GRANTED) {
13673            // If the install is being performed by a system app, we trust that app to have set the
13674            // install reason correctly.
13675            return installReason;
13676        }
13677
13678        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13679            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13680        if (dpm != null) {
13681            ComponentName owner = null;
13682            try {
13683                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13684                if (owner == null) {
13685                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13686                }
13687            } catch (RemoteException e) {
13688            }
13689            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13690                // If the install is being performed by a device or profile owner, the install
13691                // reason should be enterprise policy.
13692                return PackageManager.INSTALL_REASON_POLICY;
13693            }
13694        }
13695
13696        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13697            // If the install is being performed by a regular app (i.e. neither system app nor
13698            // device or profile owner), we have no reason to believe that the app is acting on
13699            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13700            // change it to unknown instead.
13701            return PackageManager.INSTALL_REASON_UNKNOWN;
13702        }
13703
13704        // If the install is being performed by a regular app and the install reason was set to any
13705        // value but enterprise policy, leave the install reason unchanged.
13706        return installReason;
13707    }
13708
13709    void installStage(String packageName, File stagedDir, String stagedCid,
13710            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13711            String installerPackageName, int installerUid, UserHandle user,
13712            Certificate[][] certificates) {
13713        if (DEBUG_EPHEMERAL) {
13714            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13715                Slog.d(TAG, "Ephemeral install of " + packageName);
13716            }
13717        }
13718        final VerificationInfo verificationInfo = new VerificationInfo(
13719                sessionParams.originatingUri, sessionParams.referrerUri,
13720                sessionParams.originatingUid, installerUid);
13721
13722        final OriginInfo origin;
13723        if (stagedDir != null) {
13724            origin = OriginInfo.fromStagedFile(stagedDir);
13725        } else {
13726            origin = OriginInfo.fromStagedContainer(stagedCid);
13727        }
13728
13729        final Message msg = mHandler.obtainMessage(INIT_COPY);
13730        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13731                sessionParams.installReason);
13732        final InstallParams params = new InstallParams(origin, null, observer,
13733                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13734                verificationInfo, user, sessionParams.abiOverride,
13735                sessionParams.grantedRuntimePermissions, certificates, installReason);
13736        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13737        msg.obj = params;
13738
13739        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13740                System.identityHashCode(msg.obj));
13741        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13742                System.identityHashCode(msg.obj));
13743
13744        mHandler.sendMessage(msg);
13745    }
13746
13747    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13748            int userId) {
13749        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13750        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
13751
13752        // Send a session commit broadcast
13753        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13754        info.installReason = pkgSetting.getInstallReason(userId);
13755        info.appPackageName = packageName;
13756        sendSessionCommitBroadcast(info, userId);
13757    }
13758
13759    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
13760        if (ArrayUtils.isEmpty(userIds)) {
13761            return;
13762        }
13763        Bundle extras = new Bundle(1);
13764        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13765        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13766
13767        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13768                packageName, extras, 0, null, null, userIds);
13769        if (isSystem) {
13770            mHandler.post(() -> {
13771                        for (int userId : userIds) {
13772                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
13773                        }
13774                    }
13775            );
13776        }
13777    }
13778
13779    /**
13780     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13781     * automatically without needing an explicit launch.
13782     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13783     */
13784    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
13785        // If user is not running, the app didn't miss any broadcast
13786        if (!mUserManagerInternal.isUserRunning(userId)) {
13787            return;
13788        }
13789        final IActivityManager am = ActivityManager.getService();
13790        try {
13791            // Deliver LOCKED_BOOT_COMPLETED first
13792            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13793                    .setPackage(packageName);
13794            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13795            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13796                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13797
13798            // Deliver BOOT_COMPLETED only if user is unlocked
13799            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13800                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13801                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13802                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13803            }
13804        } catch (RemoteException e) {
13805            throw e.rethrowFromSystemServer();
13806        }
13807    }
13808
13809    @Override
13810    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13811            int userId) {
13812        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13813        PackageSetting pkgSetting;
13814        final int uid = Binder.getCallingUid();
13815        enforceCrossUserPermission(uid, userId,
13816                true /* requireFullPermission */, true /* checkShell */,
13817                "setApplicationHiddenSetting for user " + userId);
13818
13819        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13820            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13821            return false;
13822        }
13823
13824        long callingId = Binder.clearCallingIdentity();
13825        try {
13826            boolean sendAdded = false;
13827            boolean sendRemoved = false;
13828            // writer
13829            synchronized (mPackages) {
13830                pkgSetting = mSettings.mPackages.get(packageName);
13831                if (pkgSetting == null) {
13832                    return false;
13833                }
13834                // Do not allow "android" is being disabled
13835                if ("android".equals(packageName)) {
13836                    Slog.w(TAG, "Cannot hide package: android");
13837                    return false;
13838                }
13839                // Cannot hide static shared libs as they are considered
13840                // a part of the using app (emulating static linking). Also
13841                // static libs are installed always on internal storage.
13842                PackageParser.Package pkg = mPackages.get(packageName);
13843                if (pkg != null && pkg.staticSharedLibName != null) {
13844                    Slog.w(TAG, "Cannot hide package: " + packageName
13845                            + " providing static shared library: "
13846                            + pkg.staticSharedLibName);
13847                    return false;
13848                }
13849                // Only allow protected packages to hide themselves.
13850                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
13851                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13852                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13853                    return false;
13854                }
13855
13856                if (pkgSetting.getHidden(userId) != hidden) {
13857                    pkgSetting.setHidden(hidden, userId);
13858                    mSettings.writePackageRestrictionsLPr(userId);
13859                    if (hidden) {
13860                        sendRemoved = true;
13861                    } else {
13862                        sendAdded = true;
13863                    }
13864                }
13865            }
13866            if (sendAdded) {
13867                sendPackageAddedForUser(packageName, pkgSetting, userId);
13868                return true;
13869            }
13870            if (sendRemoved) {
13871                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13872                        "hiding pkg");
13873                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13874                return true;
13875            }
13876        } finally {
13877            Binder.restoreCallingIdentity(callingId);
13878        }
13879        return false;
13880    }
13881
13882    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13883            int userId) {
13884        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13885        info.removedPackage = packageName;
13886        info.installerPackageName = pkgSetting.installerPackageName;
13887        info.removedUsers = new int[] {userId};
13888        info.broadcastUsers = new int[] {userId};
13889        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13890        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13891    }
13892
13893    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13894        if (pkgList.length > 0) {
13895            Bundle extras = new Bundle(1);
13896            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13897
13898            sendPackageBroadcast(
13899                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13900                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13901                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13902                    new int[] {userId});
13903        }
13904    }
13905
13906    /**
13907     * Returns true if application is not found or there was an error. Otherwise it returns
13908     * the hidden state of the package for the given user.
13909     */
13910    @Override
13911    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13912        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13913        enforceCrossUserPermission(Binder.getCallingUid(), userId,
13914                true /* requireFullPermission */, false /* checkShell */,
13915                "getApplicationHidden for user " + userId);
13916        PackageSetting pkgSetting;
13917        long callingId = Binder.clearCallingIdentity();
13918        try {
13919            // writer
13920            synchronized (mPackages) {
13921                pkgSetting = mSettings.mPackages.get(packageName);
13922                if (pkgSetting == null) {
13923                    return true;
13924                }
13925                return pkgSetting.getHidden(userId);
13926            }
13927        } finally {
13928            Binder.restoreCallingIdentity(callingId);
13929        }
13930    }
13931
13932    /**
13933     * @hide
13934     */
13935    @Override
13936    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13937            int installReason) {
13938        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13939                null);
13940        PackageSetting pkgSetting;
13941        final int uid = Binder.getCallingUid();
13942        enforceCrossUserPermission(uid, userId,
13943                true /* requireFullPermission */, true /* checkShell */,
13944                "installExistingPackage for user " + userId);
13945        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13946            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13947        }
13948
13949        long callingId = Binder.clearCallingIdentity();
13950        try {
13951            boolean installed = false;
13952            final boolean instantApp =
13953                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13954            final boolean fullApp =
13955                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13956
13957            // writer
13958            synchronized (mPackages) {
13959                pkgSetting = mSettings.mPackages.get(packageName);
13960                if (pkgSetting == null) {
13961                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13962                }
13963                if (!pkgSetting.getInstalled(userId)) {
13964                    pkgSetting.setInstalled(true, userId);
13965                    pkgSetting.setHidden(false, userId);
13966                    pkgSetting.setInstallReason(installReason, userId);
13967                    mSettings.writePackageRestrictionsLPr(userId);
13968                    mSettings.writeKernelMappingLPr(pkgSetting);
13969                    installed = true;
13970                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13971                    // upgrade app from instant to full; we don't allow app downgrade
13972                    installed = true;
13973                }
13974                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13975            }
13976
13977            if (installed) {
13978                if (pkgSetting.pkg != null) {
13979                    synchronized (mInstallLock) {
13980                        // We don't need to freeze for a brand new install
13981                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13982                    }
13983                }
13984                sendPackageAddedForUser(packageName, pkgSetting, userId);
13985                synchronized (mPackages) {
13986                    updateSequenceNumberLP(packageName, new int[]{ userId });
13987                }
13988            }
13989        } finally {
13990            Binder.restoreCallingIdentity(callingId);
13991        }
13992
13993        return PackageManager.INSTALL_SUCCEEDED;
13994    }
13995
13996    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13997            boolean instantApp, boolean fullApp) {
13998        // no state specified; do nothing
13999        if (!instantApp && !fullApp) {
14000            return;
14001        }
14002        if (userId != UserHandle.USER_ALL) {
14003            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14004                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14005            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14006                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14007            }
14008        } else {
14009            for (int currentUserId : sUserManager.getUserIds()) {
14010                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14011                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14012                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14013                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14014                }
14015            }
14016        }
14017    }
14018
14019    boolean isUserRestricted(int userId, String restrictionKey) {
14020        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14021        if (restrictions.getBoolean(restrictionKey, false)) {
14022            Log.w(TAG, "User is restricted: " + restrictionKey);
14023            return true;
14024        }
14025        return false;
14026    }
14027
14028    @Override
14029    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14030            int userId) {
14031        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14032        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14033                true /* requireFullPermission */, true /* checkShell */,
14034                "setPackagesSuspended for user " + userId);
14035
14036        if (ArrayUtils.isEmpty(packageNames)) {
14037            return packageNames;
14038        }
14039
14040        // List of package names for whom the suspended state has changed.
14041        List<String> changedPackages = new ArrayList<>(packageNames.length);
14042        // List of package names for whom the suspended state is not set as requested in this
14043        // method.
14044        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14045        long callingId = Binder.clearCallingIdentity();
14046        try {
14047            for (int i = 0; i < packageNames.length; i++) {
14048                String packageName = packageNames[i];
14049                boolean changed = false;
14050                final int appId;
14051                synchronized (mPackages) {
14052                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14053                    if (pkgSetting == null) {
14054                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14055                                + "\". Skipping suspending/un-suspending.");
14056                        unactionedPackages.add(packageName);
14057                        continue;
14058                    }
14059                    appId = pkgSetting.appId;
14060                    if (pkgSetting.getSuspended(userId) != suspended) {
14061                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14062                            unactionedPackages.add(packageName);
14063                            continue;
14064                        }
14065                        pkgSetting.setSuspended(suspended, userId);
14066                        mSettings.writePackageRestrictionsLPr(userId);
14067                        changed = true;
14068                        changedPackages.add(packageName);
14069                    }
14070                }
14071
14072                if (changed && suspended) {
14073                    killApplication(packageName, UserHandle.getUid(userId, appId),
14074                            "suspending package");
14075                }
14076            }
14077        } finally {
14078            Binder.restoreCallingIdentity(callingId);
14079        }
14080
14081        if (!changedPackages.isEmpty()) {
14082            sendPackagesSuspendedForUser(changedPackages.toArray(
14083                    new String[changedPackages.size()]), userId, suspended);
14084        }
14085
14086        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14087    }
14088
14089    @Override
14090    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14091        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14092                true /* requireFullPermission */, false /* checkShell */,
14093                "isPackageSuspendedForUser for user " + userId);
14094        synchronized (mPackages) {
14095            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14096            if (pkgSetting == null) {
14097                throw new IllegalArgumentException("Unknown target package: " + packageName);
14098            }
14099            return pkgSetting.getSuspended(userId);
14100        }
14101    }
14102
14103    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14104        if (isPackageDeviceAdmin(packageName, userId)) {
14105            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14106                    + "\": has an active device admin");
14107            return false;
14108        }
14109
14110        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14111        if (packageName.equals(activeLauncherPackageName)) {
14112            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14113                    + "\": contains the active launcher");
14114            return false;
14115        }
14116
14117        if (packageName.equals(mRequiredInstallerPackage)) {
14118            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14119                    + "\": required for package installation");
14120            return false;
14121        }
14122
14123        if (packageName.equals(mRequiredUninstallerPackage)) {
14124            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14125                    + "\": required for package uninstallation");
14126            return false;
14127        }
14128
14129        if (packageName.equals(mRequiredVerifierPackage)) {
14130            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14131                    + "\": required for package verification");
14132            return false;
14133        }
14134
14135        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14136            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14137                    + "\": is the default dialer");
14138            return false;
14139        }
14140
14141        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14142            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14143                    + "\": protected package");
14144            return false;
14145        }
14146
14147        // Cannot suspend static shared libs as they are considered
14148        // a part of the using app (emulating static linking). Also
14149        // static libs are installed always on internal storage.
14150        PackageParser.Package pkg = mPackages.get(packageName);
14151        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14152            Slog.w(TAG, "Cannot suspend package: " + packageName
14153                    + " providing static shared library: "
14154                    + pkg.staticSharedLibName);
14155            return false;
14156        }
14157
14158        return true;
14159    }
14160
14161    private String getActiveLauncherPackageName(int userId) {
14162        Intent intent = new Intent(Intent.ACTION_MAIN);
14163        intent.addCategory(Intent.CATEGORY_HOME);
14164        ResolveInfo resolveInfo = resolveIntent(
14165                intent,
14166                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14167                PackageManager.MATCH_DEFAULT_ONLY,
14168                userId);
14169
14170        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14171    }
14172
14173    private String getDefaultDialerPackageName(int userId) {
14174        synchronized (mPackages) {
14175            return mSettings.getDefaultDialerPackageNameLPw(userId);
14176        }
14177    }
14178
14179    @Override
14180    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14181        mContext.enforceCallingOrSelfPermission(
14182                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14183                "Only package verification agents can verify applications");
14184
14185        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14186        final PackageVerificationResponse response = new PackageVerificationResponse(
14187                verificationCode, Binder.getCallingUid());
14188        msg.arg1 = id;
14189        msg.obj = response;
14190        mHandler.sendMessage(msg);
14191    }
14192
14193    @Override
14194    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14195            long millisecondsToDelay) {
14196        mContext.enforceCallingOrSelfPermission(
14197                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14198                "Only package verification agents can extend verification timeouts");
14199
14200        final PackageVerificationState state = mPendingVerification.get(id);
14201        final PackageVerificationResponse response = new PackageVerificationResponse(
14202                verificationCodeAtTimeout, Binder.getCallingUid());
14203
14204        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14205            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14206        }
14207        if (millisecondsToDelay < 0) {
14208            millisecondsToDelay = 0;
14209        }
14210        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14211                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14212            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14213        }
14214
14215        if ((state != null) && !state.timeoutExtended()) {
14216            state.extendTimeout();
14217
14218            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14219            msg.arg1 = id;
14220            msg.obj = response;
14221            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14222        }
14223    }
14224
14225    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14226            int verificationCode, UserHandle user) {
14227        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14228        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14229        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14230        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14231        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14232
14233        mContext.sendBroadcastAsUser(intent, user,
14234                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14235    }
14236
14237    private ComponentName matchComponentForVerifier(String packageName,
14238            List<ResolveInfo> receivers) {
14239        ActivityInfo targetReceiver = null;
14240
14241        final int NR = receivers.size();
14242        for (int i = 0; i < NR; i++) {
14243            final ResolveInfo info = receivers.get(i);
14244            if (info.activityInfo == null) {
14245                continue;
14246            }
14247
14248            if (packageName.equals(info.activityInfo.packageName)) {
14249                targetReceiver = info.activityInfo;
14250                break;
14251            }
14252        }
14253
14254        if (targetReceiver == null) {
14255            return null;
14256        }
14257
14258        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14259    }
14260
14261    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14262            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14263        if (pkgInfo.verifiers.length == 0) {
14264            return null;
14265        }
14266
14267        final int N = pkgInfo.verifiers.length;
14268        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14269        for (int i = 0; i < N; i++) {
14270            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14271
14272            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14273                    receivers);
14274            if (comp == null) {
14275                continue;
14276            }
14277
14278            final int verifierUid = getUidForVerifier(verifierInfo);
14279            if (verifierUid == -1) {
14280                continue;
14281            }
14282
14283            if (DEBUG_VERIFY) {
14284                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14285                        + " with the correct signature");
14286            }
14287            sufficientVerifiers.add(comp);
14288            verificationState.addSufficientVerifier(verifierUid);
14289        }
14290
14291        return sufficientVerifiers;
14292    }
14293
14294    private int getUidForVerifier(VerifierInfo verifierInfo) {
14295        synchronized (mPackages) {
14296            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14297            if (pkg == null) {
14298                return -1;
14299            } else if (pkg.mSignatures.length != 1) {
14300                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14301                        + " has more than one signature; ignoring");
14302                return -1;
14303            }
14304
14305            /*
14306             * If the public key of the package's signature does not match
14307             * our expected public key, then this is a different package and
14308             * we should skip.
14309             */
14310
14311            final byte[] expectedPublicKey;
14312            try {
14313                final Signature verifierSig = pkg.mSignatures[0];
14314                final PublicKey publicKey = verifierSig.getPublicKey();
14315                expectedPublicKey = publicKey.getEncoded();
14316            } catch (CertificateException e) {
14317                return -1;
14318            }
14319
14320            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14321
14322            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14323                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14324                        + " does not have the expected public key; ignoring");
14325                return -1;
14326            }
14327
14328            return pkg.applicationInfo.uid;
14329        }
14330    }
14331
14332    @Override
14333    public void finishPackageInstall(int token, boolean didLaunch) {
14334        enforceSystemOrRoot("Only the system is allowed to finish installs");
14335
14336        if (DEBUG_INSTALL) {
14337            Slog.v(TAG, "BM finishing package install for " + token);
14338        }
14339        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14340
14341        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14342        mHandler.sendMessage(msg);
14343    }
14344
14345    /**
14346     * Get the verification agent timeout.  Used for both the APK verifier and the
14347     * intent filter verifier.
14348     *
14349     * @return verification timeout in milliseconds
14350     */
14351    private long getVerificationTimeout() {
14352        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14353                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14354                DEFAULT_VERIFICATION_TIMEOUT);
14355    }
14356
14357    /**
14358     * Get the default verification agent response code.
14359     *
14360     * @return default verification response code
14361     */
14362    private int getDefaultVerificationResponse(UserHandle user) {
14363        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14364            return PackageManager.VERIFICATION_REJECT;
14365        }
14366        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14367                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14368                DEFAULT_VERIFICATION_RESPONSE);
14369    }
14370
14371    /**
14372     * Check whether or not package verification has been enabled.
14373     *
14374     * @return true if verification should be performed
14375     */
14376    private boolean isVerificationEnabled(int userId, int installFlags) {
14377        if (!DEFAULT_VERIFY_ENABLE) {
14378            return false;
14379        }
14380
14381        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14382
14383        // Check if installing from ADB
14384        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14385            // Do not run verification in a test harness environment
14386            if (ActivityManager.isRunningInTestHarness()) {
14387                return false;
14388            }
14389            if (ensureVerifyAppsEnabled) {
14390                return true;
14391            }
14392            // Check if the developer does not want package verification for ADB installs
14393            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14394                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14395                return false;
14396            }
14397        }
14398
14399        if (ensureVerifyAppsEnabled) {
14400            return true;
14401        }
14402
14403        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14404                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14405    }
14406
14407    @Override
14408    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14409            throws RemoteException {
14410        mContext.enforceCallingOrSelfPermission(
14411                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14412                "Only intentfilter verification agents can verify applications");
14413
14414        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14415        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14416                Binder.getCallingUid(), verificationCode, failedDomains);
14417        msg.arg1 = id;
14418        msg.obj = response;
14419        mHandler.sendMessage(msg);
14420    }
14421
14422    @Override
14423    public int getIntentVerificationStatus(String packageName, int userId) {
14424        synchronized (mPackages) {
14425            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14426        }
14427    }
14428
14429    @Override
14430    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14431        mContext.enforceCallingOrSelfPermission(
14432                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14433
14434        boolean result = false;
14435        synchronized (mPackages) {
14436            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14437        }
14438        if (result) {
14439            scheduleWritePackageRestrictionsLocked(userId);
14440        }
14441        return result;
14442    }
14443
14444    @Override
14445    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14446            String packageName) {
14447        synchronized (mPackages) {
14448            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14449        }
14450    }
14451
14452    @Override
14453    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14454        if (TextUtils.isEmpty(packageName)) {
14455            return ParceledListSlice.emptyList();
14456        }
14457        synchronized (mPackages) {
14458            PackageParser.Package pkg = mPackages.get(packageName);
14459            if (pkg == null || pkg.activities == null) {
14460                return ParceledListSlice.emptyList();
14461            }
14462            final int count = pkg.activities.size();
14463            ArrayList<IntentFilter> result = new ArrayList<>();
14464            for (int n=0; n<count; n++) {
14465                PackageParser.Activity activity = pkg.activities.get(n);
14466                if (activity.intents != null && activity.intents.size() > 0) {
14467                    result.addAll(activity.intents);
14468                }
14469            }
14470            return new ParceledListSlice<>(result);
14471        }
14472    }
14473
14474    @Override
14475    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14476        mContext.enforceCallingOrSelfPermission(
14477                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14478
14479        synchronized (mPackages) {
14480            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14481            if (packageName != null) {
14482                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14483                        packageName, userId);
14484            }
14485            return result;
14486        }
14487    }
14488
14489    @Override
14490    public String getDefaultBrowserPackageName(int userId) {
14491        synchronized (mPackages) {
14492            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14493        }
14494    }
14495
14496    /**
14497     * Get the "allow unknown sources" setting.
14498     *
14499     * @return the current "allow unknown sources" setting
14500     */
14501    private int getUnknownSourcesSettings() {
14502        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14503                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14504                -1);
14505    }
14506
14507    @Override
14508    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14509        final int uid = Binder.getCallingUid();
14510        // writer
14511        synchronized (mPackages) {
14512            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14513            if (targetPackageSetting == null) {
14514                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14515            }
14516
14517            PackageSetting installerPackageSetting;
14518            if (installerPackageName != null) {
14519                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14520                if (installerPackageSetting == null) {
14521                    throw new IllegalArgumentException("Unknown installer package: "
14522                            + installerPackageName);
14523                }
14524            } else {
14525                installerPackageSetting = null;
14526            }
14527
14528            Signature[] callerSignature;
14529            Object obj = mSettings.getUserIdLPr(uid);
14530            if (obj != null) {
14531                if (obj instanceof SharedUserSetting) {
14532                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14533                } else if (obj instanceof PackageSetting) {
14534                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14535                } else {
14536                    throw new SecurityException("Bad object " + obj + " for uid " + uid);
14537                }
14538            } else {
14539                throw new SecurityException("Unknown calling UID: " + uid);
14540            }
14541
14542            // Verify: can't set installerPackageName to a package that is
14543            // not signed with the same cert as the caller.
14544            if (installerPackageSetting != null) {
14545                if (compareSignatures(callerSignature,
14546                        installerPackageSetting.signatures.mSignatures)
14547                        != PackageManager.SIGNATURE_MATCH) {
14548                    throw new SecurityException(
14549                            "Caller does not have same cert as new installer package "
14550                            + installerPackageName);
14551                }
14552            }
14553
14554            // Verify: if target already has an installer package, it must
14555            // be signed with the same cert as the caller.
14556            if (targetPackageSetting.installerPackageName != null) {
14557                PackageSetting setting = mSettings.mPackages.get(
14558                        targetPackageSetting.installerPackageName);
14559                // If the currently set package isn't valid, then it's always
14560                // okay to change it.
14561                if (setting != null) {
14562                    if (compareSignatures(callerSignature,
14563                            setting.signatures.mSignatures)
14564                            != PackageManager.SIGNATURE_MATCH) {
14565                        throw new SecurityException(
14566                                "Caller does not have same cert as old installer package "
14567                                + targetPackageSetting.installerPackageName);
14568                    }
14569                }
14570            }
14571
14572            // Okay!
14573            targetPackageSetting.installerPackageName = installerPackageName;
14574            if (installerPackageName != null) {
14575                mSettings.mInstallerPackages.add(installerPackageName);
14576            }
14577            scheduleWriteSettingsLocked();
14578        }
14579    }
14580
14581    @Override
14582    public void setApplicationCategoryHint(String packageName, int categoryHint,
14583            String callerPackageName) {
14584        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14585                callerPackageName);
14586        synchronized (mPackages) {
14587            PackageSetting ps = mSettings.mPackages.get(packageName);
14588            if (ps == null) {
14589                throw new IllegalArgumentException("Unknown target package " + packageName);
14590            }
14591
14592            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14593                throw new IllegalArgumentException("Calling package " + callerPackageName
14594                        + " is not installer for " + packageName);
14595            }
14596
14597            if (ps.categoryHint != categoryHint) {
14598                ps.categoryHint = categoryHint;
14599                scheduleWriteSettingsLocked();
14600            }
14601        }
14602    }
14603
14604    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14605        // Queue up an async operation since the package installation may take a little while.
14606        mHandler.post(new Runnable() {
14607            public void run() {
14608                mHandler.removeCallbacks(this);
14609                 // Result object to be returned
14610                PackageInstalledInfo res = new PackageInstalledInfo();
14611                res.setReturnCode(currentStatus);
14612                res.uid = -1;
14613                res.pkg = null;
14614                res.removedInfo = null;
14615                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14616                    args.doPreInstall(res.returnCode);
14617                    synchronized (mInstallLock) {
14618                        installPackageTracedLI(args, res);
14619                    }
14620                    args.doPostInstall(res.returnCode, res.uid);
14621                }
14622
14623                // A restore should be performed at this point if (a) the install
14624                // succeeded, (b) the operation is not an update, and (c) the new
14625                // package has not opted out of backup participation.
14626                final boolean update = res.removedInfo != null
14627                        && res.removedInfo.removedPackage != null;
14628                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14629                boolean doRestore = !update
14630                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14631
14632                // Set up the post-install work request bookkeeping.  This will be used
14633                // and cleaned up by the post-install event handling regardless of whether
14634                // there's a restore pass performed.  Token values are >= 1.
14635                int token;
14636                if (mNextInstallToken < 0) mNextInstallToken = 1;
14637                token = mNextInstallToken++;
14638
14639                PostInstallData data = new PostInstallData(args, res);
14640                mRunningInstalls.put(token, data);
14641                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14642
14643                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14644                    // Pass responsibility to the Backup Manager.  It will perform a
14645                    // restore if appropriate, then pass responsibility back to the
14646                    // Package Manager to run the post-install observer callbacks
14647                    // and broadcasts.
14648                    IBackupManager bm = IBackupManager.Stub.asInterface(
14649                            ServiceManager.getService(Context.BACKUP_SERVICE));
14650                    if (bm != null) {
14651                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14652                                + " to BM for possible restore");
14653                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14654                        try {
14655                            // TODO: http://b/22388012
14656                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14657                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14658                            } else {
14659                                doRestore = false;
14660                            }
14661                        } catch (RemoteException e) {
14662                            // can't happen; the backup manager is local
14663                        } catch (Exception e) {
14664                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14665                            doRestore = false;
14666                        }
14667                    } else {
14668                        Slog.e(TAG, "Backup Manager not found!");
14669                        doRestore = false;
14670                    }
14671                }
14672
14673                if (!doRestore) {
14674                    // No restore possible, or the Backup Manager was mysteriously not
14675                    // available -- just fire the post-install work request directly.
14676                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14677
14678                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14679
14680                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14681                    mHandler.sendMessage(msg);
14682                }
14683            }
14684        });
14685    }
14686
14687    /**
14688     * Callback from PackageSettings whenever an app is first transitioned out of the
14689     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14690     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14691     * here whether the app is the target of an ongoing install, and only send the
14692     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14693     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14694     * handling.
14695     */
14696    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14697        // Serialize this with the rest of the install-process message chain.  In the
14698        // restore-at-install case, this Runnable will necessarily run before the
14699        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14700        // are coherent.  In the non-restore case, the app has already completed install
14701        // and been launched through some other means, so it is not in a problematic
14702        // state for observers to see the FIRST_LAUNCH signal.
14703        mHandler.post(new Runnable() {
14704            @Override
14705            public void run() {
14706                for (int i = 0; i < mRunningInstalls.size(); i++) {
14707                    final PostInstallData data = mRunningInstalls.valueAt(i);
14708                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14709                        continue;
14710                    }
14711                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14712                        // right package; but is it for the right user?
14713                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14714                            if (userId == data.res.newUsers[uIndex]) {
14715                                if (DEBUG_BACKUP) {
14716                                    Slog.i(TAG, "Package " + pkgName
14717                                            + " being restored so deferring FIRST_LAUNCH");
14718                                }
14719                                return;
14720                            }
14721                        }
14722                    }
14723                }
14724                // didn't find it, so not being restored
14725                if (DEBUG_BACKUP) {
14726                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14727                }
14728                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14729            }
14730        });
14731    }
14732
14733    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14734        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14735                installerPkg, null, userIds);
14736    }
14737
14738    private abstract class HandlerParams {
14739        private static final int MAX_RETRIES = 4;
14740
14741        /**
14742         * Number of times startCopy() has been attempted and had a non-fatal
14743         * error.
14744         */
14745        private int mRetries = 0;
14746
14747        /** User handle for the user requesting the information or installation. */
14748        private final UserHandle mUser;
14749        String traceMethod;
14750        int traceCookie;
14751
14752        HandlerParams(UserHandle user) {
14753            mUser = user;
14754        }
14755
14756        UserHandle getUser() {
14757            return mUser;
14758        }
14759
14760        HandlerParams setTraceMethod(String traceMethod) {
14761            this.traceMethod = traceMethod;
14762            return this;
14763        }
14764
14765        HandlerParams setTraceCookie(int traceCookie) {
14766            this.traceCookie = traceCookie;
14767            return this;
14768        }
14769
14770        final boolean startCopy() {
14771            boolean res;
14772            try {
14773                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14774
14775                if (++mRetries > MAX_RETRIES) {
14776                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14777                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14778                    handleServiceError();
14779                    return false;
14780                } else {
14781                    handleStartCopy();
14782                    res = true;
14783                }
14784            } catch (RemoteException e) {
14785                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14786                mHandler.sendEmptyMessage(MCS_RECONNECT);
14787                res = false;
14788            }
14789            handleReturnCode();
14790            return res;
14791        }
14792
14793        final void serviceError() {
14794            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14795            handleServiceError();
14796            handleReturnCode();
14797        }
14798
14799        abstract void handleStartCopy() throws RemoteException;
14800        abstract void handleServiceError();
14801        abstract void handleReturnCode();
14802    }
14803
14804    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14805        for (File path : paths) {
14806            try {
14807                mcs.clearDirectory(path.getAbsolutePath());
14808            } catch (RemoteException e) {
14809            }
14810        }
14811    }
14812
14813    static class OriginInfo {
14814        /**
14815         * Location where install is coming from, before it has been
14816         * copied/renamed into place. This could be a single monolithic APK
14817         * file, or a cluster directory. This location may be untrusted.
14818         */
14819        final File file;
14820        final String cid;
14821
14822        /**
14823         * Flag indicating that {@link #file} or {@link #cid} has already been
14824         * staged, meaning downstream users don't need to defensively copy the
14825         * contents.
14826         */
14827        final boolean staged;
14828
14829        /**
14830         * Flag indicating that {@link #file} or {@link #cid} is an already
14831         * installed app that is being moved.
14832         */
14833        final boolean existing;
14834
14835        final String resolvedPath;
14836        final File resolvedFile;
14837
14838        static OriginInfo fromNothing() {
14839            return new OriginInfo(null, null, false, false);
14840        }
14841
14842        static OriginInfo fromUntrustedFile(File file) {
14843            return new OriginInfo(file, null, false, false);
14844        }
14845
14846        static OriginInfo fromExistingFile(File file) {
14847            return new OriginInfo(file, null, false, true);
14848        }
14849
14850        static OriginInfo fromStagedFile(File file) {
14851            return new OriginInfo(file, null, true, false);
14852        }
14853
14854        static OriginInfo fromStagedContainer(String cid) {
14855            return new OriginInfo(null, cid, true, false);
14856        }
14857
14858        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
14859            this.file = file;
14860            this.cid = cid;
14861            this.staged = staged;
14862            this.existing = existing;
14863
14864            if (cid != null) {
14865                resolvedPath = PackageHelper.getSdDir(cid);
14866                resolvedFile = new File(resolvedPath);
14867            } else if (file != null) {
14868                resolvedPath = file.getAbsolutePath();
14869                resolvedFile = file;
14870            } else {
14871                resolvedPath = null;
14872                resolvedFile = null;
14873            }
14874        }
14875    }
14876
14877    static class MoveInfo {
14878        final int moveId;
14879        final String fromUuid;
14880        final String toUuid;
14881        final String packageName;
14882        final String dataAppName;
14883        final int appId;
14884        final String seinfo;
14885        final int targetSdkVersion;
14886
14887        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14888                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14889            this.moveId = moveId;
14890            this.fromUuid = fromUuid;
14891            this.toUuid = toUuid;
14892            this.packageName = packageName;
14893            this.dataAppName = dataAppName;
14894            this.appId = appId;
14895            this.seinfo = seinfo;
14896            this.targetSdkVersion = targetSdkVersion;
14897        }
14898    }
14899
14900    static class VerificationInfo {
14901        /** A constant used to indicate that a uid value is not present. */
14902        public static final int NO_UID = -1;
14903
14904        /** URI referencing where the package was downloaded from. */
14905        final Uri originatingUri;
14906
14907        /** HTTP referrer URI associated with the originatingURI. */
14908        final Uri referrer;
14909
14910        /** UID of the application that the install request originated from. */
14911        final int originatingUid;
14912
14913        /** UID of application requesting the install */
14914        final int installerUid;
14915
14916        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14917            this.originatingUri = originatingUri;
14918            this.referrer = referrer;
14919            this.originatingUid = originatingUid;
14920            this.installerUid = installerUid;
14921        }
14922    }
14923
14924    class InstallParams extends HandlerParams {
14925        final OriginInfo origin;
14926        final MoveInfo move;
14927        final IPackageInstallObserver2 observer;
14928        int installFlags;
14929        final String installerPackageName;
14930        final String volumeUuid;
14931        private InstallArgs mArgs;
14932        private int mRet;
14933        final String packageAbiOverride;
14934        final String[] grantedRuntimePermissions;
14935        final VerificationInfo verificationInfo;
14936        final Certificate[][] certificates;
14937        final int installReason;
14938
14939        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14940                int installFlags, String installerPackageName, String volumeUuid,
14941                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14942                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14943            super(user);
14944            this.origin = origin;
14945            this.move = move;
14946            this.observer = observer;
14947            this.installFlags = installFlags;
14948            this.installerPackageName = installerPackageName;
14949            this.volumeUuid = volumeUuid;
14950            this.verificationInfo = verificationInfo;
14951            this.packageAbiOverride = packageAbiOverride;
14952            this.grantedRuntimePermissions = grantedPermissions;
14953            this.certificates = certificates;
14954            this.installReason = installReason;
14955        }
14956
14957        @Override
14958        public String toString() {
14959            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14960                    + " file=" + origin.file + " cid=" + origin.cid + "}";
14961        }
14962
14963        private int installLocationPolicy(PackageInfoLite pkgLite) {
14964            String packageName = pkgLite.packageName;
14965            int installLocation = pkgLite.installLocation;
14966            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14967            // reader
14968            synchronized (mPackages) {
14969                // Currently installed package which the new package is attempting to replace or
14970                // null if no such package is installed.
14971                PackageParser.Package installedPkg = mPackages.get(packageName);
14972                // Package which currently owns the data which the new package will own if installed.
14973                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14974                // will be null whereas dataOwnerPkg will contain information about the package
14975                // which was uninstalled while keeping its data.
14976                PackageParser.Package dataOwnerPkg = installedPkg;
14977                if (dataOwnerPkg  == null) {
14978                    PackageSetting ps = mSettings.mPackages.get(packageName);
14979                    if (ps != null) {
14980                        dataOwnerPkg = ps.pkg;
14981                    }
14982                }
14983
14984                if (dataOwnerPkg != null) {
14985                    // If installed, the package will get access to data left on the device by its
14986                    // predecessor. As a security measure, this is permited only if this is not a
14987                    // version downgrade or if the predecessor package is marked as debuggable and
14988                    // a downgrade is explicitly requested.
14989                    //
14990                    // On debuggable platform builds, downgrades are permitted even for
14991                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14992                    // not offer security guarantees and thus it's OK to disable some security
14993                    // mechanisms to make debugging/testing easier on those builds. However, even on
14994                    // debuggable builds downgrades of packages are permitted only if requested via
14995                    // installFlags. This is because we aim to keep the behavior of debuggable
14996                    // platform builds as close as possible to the behavior of non-debuggable
14997                    // platform builds.
14998                    final boolean downgradeRequested =
14999                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15000                    final boolean packageDebuggable =
15001                                (dataOwnerPkg.applicationInfo.flags
15002                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15003                    final boolean downgradePermitted =
15004                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15005                    if (!downgradePermitted) {
15006                        try {
15007                            checkDowngrade(dataOwnerPkg, pkgLite);
15008                        } catch (PackageManagerException e) {
15009                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15010                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15011                        }
15012                    }
15013                }
15014
15015                if (installedPkg != null) {
15016                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15017                        // Check for updated system application.
15018                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15019                            if (onSd) {
15020                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15021                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15022                            }
15023                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15024                        } else {
15025                            if (onSd) {
15026                                // Install flag overrides everything.
15027                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15028                            }
15029                            // If current upgrade specifies particular preference
15030                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15031                                // Application explicitly specified internal.
15032                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15033                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15034                                // App explictly prefers external. Let policy decide
15035                            } else {
15036                                // Prefer previous location
15037                                if (isExternal(installedPkg)) {
15038                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15039                                }
15040                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15041                            }
15042                        }
15043                    } else {
15044                        // Invalid install. Return error code
15045                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15046                    }
15047                }
15048            }
15049            // All the special cases have been taken care of.
15050            // Return result based on recommended install location.
15051            if (onSd) {
15052                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15053            }
15054            return pkgLite.recommendedInstallLocation;
15055        }
15056
15057        /*
15058         * Invoke remote method to get package information and install
15059         * location values. Override install location based on default
15060         * policy if needed and then create install arguments based
15061         * on the install location.
15062         */
15063        public void handleStartCopy() throws RemoteException {
15064            int ret = PackageManager.INSTALL_SUCCEEDED;
15065
15066            // If we're already staged, we've firmly committed to an install location
15067            if (origin.staged) {
15068                if (origin.file != null) {
15069                    installFlags |= PackageManager.INSTALL_INTERNAL;
15070                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15071                } else if (origin.cid != null) {
15072                    installFlags |= PackageManager.INSTALL_EXTERNAL;
15073                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
15074                } else {
15075                    throw new IllegalStateException("Invalid stage location");
15076                }
15077            }
15078
15079            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15080            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15081            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15082            PackageInfoLite pkgLite = null;
15083
15084            if (onInt && onSd) {
15085                // Check if both bits are set.
15086                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15087                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15088            } else if (onSd && ephemeral) {
15089                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15090                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15091            } else {
15092                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15093                        packageAbiOverride);
15094
15095                if (DEBUG_EPHEMERAL && ephemeral) {
15096                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15097                }
15098
15099                /*
15100                 * If we have too little free space, try to free cache
15101                 * before giving up.
15102                 */
15103                if (!origin.staged && pkgLite.recommendedInstallLocation
15104                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15105                    // TODO: focus freeing disk space on the target device
15106                    final StorageManager storage = StorageManager.from(mContext);
15107                    final long lowThreshold = storage.getStorageLowBytes(
15108                            Environment.getDataDirectory());
15109
15110                    final long sizeBytes = mContainerService.calculateInstalledSize(
15111                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
15112
15113                    try {
15114                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
15115                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15116                                installFlags, packageAbiOverride);
15117                    } catch (InstallerException e) {
15118                        Slog.w(TAG, "Failed to free cache", e);
15119                    }
15120
15121                    /*
15122                     * The cache free must have deleted the file we
15123                     * downloaded to install.
15124                     *
15125                     * TODO: fix the "freeCache" call to not delete
15126                     *       the file we care about.
15127                     */
15128                    if (pkgLite.recommendedInstallLocation
15129                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15130                        pkgLite.recommendedInstallLocation
15131                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15132                    }
15133                }
15134            }
15135
15136            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15137                int loc = pkgLite.recommendedInstallLocation;
15138                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15139                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15140                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15141                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15142                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15143                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15144                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15145                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15146                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15147                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15148                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15149                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15150                } else {
15151                    // Override with defaults if needed.
15152                    loc = installLocationPolicy(pkgLite);
15153                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15154                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15155                    } else if (!onSd && !onInt) {
15156                        // Override install location with flags
15157                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15158                            // Set the flag to install on external media.
15159                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15160                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15161                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15162                            if (DEBUG_EPHEMERAL) {
15163                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15164                            }
15165                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15166                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15167                                    |PackageManager.INSTALL_INTERNAL);
15168                        } else {
15169                            // Make sure the flag for installing on external
15170                            // media is unset
15171                            installFlags |= PackageManager.INSTALL_INTERNAL;
15172                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15173                        }
15174                    }
15175                }
15176            }
15177
15178            final InstallArgs args = createInstallArgs(this);
15179            mArgs = args;
15180
15181            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15182                // TODO: http://b/22976637
15183                // Apps installed for "all" users use the device owner to verify the app
15184                UserHandle verifierUser = getUser();
15185                if (verifierUser == UserHandle.ALL) {
15186                    verifierUser = UserHandle.SYSTEM;
15187                }
15188
15189                /*
15190                 * Determine if we have any installed package verifiers. If we
15191                 * do, then we'll defer to them to verify the packages.
15192                 */
15193                final int requiredUid = mRequiredVerifierPackage == null ? -1
15194                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15195                                verifierUser.getIdentifier());
15196                if (!origin.existing && requiredUid != -1
15197                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
15198                    final Intent verification = new Intent(
15199                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15200                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15201                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15202                            PACKAGE_MIME_TYPE);
15203                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15204
15205                    // Query all live verifiers based on current user state
15206                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15207                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
15208
15209                    if (DEBUG_VERIFY) {
15210                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15211                                + verification.toString() + " with " + pkgLite.verifiers.length
15212                                + " optional verifiers");
15213                    }
15214
15215                    final int verificationId = mPendingVerificationToken++;
15216
15217                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15218
15219                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15220                            installerPackageName);
15221
15222                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15223                            installFlags);
15224
15225                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15226                            pkgLite.packageName);
15227
15228                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15229                            pkgLite.versionCode);
15230
15231                    if (verificationInfo != null) {
15232                        if (verificationInfo.originatingUri != null) {
15233                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15234                                    verificationInfo.originatingUri);
15235                        }
15236                        if (verificationInfo.referrer != null) {
15237                            verification.putExtra(Intent.EXTRA_REFERRER,
15238                                    verificationInfo.referrer);
15239                        }
15240                        if (verificationInfo.originatingUid >= 0) {
15241                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15242                                    verificationInfo.originatingUid);
15243                        }
15244                        if (verificationInfo.installerUid >= 0) {
15245                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15246                                    verificationInfo.installerUid);
15247                        }
15248                    }
15249
15250                    final PackageVerificationState verificationState = new PackageVerificationState(
15251                            requiredUid, args);
15252
15253                    mPendingVerification.append(verificationId, verificationState);
15254
15255                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15256                            receivers, verificationState);
15257
15258                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15259                    final long idleDuration = getVerificationTimeout();
15260
15261                    /*
15262                     * If any sufficient verifiers were listed in the package
15263                     * manifest, attempt to ask them.
15264                     */
15265                    if (sufficientVerifiers != null) {
15266                        final int N = sufficientVerifiers.size();
15267                        if (N == 0) {
15268                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15269                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15270                        } else {
15271                            for (int i = 0; i < N; i++) {
15272                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15273                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15274                                        verifierComponent.getPackageName(), idleDuration,
15275                                        verifierUser.getIdentifier(), false, "package verifier");
15276
15277                                final Intent sufficientIntent = new Intent(verification);
15278                                sufficientIntent.setComponent(verifierComponent);
15279                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15280                            }
15281                        }
15282                    }
15283
15284                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15285                            mRequiredVerifierPackage, receivers);
15286                    if (ret == PackageManager.INSTALL_SUCCEEDED
15287                            && mRequiredVerifierPackage != null) {
15288                        Trace.asyncTraceBegin(
15289                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15290                        /*
15291                         * Send the intent to the required verification agent,
15292                         * but only start the verification timeout after the
15293                         * target BroadcastReceivers have run.
15294                         */
15295                        verification.setComponent(requiredVerifierComponent);
15296                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15297                                mRequiredVerifierPackage, idleDuration,
15298                                verifierUser.getIdentifier(), false, "package verifier");
15299                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15300                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15301                                new BroadcastReceiver() {
15302                                    @Override
15303                                    public void onReceive(Context context, Intent intent) {
15304                                        final Message msg = mHandler
15305                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15306                                        msg.arg1 = verificationId;
15307                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15308                                    }
15309                                }, null, 0, null, null);
15310
15311                        /*
15312                         * We don't want the copy to proceed until verification
15313                         * succeeds, so null out this field.
15314                         */
15315                        mArgs = null;
15316                    }
15317                } else {
15318                    /*
15319                     * No package verification is enabled, so immediately start
15320                     * the remote call to initiate copy using temporary file.
15321                     */
15322                    ret = args.copyApk(mContainerService, true);
15323                }
15324            }
15325
15326            mRet = ret;
15327        }
15328
15329        @Override
15330        void handleReturnCode() {
15331            // If mArgs is null, then MCS couldn't be reached. When it
15332            // reconnects, it will try again to install. At that point, this
15333            // will succeed.
15334            if (mArgs != null) {
15335                processPendingInstall(mArgs, mRet);
15336            }
15337        }
15338
15339        @Override
15340        void handleServiceError() {
15341            mArgs = createInstallArgs(this);
15342            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15343        }
15344
15345        public boolean isForwardLocked() {
15346            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15347        }
15348    }
15349
15350    /**
15351     * Used during creation of InstallArgs
15352     *
15353     * @param installFlags package installation flags
15354     * @return true if should be installed on external storage
15355     */
15356    private static boolean installOnExternalAsec(int installFlags) {
15357        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
15358            return false;
15359        }
15360        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15361            return true;
15362        }
15363        return false;
15364    }
15365
15366    /**
15367     * Used during creation of InstallArgs
15368     *
15369     * @param installFlags package installation flags
15370     * @return true if should be installed as forward locked
15371     */
15372    private static boolean installForwardLocked(int installFlags) {
15373        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15374    }
15375
15376    private InstallArgs createInstallArgs(InstallParams params) {
15377        if (params.move != null) {
15378            return new MoveInstallArgs(params);
15379        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15380            return new AsecInstallArgs(params);
15381        } else {
15382            return new FileInstallArgs(params);
15383        }
15384    }
15385
15386    /**
15387     * Create args that describe an existing installed package. Typically used
15388     * when cleaning up old installs, or used as a move source.
15389     */
15390    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15391            String resourcePath, String[] instructionSets) {
15392        final boolean isInAsec;
15393        if (installOnExternalAsec(installFlags)) {
15394            /* Apps on SD card are always in ASEC containers. */
15395            isInAsec = true;
15396        } else if (installForwardLocked(installFlags)
15397                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15398            /*
15399             * Forward-locked apps are only in ASEC containers if they're the
15400             * new style
15401             */
15402            isInAsec = true;
15403        } else {
15404            isInAsec = false;
15405        }
15406
15407        if (isInAsec) {
15408            return new AsecInstallArgs(codePath, instructionSets,
15409                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15410        } else {
15411            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15412        }
15413    }
15414
15415    static abstract class InstallArgs {
15416        /** @see InstallParams#origin */
15417        final OriginInfo origin;
15418        /** @see InstallParams#move */
15419        final MoveInfo move;
15420
15421        final IPackageInstallObserver2 observer;
15422        // Always refers to PackageManager flags only
15423        final int installFlags;
15424        final String installerPackageName;
15425        final String volumeUuid;
15426        final UserHandle user;
15427        final String abiOverride;
15428        final String[] installGrantPermissions;
15429        /** If non-null, drop an async trace when the install completes */
15430        final String traceMethod;
15431        final int traceCookie;
15432        final Certificate[][] certificates;
15433        final int installReason;
15434
15435        // The list of instruction sets supported by this app. This is currently
15436        // only used during the rmdex() phase to clean up resources. We can get rid of this
15437        // if we move dex files under the common app path.
15438        /* nullable */ String[] instructionSets;
15439
15440        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15441                int installFlags, String installerPackageName, String volumeUuid,
15442                UserHandle user, String[] instructionSets,
15443                String abiOverride, String[] installGrantPermissions,
15444                String traceMethod, int traceCookie, Certificate[][] certificates,
15445                int installReason) {
15446            this.origin = origin;
15447            this.move = move;
15448            this.installFlags = installFlags;
15449            this.observer = observer;
15450            this.installerPackageName = installerPackageName;
15451            this.volumeUuid = volumeUuid;
15452            this.user = user;
15453            this.instructionSets = instructionSets;
15454            this.abiOverride = abiOverride;
15455            this.installGrantPermissions = installGrantPermissions;
15456            this.traceMethod = traceMethod;
15457            this.traceCookie = traceCookie;
15458            this.certificates = certificates;
15459            this.installReason = installReason;
15460        }
15461
15462        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15463        abstract int doPreInstall(int status);
15464
15465        /**
15466         * Rename package into final resting place. All paths on the given
15467         * scanned package should be updated to reflect the rename.
15468         */
15469        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15470        abstract int doPostInstall(int status, int uid);
15471
15472        /** @see PackageSettingBase#codePathString */
15473        abstract String getCodePath();
15474        /** @see PackageSettingBase#resourcePathString */
15475        abstract String getResourcePath();
15476
15477        // Need installer lock especially for dex file removal.
15478        abstract void cleanUpResourcesLI();
15479        abstract boolean doPostDeleteLI(boolean delete);
15480
15481        /**
15482         * Called before the source arguments are copied. This is used mostly
15483         * for MoveParams when it needs to read the source file to put it in the
15484         * destination.
15485         */
15486        int doPreCopy() {
15487            return PackageManager.INSTALL_SUCCEEDED;
15488        }
15489
15490        /**
15491         * Called after the source arguments are copied. This is used mostly for
15492         * MoveParams when it needs to read the source file to put it in the
15493         * destination.
15494         */
15495        int doPostCopy(int uid) {
15496            return PackageManager.INSTALL_SUCCEEDED;
15497        }
15498
15499        protected boolean isFwdLocked() {
15500            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15501        }
15502
15503        protected boolean isExternalAsec() {
15504            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15505        }
15506
15507        protected boolean isEphemeral() {
15508            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15509        }
15510
15511        UserHandle getUser() {
15512            return user;
15513        }
15514    }
15515
15516    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15517        if (!allCodePaths.isEmpty()) {
15518            if (instructionSets == null) {
15519                throw new IllegalStateException("instructionSet == null");
15520            }
15521            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15522            for (String codePath : allCodePaths) {
15523                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15524                    try {
15525                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15526                    } catch (InstallerException ignored) {
15527                    }
15528                }
15529            }
15530        }
15531    }
15532
15533    /**
15534     * Logic to handle installation of non-ASEC applications, including copying
15535     * and renaming logic.
15536     */
15537    class FileInstallArgs extends InstallArgs {
15538        private File codeFile;
15539        private File resourceFile;
15540
15541        // Example topology:
15542        // /data/app/com.example/base.apk
15543        // /data/app/com.example/split_foo.apk
15544        // /data/app/com.example/lib/arm/libfoo.so
15545        // /data/app/com.example/lib/arm64/libfoo.so
15546        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15547
15548        /** New install */
15549        FileInstallArgs(InstallParams params) {
15550            super(params.origin, params.move, params.observer, params.installFlags,
15551                    params.installerPackageName, params.volumeUuid,
15552                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15553                    params.grantedRuntimePermissions,
15554                    params.traceMethod, params.traceCookie, params.certificates,
15555                    params.installReason);
15556            if (isFwdLocked()) {
15557                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15558            }
15559        }
15560
15561        /** Existing install */
15562        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15563            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15564                    null, null, null, 0, null /*certificates*/,
15565                    PackageManager.INSTALL_REASON_UNKNOWN);
15566            this.codeFile = (codePath != null) ? new File(codePath) : null;
15567            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15568        }
15569
15570        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15571            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15572            try {
15573                return doCopyApk(imcs, temp);
15574            } finally {
15575                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15576            }
15577        }
15578
15579        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15580            if (origin.staged) {
15581                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15582                codeFile = origin.file;
15583                resourceFile = origin.file;
15584                return PackageManager.INSTALL_SUCCEEDED;
15585            }
15586
15587            try {
15588                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15589                final File tempDir =
15590                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15591                codeFile = tempDir;
15592                resourceFile = tempDir;
15593            } catch (IOException e) {
15594                Slog.w(TAG, "Failed to create copy file: " + e);
15595                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15596            }
15597
15598            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15599                @Override
15600                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15601                    if (!FileUtils.isValidExtFilename(name)) {
15602                        throw new IllegalArgumentException("Invalid filename: " + name);
15603                    }
15604                    try {
15605                        final File file = new File(codeFile, name);
15606                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15607                                O_RDWR | O_CREAT, 0644);
15608                        Os.chmod(file.getAbsolutePath(), 0644);
15609                        return new ParcelFileDescriptor(fd);
15610                    } catch (ErrnoException e) {
15611                        throw new RemoteException("Failed to open: " + e.getMessage());
15612                    }
15613                }
15614            };
15615
15616            int ret = PackageManager.INSTALL_SUCCEEDED;
15617            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15618            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15619                Slog.e(TAG, "Failed to copy package");
15620                return ret;
15621            }
15622
15623            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15624            NativeLibraryHelper.Handle handle = null;
15625            try {
15626                handle = NativeLibraryHelper.Handle.create(codeFile);
15627                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15628                        abiOverride);
15629            } catch (IOException e) {
15630                Slog.e(TAG, "Copying native libraries failed", e);
15631                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15632            } finally {
15633                IoUtils.closeQuietly(handle);
15634            }
15635
15636            return ret;
15637        }
15638
15639        int doPreInstall(int status) {
15640            if (status != PackageManager.INSTALL_SUCCEEDED) {
15641                cleanUp();
15642            }
15643            return status;
15644        }
15645
15646        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15647            if (status != PackageManager.INSTALL_SUCCEEDED) {
15648                cleanUp();
15649                return false;
15650            }
15651
15652            final File targetDir = codeFile.getParentFile();
15653            final File beforeCodeFile = codeFile;
15654            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15655
15656            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15657            try {
15658                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15659            } catch (ErrnoException e) {
15660                Slog.w(TAG, "Failed to rename", e);
15661                return false;
15662            }
15663
15664            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15665                Slog.w(TAG, "Failed to restorecon");
15666                return false;
15667            }
15668
15669            // Reflect the rename internally
15670            codeFile = afterCodeFile;
15671            resourceFile = afterCodeFile;
15672
15673            // Reflect the rename in scanned details
15674            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15675            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15676                    afterCodeFile, pkg.baseCodePath));
15677            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15678                    afterCodeFile, pkg.splitCodePaths));
15679
15680            // Reflect the rename in app info
15681            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15682            pkg.setApplicationInfoCodePath(pkg.codePath);
15683            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15684            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15685            pkg.setApplicationInfoResourcePath(pkg.codePath);
15686            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15687            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15688
15689            return true;
15690        }
15691
15692        int doPostInstall(int status, int uid) {
15693            if (status != PackageManager.INSTALL_SUCCEEDED) {
15694                cleanUp();
15695            }
15696            return status;
15697        }
15698
15699        @Override
15700        String getCodePath() {
15701            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15702        }
15703
15704        @Override
15705        String getResourcePath() {
15706            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15707        }
15708
15709        private boolean cleanUp() {
15710            if (codeFile == null || !codeFile.exists()) {
15711                return false;
15712            }
15713
15714            removeCodePathLI(codeFile);
15715
15716            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15717                resourceFile.delete();
15718            }
15719
15720            return true;
15721        }
15722
15723        void cleanUpResourcesLI() {
15724            // Try enumerating all code paths before deleting
15725            List<String> allCodePaths = Collections.EMPTY_LIST;
15726            if (codeFile != null && codeFile.exists()) {
15727                try {
15728                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15729                    allCodePaths = pkg.getAllCodePaths();
15730                } catch (PackageParserException e) {
15731                    // Ignored; we tried our best
15732                }
15733            }
15734
15735            cleanUp();
15736            removeDexFiles(allCodePaths, instructionSets);
15737        }
15738
15739        boolean doPostDeleteLI(boolean delete) {
15740            // XXX err, shouldn't we respect the delete flag?
15741            cleanUpResourcesLI();
15742            return true;
15743        }
15744    }
15745
15746    private boolean isAsecExternal(String cid) {
15747        final String asecPath = PackageHelper.getSdFilesystem(cid);
15748        return !asecPath.startsWith(mAsecInternalPath);
15749    }
15750
15751    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15752            PackageManagerException {
15753        if (copyRet < 0) {
15754            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15755                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15756                throw new PackageManagerException(copyRet, message);
15757            }
15758        }
15759    }
15760
15761    /**
15762     * Extract the StorageManagerService "container ID" from the full code path of an
15763     * .apk.
15764     */
15765    static String cidFromCodePath(String fullCodePath) {
15766        int eidx = fullCodePath.lastIndexOf("/");
15767        String subStr1 = fullCodePath.substring(0, eidx);
15768        int sidx = subStr1.lastIndexOf("/");
15769        return subStr1.substring(sidx+1, eidx);
15770    }
15771
15772    /**
15773     * Logic to handle installation of ASEC applications, including copying and
15774     * renaming logic.
15775     */
15776    class AsecInstallArgs extends InstallArgs {
15777        static final String RES_FILE_NAME = "pkg.apk";
15778        static final String PUBLIC_RES_FILE_NAME = "res.zip";
15779
15780        String cid;
15781        String packagePath;
15782        String resourcePath;
15783
15784        /** New install */
15785        AsecInstallArgs(InstallParams params) {
15786            super(params.origin, params.move, params.observer, params.installFlags,
15787                    params.installerPackageName, params.volumeUuid,
15788                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15789                    params.grantedRuntimePermissions,
15790                    params.traceMethod, params.traceCookie, params.certificates,
15791                    params.installReason);
15792        }
15793
15794        /** Existing install */
15795        AsecInstallArgs(String fullCodePath, String[] instructionSets,
15796                        boolean isExternal, boolean isForwardLocked) {
15797            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
15798                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15799                    instructionSets, null, null, null, 0, null /*certificates*/,
15800                    PackageManager.INSTALL_REASON_UNKNOWN);
15801            // Hackily pretend we're still looking at a full code path
15802            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
15803                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
15804            }
15805
15806            // Extract cid from fullCodePath
15807            int eidx = fullCodePath.lastIndexOf("/");
15808            String subStr1 = fullCodePath.substring(0, eidx);
15809            int sidx = subStr1.lastIndexOf("/");
15810            cid = subStr1.substring(sidx+1, eidx);
15811            setMountPath(subStr1);
15812        }
15813
15814        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
15815            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
15816                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
15817                    instructionSets, null, null, null, 0, null /*certificates*/,
15818                    PackageManager.INSTALL_REASON_UNKNOWN);
15819            this.cid = cid;
15820            setMountPath(PackageHelper.getSdDir(cid));
15821        }
15822
15823        void createCopyFile() {
15824            cid = mInstallerService.allocateExternalStageCidLegacy();
15825        }
15826
15827        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15828            if (origin.staged && origin.cid != null) {
15829                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
15830                cid = origin.cid;
15831                setMountPath(PackageHelper.getSdDir(cid));
15832                return PackageManager.INSTALL_SUCCEEDED;
15833            }
15834
15835            if (temp) {
15836                createCopyFile();
15837            } else {
15838                /*
15839                 * Pre-emptively destroy the container since it's destroyed if
15840                 * copying fails due to it existing anyway.
15841                 */
15842                PackageHelper.destroySdDir(cid);
15843            }
15844
15845            final String newMountPath = imcs.copyPackageToContainer(
15846                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
15847                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
15848
15849            if (newMountPath != null) {
15850                setMountPath(newMountPath);
15851                return PackageManager.INSTALL_SUCCEEDED;
15852            } else {
15853                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15854            }
15855        }
15856
15857        @Override
15858        String getCodePath() {
15859            return packagePath;
15860        }
15861
15862        @Override
15863        String getResourcePath() {
15864            return resourcePath;
15865        }
15866
15867        int doPreInstall(int status) {
15868            if (status != PackageManager.INSTALL_SUCCEEDED) {
15869                // Destroy container
15870                PackageHelper.destroySdDir(cid);
15871            } else {
15872                boolean mounted = PackageHelper.isContainerMounted(cid);
15873                if (!mounted) {
15874                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
15875                            Process.SYSTEM_UID);
15876                    if (newMountPath != null) {
15877                        setMountPath(newMountPath);
15878                    } else {
15879                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15880                    }
15881                }
15882            }
15883            return status;
15884        }
15885
15886        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15887            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
15888            String newMountPath = null;
15889            if (PackageHelper.isContainerMounted(cid)) {
15890                // Unmount the container
15891                if (!PackageHelper.unMountSdDir(cid)) {
15892                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
15893                    return false;
15894                }
15895            }
15896            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15897                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
15898                        " which might be stale. Will try to clean up.");
15899                // Clean up the stale container and proceed to recreate.
15900                if (!PackageHelper.destroySdDir(newCacheId)) {
15901                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
15902                    return false;
15903                }
15904                // Successfully cleaned up stale container. Try to rename again.
15905                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
15906                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
15907                            + " inspite of cleaning it up.");
15908                    return false;
15909                }
15910            }
15911            if (!PackageHelper.isContainerMounted(newCacheId)) {
15912                Slog.w(TAG, "Mounting container " + newCacheId);
15913                newMountPath = PackageHelper.mountSdDir(newCacheId,
15914                        getEncryptKey(), Process.SYSTEM_UID);
15915            } else {
15916                newMountPath = PackageHelper.getSdDir(newCacheId);
15917            }
15918            if (newMountPath == null) {
15919                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
15920                return false;
15921            }
15922            Log.i(TAG, "Succesfully renamed " + cid +
15923                    " to " + newCacheId +
15924                    " at new path: " + newMountPath);
15925            cid = newCacheId;
15926
15927            final File beforeCodeFile = new File(packagePath);
15928            setMountPath(newMountPath);
15929            final File afterCodeFile = new File(packagePath);
15930
15931            // Reflect the rename in scanned details
15932            pkg.setCodePath(afterCodeFile.getAbsolutePath());
15933            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15934                    afterCodeFile, pkg.baseCodePath));
15935            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15936                    afterCodeFile, pkg.splitCodePaths));
15937
15938            // Reflect the rename in app info
15939            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15940            pkg.setApplicationInfoCodePath(pkg.codePath);
15941            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15942            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15943            pkg.setApplicationInfoResourcePath(pkg.codePath);
15944            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15945            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15946
15947            return true;
15948        }
15949
15950        private void setMountPath(String mountPath) {
15951            final File mountFile = new File(mountPath);
15952
15953            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
15954            if (monolithicFile.exists()) {
15955                packagePath = monolithicFile.getAbsolutePath();
15956                if (isFwdLocked()) {
15957                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
15958                } else {
15959                    resourcePath = packagePath;
15960                }
15961            } else {
15962                packagePath = mountFile.getAbsolutePath();
15963                resourcePath = packagePath;
15964            }
15965        }
15966
15967        int doPostInstall(int status, int uid) {
15968            if (status != PackageManager.INSTALL_SUCCEEDED) {
15969                cleanUp();
15970            } else {
15971                final int groupOwner;
15972                final String protectedFile;
15973                if (isFwdLocked()) {
15974                    groupOwner = UserHandle.getSharedAppGid(uid);
15975                    protectedFile = RES_FILE_NAME;
15976                } else {
15977                    groupOwner = -1;
15978                    protectedFile = null;
15979                }
15980
15981                if (uid < Process.FIRST_APPLICATION_UID
15982                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
15983                    Slog.e(TAG, "Failed to finalize " + cid);
15984                    PackageHelper.destroySdDir(cid);
15985                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
15986                }
15987
15988                boolean mounted = PackageHelper.isContainerMounted(cid);
15989                if (!mounted) {
15990                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
15991                }
15992            }
15993            return status;
15994        }
15995
15996        private void cleanUp() {
15997            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
15998
15999            // Destroy secure container
16000            PackageHelper.destroySdDir(cid);
16001        }
16002
16003        private List<String> getAllCodePaths() {
16004            final File codeFile = new File(getCodePath());
16005            if (codeFile != null && codeFile.exists()) {
16006                try {
16007                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16008                    return pkg.getAllCodePaths();
16009                } catch (PackageParserException e) {
16010                    // Ignored; we tried our best
16011                }
16012            }
16013            return Collections.EMPTY_LIST;
16014        }
16015
16016        void cleanUpResourcesLI() {
16017            // Enumerate all code paths before deleting
16018            cleanUpResourcesLI(getAllCodePaths());
16019        }
16020
16021        private void cleanUpResourcesLI(List<String> allCodePaths) {
16022            cleanUp();
16023            removeDexFiles(allCodePaths, instructionSets);
16024        }
16025
16026        String getPackageName() {
16027            return getAsecPackageName(cid);
16028        }
16029
16030        boolean doPostDeleteLI(boolean delete) {
16031            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
16032            final List<String> allCodePaths = getAllCodePaths();
16033            boolean mounted = PackageHelper.isContainerMounted(cid);
16034            if (mounted) {
16035                // Unmount first
16036                if (PackageHelper.unMountSdDir(cid)) {
16037                    mounted = false;
16038                }
16039            }
16040            if (!mounted && delete) {
16041                cleanUpResourcesLI(allCodePaths);
16042            }
16043            return !mounted;
16044        }
16045
16046        @Override
16047        int doPreCopy() {
16048            if (isFwdLocked()) {
16049                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
16050                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
16051                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16052                }
16053            }
16054
16055            return PackageManager.INSTALL_SUCCEEDED;
16056        }
16057
16058        @Override
16059        int doPostCopy(int uid) {
16060            if (isFwdLocked()) {
16061                if (uid < Process.FIRST_APPLICATION_UID
16062                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
16063                                RES_FILE_NAME)) {
16064                    Slog.e(TAG, "Failed to finalize " + cid);
16065                    PackageHelper.destroySdDir(cid);
16066                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16067                }
16068            }
16069
16070            return PackageManager.INSTALL_SUCCEEDED;
16071        }
16072    }
16073
16074    /**
16075     * Logic to handle movement of existing installed applications.
16076     */
16077    class MoveInstallArgs extends InstallArgs {
16078        private File codeFile;
16079        private File resourceFile;
16080
16081        /** New install */
16082        MoveInstallArgs(InstallParams params) {
16083            super(params.origin, params.move, params.observer, params.installFlags,
16084                    params.installerPackageName, params.volumeUuid,
16085                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16086                    params.grantedRuntimePermissions,
16087                    params.traceMethod, params.traceCookie, params.certificates,
16088                    params.installReason);
16089        }
16090
16091        int copyApk(IMediaContainerService imcs, boolean temp) {
16092            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16093                    + move.fromUuid + " to " + move.toUuid);
16094            synchronized (mInstaller) {
16095                try {
16096                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16097                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16098                } catch (InstallerException e) {
16099                    Slog.w(TAG, "Failed to move app", e);
16100                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16101                }
16102            }
16103
16104            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16105            resourceFile = codeFile;
16106            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16107
16108            return PackageManager.INSTALL_SUCCEEDED;
16109        }
16110
16111        int doPreInstall(int status) {
16112            if (status != PackageManager.INSTALL_SUCCEEDED) {
16113                cleanUp(move.toUuid);
16114            }
16115            return status;
16116        }
16117
16118        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16119            if (status != PackageManager.INSTALL_SUCCEEDED) {
16120                cleanUp(move.toUuid);
16121                return false;
16122            }
16123
16124            // Reflect the move in app info
16125            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16126            pkg.setApplicationInfoCodePath(pkg.codePath);
16127            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16128            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16129            pkg.setApplicationInfoResourcePath(pkg.codePath);
16130            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16131            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16132
16133            return true;
16134        }
16135
16136        int doPostInstall(int status, int uid) {
16137            if (status == PackageManager.INSTALL_SUCCEEDED) {
16138                cleanUp(move.fromUuid);
16139            } else {
16140                cleanUp(move.toUuid);
16141            }
16142            return status;
16143        }
16144
16145        @Override
16146        String getCodePath() {
16147            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16148        }
16149
16150        @Override
16151        String getResourcePath() {
16152            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16153        }
16154
16155        private boolean cleanUp(String volumeUuid) {
16156            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16157                    move.dataAppName);
16158            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16159            final int[] userIds = sUserManager.getUserIds();
16160            synchronized (mInstallLock) {
16161                // Clean up both app data and code
16162                // All package moves are frozen until finished
16163                for (int userId : userIds) {
16164                    try {
16165                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16166                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16167                    } catch (InstallerException e) {
16168                        Slog.w(TAG, String.valueOf(e));
16169                    }
16170                }
16171                removeCodePathLI(codeFile);
16172            }
16173            return true;
16174        }
16175
16176        void cleanUpResourcesLI() {
16177            throw new UnsupportedOperationException();
16178        }
16179
16180        boolean doPostDeleteLI(boolean delete) {
16181            throw new UnsupportedOperationException();
16182        }
16183    }
16184
16185    static String getAsecPackageName(String packageCid) {
16186        int idx = packageCid.lastIndexOf("-");
16187        if (idx == -1) {
16188            return packageCid;
16189        }
16190        return packageCid.substring(0, idx);
16191    }
16192
16193    // Utility method used to create code paths based on package name and available index.
16194    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16195        String idxStr = "";
16196        int idx = 1;
16197        // Fall back to default value of idx=1 if prefix is not
16198        // part of oldCodePath
16199        if (oldCodePath != null) {
16200            String subStr = oldCodePath;
16201            // Drop the suffix right away
16202            if (suffix != null && subStr.endsWith(suffix)) {
16203                subStr = subStr.substring(0, subStr.length() - suffix.length());
16204            }
16205            // If oldCodePath already contains prefix find out the
16206            // ending index to either increment or decrement.
16207            int sidx = subStr.lastIndexOf(prefix);
16208            if (sidx != -1) {
16209                subStr = subStr.substring(sidx + prefix.length());
16210                if (subStr != null) {
16211                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16212                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16213                    }
16214                    try {
16215                        idx = Integer.parseInt(subStr);
16216                        if (idx <= 1) {
16217                            idx++;
16218                        } else {
16219                            idx--;
16220                        }
16221                    } catch(NumberFormatException e) {
16222                    }
16223                }
16224            }
16225        }
16226        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16227        return prefix + idxStr;
16228    }
16229
16230    private File getNextCodePath(File targetDir, String packageName) {
16231        File result;
16232        SecureRandom random = new SecureRandom();
16233        byte[] bytes = new byte[16];
16234        do {
16235            random.nextBytes(bytes);
16236            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16237            result = new File(targetDir, packageName + "-" + suffix);
16238        } while (result.exists());
16239        return result;
16240    }
16241
16242    // Utility method that returns the relative package path with respect
16243    // to the installation directory. Like say for /data/data/com.test-1.apk
16244    // string com.test-1 is returned.
16245    static String deriveCodePathName(String codePath) {
16246        if (codePath == null) {
16247            return null;
16248        }
16249        final File codeFile = new File(codePath);
16250        final String name = codeFile.getName();
16251        if (codeFile.isDirectory()) {
16252            return name;
16253        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16254            final int lastDot = name.lastIndexOf('.');
16255            return name.substring(0, lastDot);
16256        } else {
16257            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16258            return null;
16259        }
16260    }
16261
16262    static class PackageInstalledInfo {
16263        String name;
16264        int uid;
16265        // The set of users that originally had this package installed.
16266        int[] origUsers;
16267        // The set of users that now have this package installed.
16268        int[] newUsers;
16269        PackageParser.Package pkg;
16270        int returnCode;
16271        String returnMsg;
16272        PackageRemovedInfo removedInfo;
16273        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16274
16275        public void setError(int code, String msg) {
16276            setReturnCode(code);
16277            setReturnMessage(msg);
16278            Slog.w(TAG, msg);
16279        }
16280
16281        public void setError(String msg, PackageParserException e) {
16282            setReturnCode(e.error);
16283            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16284            Slog.w(TAG, msg, e);
16285        }
16286
16287        public void setError(String msg, PackageManagerException e) {
16288            returnCode = e.error;
16289            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16290            Slog.w(TAG, msg, e);
16291        }
16292
16293        public void setReturnCode(int returnCode) {
16294            this.returnCode = returnCode;
16295            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16296            for (int i = 0; i < childCount; i++) {
16297                addedChildPackages.valueAt(i).returnCode = returnCode;
16298            }
16299        }
16300
16301        private void setReturnMessage(String returnMsg) {
16302            this.returnMsg = returnMsg;
16303            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16304            for (int i = 0; i < childCount; i++) {
16305                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16306            }
16307        }
16308
16309        // In some error cases we want to convey more info back to the observer
16310        String origPackage;
16311        String origPermission;
16312    }
16313
16314    /*
16315     * Install a non-existing package.
16316     */
16317    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16318            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16319            PackageInstalledInfo res, int installReason) {
16320        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16321
16322        // Remember this for later, in case we need to rollback this install
16323        String pkgName = pkg.packageName;
16324
16325        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16326
16327        synchronized(mPackages) {
16328            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16329            if (renamedPackage != null) {
16330                // A package with the same name is already installed, though
16331                // it has been renamed to an older name.  The package we
16332                // are trying to install should be installed as an update to
16333                // the existing one, but that has not been requested, so bail.
16334                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16335                        + " without first uninstalling package running as "
16336                        + renamedPackage);
16337                return;
16338            }
16339            if (mPackages.containsKey(pkgName)) {
16340                // Don't allow installation over an existing package with the same name.
16341                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16342                        + " without first uninstalling.");
16343                return;
16344            }
16345        }
16346
16347        try {
16348            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
16349                    System.currentTimeMillis(), user);
16350
16351            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16352
16353            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16354                prepareAppDataAfterInstallLIF(newPackage);
16355
16356            } else {
16357                // Remove package from internal structures, but keep around any
16358                // data that might have already existed
16359                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16360                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16361            }
16362        } catch (PackageManagerException e) {
16363            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16364        }
16365
16366        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16367    }
16368
16369    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16370        // Can't rotate keys during boot or if sharedUser.
16371        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16372                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16373            return false;
16374        }
16375        // app is using upgradeKeySets; make sure all are valid
16376        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16377        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16378        for (int i = 0; i < upgradeKeySets.length; i++) {
16379            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16380                Slog.wtf(TAG, "Package "
16381                         + (oldPs.name != null ? oldPs.name : "<null>")
16382                         + " contains upgrade-key-set reference to unknown key-set: "
16383                         + upgradeKeySets[i]
16384                         + " reverting to signatures check.");
16385                return false;
16386            }
16387        }
16388        return true;
16389    }
16390
16391    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16392        // Upgrade keysets are being used.  Determine if new package has a superset of the
16393        // required keys.
16394        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16395        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16396        for (int i = 0; i < upgradeKeySets.length; i++) {
16397            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16398            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16399                return true;
16400            }
16401        }
16402        return false;
16403    }
16404
16405    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16406        try (DigestInputStream digestStream =
16407                new DigestInputStream(new FileInputStream(file), digest)) {
16408            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16409        }
16410    }
16411
16412    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16413            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16414            int installReason) {
16415        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16416
16417        final PackageParser.Package oldPackage;
16418        final PackageSetting ps;
16419        final String pkgName = pkg.packageName;
16420        final int[] allUsers;
16421        final int[] installedUsers;
16422
16423        synchronized(mPackages) {
16424            oldPackage = mPackages.get(pkgName);
16425            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16426
16427            // don't allow upgrade to target a release SDK from a pre-release SDK
16428            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16429                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16430            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16431                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16432            if (oldTargetsPreRelease
16433                    && !newTargetsPreRelease
16434                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16435                Slog.w(TAG, "Can't install package targeting released sdk");
16436                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16437                return;
16438            }
16439
16440            ps = mSettings.mPackages.get(pkgName);
16441
16442            // verify signatures are valid
16443            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16444                if (!checkUpgradeKeySetLP(ps, pkg)) {
16445                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16446                            "New package not signed by keys specified by upgrade-keysets: "
16447                                    + pkgName);
16448                    return;
16449                }
16450            } else {
16451                // default to original signature matching
16452                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16453                        != PackageManager.SIGNATURE_MATCH) {
16454                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16455                            "New package has a different signature: " + pkgName);
16456                    return;
16457                }
16458            }
16459
16460            // don't allow a system upgrade unless the upgrade hash matches
16461            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16462                byte[] digestBytes = null;
16463                try {
16464                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16465                    updateDigest(digest, new File(pkg.baseCodePath));
16466                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16467                        for (String path : pkg.splitCodePaths) {
16468                            updateDigest(digest, new File(path));
16469                        }
16470                    }
16471                    digestBytes = digest.digest();
16472                } catch (NoSuchAlgorithmException | IOException e) {
16473                    res.setError(INSTALL_FAILED_INVALID_APK,
16474                            "Could not compute hash: " + pkgName);
16475                    return;
16476                }
16477                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16478                    res.setError(INSTALL_FAILED_INVALID_APK,
16479                            "New package fails restrict-update check: " + pkgName);
16480                    return;
16481                }
16482                // retain upgrade restriction
16483                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16484            }
16485
16486            // Check for shared user id changes
16487            String invalidPackageName =
16488                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16489            if (invalidPackageName != null) {
16490                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16491                        "Package " + invalidPackageName + " tried to change user "
16492                                + oldPackage.mSharedUserId);
16493                return;
16494            }
16495
16496            // In case of rollback, remember per-user/profile install state
16497            allUsers = sUserManager.getUserIds();
16498            installedUsers = ps.queryInstalledUsers(allUsers, true);
16499
16500            // don't allow an upgrade from full to ephemeral
16501            if (isInstantApp) {
16502                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16503                    for (int currentUser : allUsers) {
16504                        if (!ps.getInstantApp(currentUser)) {
16505                            // can't downgrade from full to instant
16506                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16507                                    + " for user: " + currentUser);
16508                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16509                            return;
16510                        }
16511                    }
16512                } else if (!ps.getInstantApp(user.getIdentifier())) {
16513                    // can't downgrade from full to instant
16514                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16515                            + " for user: " + user.getIdentifier());
16516                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16517                    return;
16518                }
16519            }
16520        }
16521
16522        // Update what is removed
16523        res.removedInfo = new PackageRemovedInfo(this);
16524        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16525        res.removedInfo.removedPackage = oldPackage.packageName;
16526        res.removedInfo.installerPackageName = ps.installerPackageName;
16527        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16528        res.removedInfo.isUpdate = true;
16529        res.removedInfo.origUsers = installedUsers;
16530        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16531        for (int i = 0; i < installedUsers.length; i++) {
16532            final int userId = installedUsers[i];
16533            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16534        }
16535
16536        final int childCount = (oldPackage.childPackages != null)
16537                ? oldPackage.childPackages.size() : 0;
16538        for (int i = 0; i < childCount; i++) {
16539            boolean childPackageUpdated = false;
16540            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16541            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16542            if (res.addedChildPackages != null) {
16543                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16544                if (childRes != null) {
16545                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16546                    childRes.removedInfo.removedPackage = childPkg.packageName;
16547                    if (childPs != null) {
16548                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16549                    }
16550                    childRes.removedInfo.isUpdate = true;
16551                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16552                    childPackageUpdated = true;
16553                }
16554            }
16555            if (!childPackageUpdated) {
16556                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16557                childRemovedRes.removedPackage = childPkg.packageName;
16558                if (childPs != null) {
16559                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16560                }
16561                childRemovedRes.isUpdate = false;
16562                childRemovedRes.dataRemoved = true;
16563                synchronized (mPackages) {
16564                    if (childPs != null) {
16565                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16566                    }
16567                }
16568                if (res.removedInfo.removedChildPackages == null) {
16569                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16570                }
16571                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16572            }
16573        }
16574
16575        boolean sysPkg = (isSystemApp(oldPackage));
16576        if (sysPkg) {
16577            // Set the system/privileged flags as needed
16578            final boolean privileged =
16579                    (oldPackage.applicationInfo.privateFlags
16580                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16581            final int systemPolicyFlags = policyFlags
16582                    | PackageParser.PARSE_IS_SYSTEM
16583                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16584
16585            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16586                    user, allUsers, installerPackageName, res, installReason);
16587        } else {
16588            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16589                    user, allUsers, installerPackageName, res, installReason);
16590        }
16591    }
16592
16593    public List<String> getPreviousCodePaths(String packageName) {
16594        final PackageSetting ps = mSettings.mPackages.get(packageName);
16595        final List<String> result = new ArrayList<String>();
16596        if (ps != null && ps.oldCodePaths != null) {
16597            result.addAll(ps.oldCodePaths);
16598        }
16599        return result;
16600    }
16601
16602    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16603            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16604            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16605            int installReason) {
16606        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16607                + deletedPackage);
16608
16609        String pkgName = deletedPackage.packageName;
16610        boolean deletedPkg = true;
16611        boolean addedPkg = false;
16612        boolean updatedSettings = false;
16613        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16614        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16615                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16616
16617        final long origUpdateTime = (pkg.mExtras != null)
16618                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16619
16620        // First delete the existing package while retaining the data directory
16621        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16622                res.removedInfo, true, pkg)) {
16623            // If the existing package wasn't successfully deleted
16624            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16625            deletedPkg = false;
16626        } else {
16627            // Successfully deleted the old package; proceed with replace.
16628
16629            // If deleted package lived in a container, give users a chance to
16630            // relinquish resources before killing.
16631            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16632                if (DEBUG_INSTALL) {
16633                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16634                }
16635                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16636                final ArrayList<String> pkgList = new ArrayList<String>(1);
16637                pkgList.add(deletedPackage.applicationInfo.packageName);
16638                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16639            }
16640
16641            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16642                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16643            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16644
16645            try {
16646                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
16647                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16648                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16649                        installReason);
16650
16651                // Update the in-memory copy of the previous code paths.
16652                PackageSetting ps = mSettings.mPackages.get(pkgName);
16653                if (!killApp) {
16654                    if (ps.oldCodePaths == null) {
16655                        ps.oldCodePaths = new ArraySet<>();
16656                    }
16657                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16658                    if (deletedPackage.splitCodePaths != null) {
16659                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16660                    }
16661                } else {
16662                    ps.oldCodePaths = null;
16663                }
16664                if (ps.childPackageNames != null) {
16665                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16666                        final String childPkgName = ps.childPackageNames.get(i);
16667                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16668                        childPs.oldCodePaths = ps.oldCodePaths;
16669                    }
16670                }
16671                // set instant app status, but, only if it's explicitly specified
16672                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16673                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16674                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16675                prepareAppDataAfterInstallLIF(newPackage);
16676                addedPkg = true;
16677                mDexManager.notifyPackageUpdated(newPackage.packageName,
16678                        newPackage.baseCodePath, newPackage.splitCodePaths);
16679            } catch (PackageManagerException e) {
16680                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16681            }
16682        }
16683
16684        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16685            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16686
16687            // Revert all internal state mutations and added folders for the failed install
16688            if (addedPkg) {
16689                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16690                        res.removedInfo, true, null);
16691            }
16692
16693            // Restore the old package
16694            if (deletedPkg) {
16695                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16696                File restoreFile = new File(deletedPackage.codePath);
16697                // Parse old package
16698                boolean oldExternal = isExternal(deletedPackage);
16699                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16700                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16701                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16702                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16703                try {
16704                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16705                            null);
16706                } catch (PackageManagerException e) {
16707                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16708                            + e.getMessage());
16709                    return;
16710                }
16711
16712                synchronized (mPackages) {
16713                    // Ensure the installer package name up to date
16714                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16715
16716                    // Update permissions for restored package
16717                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16718
16719                    mSettings.writeLPr();
16720                }
16721
16722                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16723            }
16724        } else {
16725            synchronized (mPackages) {
16726                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16727                if (ps != null) {
16728                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16729                    if (res.removedInfo.removedChildPackages != null) {
16730                        final int childCount = res.removedInfo.removedChildPackages.size();
16731                        // Iterate in reverse as we may modify the collection
16732                        for (int i = childCount - 1; i >= 0; i--) {
16733                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16734                            if (res.addedChildPackages.containsKey(childPackageName)) {
16735                                res.removedInfo.removedChildPackages.removeAt(i);
16736                            } else {
16737                                PackageRemovedInfo childInfo = res.removedInfo
16738                                        .removedChildPackages.valueAt(i);
16739                                childInfo.removedForAllUsers = mPackages.get(
16740                                        childInfo.removedPackage) == null;
16741                            }
16742                        }
16743                    }
16744                }
16745            }
16746        }
16747    }
16748
16749    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16750            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16751            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16752            int installReason) {
16753        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16754                + ", old=" + deletedPackage);
16755
16756        final boolean disabledSystem;
16757
16758        // Remove existing system package
16759        removePackageLI(deletedPackage, true);
16760
16761        synchronized (mPackages) {
16762            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16763        }
16764        if (!disabledSystem) {
16765            // We didn't need to disable the .apk as a current system package,
16766            // which means we are replacing another update that is already
16767            // installed.  We need to make sure to delete the older one's .apk.
16768            res.removedInfo.args = createInstallArgsForExisting(0,
16769                    deletedPackage.applicationInfo.getCodePath(),
16770                    deletedPackage.applicationInfo.getResourcePath(),
16771                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16772        } else {
16773            res.removedInfo.args = null;
16774        }
16775
16776        // Successfully disabled the old package. Now proceed with re-installation
16777        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16778                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16779        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
16780
16781        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16782        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16783                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16784
16785        PackageParser.Package newPackage = null;
16786        try {
16787            // Add the package to the internal data structures
16788            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
16789
16790            // Set the update and install times
16791            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16792            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16793                    System.currentTimeMillis());
16794
16795            // Update the package dynamic state if succeeded
16796            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16797                // Now that the install succeeded make sure we remove data
16798                // directories for any child package the update removed.
16799                final int deletedChildCount = (deletedPackage.childPackages != null)
16800                        ? deletedPackage.childPackages.size() : 0;
16801                final int newChildCount = (newPackage.childPackages != null)
16802                        ? newPackage.childPackages.size() : 0;
16803                for (int i = 0; i < deletedChildCount; i++) {
16804                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16805                    boolean childPackageDeleted = true;
16806                    for (int j = 0; j < newChildCount; j++) {
16807                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16808                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16809                            childPackageDeleted = false;
16810                            break;
16811                        }
16812                    }
16813                    if (childPackageDeleted) {
16814                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16815                                deletedChildPkg.packageName);
16816                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16817                            PackageRemovedInfo removedChildRes = res.removedInfo
16818                                    .removedChildPackages.get(deletedChildPkg.packageName);
16819                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16820                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16821                        }
16822                    }
16823                }
16824
16825                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16826                        installReason);
16827                prepareAppDataAfterInstallLIF(newPackage);
16828
16829                mDexManager.notifyPackageUpdated(newPackage.packageName,
16830                            newPackage.baseCodePath, newPackage.splitCodePaths);
16831            }
16832        } catch (PackageManagerException e) {
16833            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16834            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16835        }
16836
16837        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16838            // Re installation failed. Restore old information
16839            // Remove new pkg information
16840            if (newPackage != null) {
16841                removeInstalledPackageLI(newPackage, true);
16842            }
16843            // Add back the old system package
16844            try {
16845                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16846            } catch (PackageManagerException e) {
16847                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16848            }
16849
16850            synchronized (mPackages) {
16851                if (disabledSystem) {
16852                    enableSystemPackageLPw(deletedPackage);
16853                }
16854
16855                // Ensure the installer package name up to date
16856                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16857
16858                // Update permissions for restored package
16859                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
16860
16861                mSettings.writeLPr();
16862            }
16863
16864            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16865                    + " after failed upgrade");
16866        }
16867    }
16868
16869    /**
16870     * Checks whether the parent or any of the child packages have a change shared
16871     * user. For a package to be a valid update the shred users of the parent and
16872     * the children should match. We may later support changing child shared users.
16873     * @param oldPkg The updated package.
16874     * @param newPkg The update package.
16875     * @return The shared user that change between the versions.
16876     */
16877    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16878            PackageParser.Package newPkg) {
16879        // Check parent shared user
16880        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16881            return newPkg.packageName;
16882        }
16883        // Check child shared users
16884        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16885        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16886        for (int i = 0; i < newChildCount; i++) {
16887            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16888            // If this child was present, did it have the same shared user?
16889            for (int j = 0; j < oldChildCount; j++) {
16890                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16891                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16892                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16893                    return newChildPkg.packageName;
16894                }
16895            }
16896        }
16897        return null;
16898    }
16899
16900    private void removeNativeBinariesLI(PackageSetting ps) {
16901        // Remove the lib path for the parent package
16902        if (ps != null) {
16903            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16904            // Remove the lib path for the child packages
16905            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16906            for (int i = 0; i < childCount; i++) {
16907                PackageSetting childPs = null;
16908                synchronized (mPackages) {
16909                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16910                }
16911                if (childPs != null) {
16912                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16913                            .legacyNativeLibraryPathString);
16914                }
16915            }
16916        }
16917    }
16918
16919    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16920        // Enable the parent package
16921        mSettings.enableSystemPackageLPw(pkg.packageName);
16922        // Enable the child packages
16923        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16924        for (int i = 0; i < childCount; i++) {
16925            PackageParser.Package childPkg = pkg.childPackages.get(i);
16926            mSettings.enableSystemPackageLPw(childPkg.packageName);
16927        }
16928    }
16929
16930    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16931            PackageParser.Package newPkg) {
16932        // Disable the parent package (parent always replaced)
16933        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16934        // Disable the child packages
16935        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16936        for (int i = 0; i < childCount; i++) {
16937            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16938            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16939            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16940        }
16941        return disabled;
16942    }
16943
16944    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16945            String installerPackageName) {
16946        // Enable the parent package
16947        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16948        // Enable the child packages
16949        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16950        for (int i = 0; i < childCount; i++) {
16951            PackageParser.Package childPkg = pkg.childPackages.get(i);
16952            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16953        }
16954    }
16955
16956    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
16957        // Collect all used permissions in the UID
16958        ArraySet<String> usedPermissions = new ArraySet<>();
16959        final int packageCount = su.packages.size();
16960        for (int i = 0; i < packageCount; i++) {
16961            PackageSetting ps = su.packages.valueAt(i);
16962            if (ps.pkg == null) {
16963                continue;
16964            }
16965            final int requestedPermCount = ps.pkg.requestedPermissions.size();
16966            for (int j = 0; j < requestedPermCount; j++) {
16967                String permission = ps.pkg.requestedPermissions.get(j);
16968                BasePermission bp = mSettings.mPermissions.get(permission);
16969                if (bp != null) {
16970                    usedPermissions.add(permission);
16971                }
16972            }
16973        }
16974
16975        PermissionsState permissionsState = su.getPermissionsState();
16976        // Prune install permissions
16977        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
16978        final int installPermCount = installPermStates.size();
16979        for (int i = installPermCount - 1; i >= 0;  i--) {
16980            PermissionState permissionState = installPermStates.get(i);
16981            if (!usedPermissions.contains(permissionState.getName())) {
16982                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
16983                if (bp != null) {
16984                    permissionsState.revokeInstallPermission(bp);
16985                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
16986                            PackageManager.MASK_PERMISSION_FLAGS, 0);
16987                }
16988            }
16989        }
16990
16991        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
16992
16993        // Prune runtime permissions
16994        for (int userId : allUserIds) {
16995            List<PermissionState> runtimePermStates = permissionsState
16996                    .getRuntimePermissionStates(userId);
16997            final int runtimePermCount = runtimePermStates.size();
16998            for (int i = runtimePermCount - 1; i >= 0; i--) {
16999                PermissionState permissionState = runtimePermStates.get(i);
17000                if (!usedPermissions.contains(permissionState.getName())) {
17001                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17002                    if (bp != null) {
17003                        permissionsState.revokeRuntimePermission(bp, userId);
17004                        permissionsState.updatePermissionFlags(bp, userId,
17005                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17006                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17007                                runtimePermissionChangedUserIds, userId);
17008                    }
17009                }
17010            }
17011        }
17012
17013        return runtimePermissionChangedUserIds;
17014    }
17015
17016    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17017            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17018        // Update the parent package setting
17019        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17020                res, user, installReason);
17021        // Update the child packages setting
17022        final int childCount = (newPackage.childPackages != null)
17023                ? newPackage.childPackages.size() : 0;
17024        for (int i = 0; i < childCount; i++) {
17025            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17026            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17027            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17028                    childRes.origUsers, childRes, user, installReason);
17029        }
17030    }
17031
17032    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17033            String installerPackageName, int[] allUsers, int[] installedForUsers,
17034            PackageInstalledInfo res, UserHandle user, int installReason) {
17035        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17036
17037        String pkgName = newPackage.packageName;
17038        synchronized (mPackages) {
17039            //write settings. the installStatus will be incomplete at this stage.
17040            //note that the new package setting would have already been
17041            //added to mPackages. It hasn't been persisted yet.
17042            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17043            // TODO: Remove this write? It's also written at the end of this method
17044            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17045            mSettings.writeLPr();
17046            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17047        }
17048
17049        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17050        synchronized (mPackages) {
17051            updatePermissionsLPw(newPackage.packageName, newPackage,
17052                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17053                            ? UPDATE_PERMISSIONS_ALL : 0));
17054            // For system-bundled packages, we assume that installing an upgraded version
17055            // of the package implies that the user actually wants to run that new code,
17056            // so we enable the package.
17057            PackageSetting ps = mSettings.mPackages.get(pkgName);
17058            final int userId = user.getIdentifier();
17059            if (ps != null) {
17060                if (isSystemApp(newPackage)) {
17061                    if (DEBUG_INSTALL) {
17062                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17063                    }
17064                    // Enable system package for requested users
17065                    if (res.origUsers != null) {
17066                        for (int origUserId : res.origUsers) {
17067                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17068                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17069                                        origUserId, installerPackageName);
17070                            }
17071                        }
17072                    }
17073                    // Also convey the prior install/uninstall state
17074                    if (allUsers != null && installedForUsers != null) {
17075                        for (int currentUserId : allUsers) {
17076                            final boolean installed = ArrayUtils.contains(
17077                                    installedForUsers, currentUserId);
17078                            if (DEBUG_INSTALL) {
17079                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17080                            }
17081                            ps.setInstalled(installed, currentUserId);
17082                        }
17083                        // these install state changes will be persisted in the
17084                        // upcoming call to mSettings.writeLPr().
17085                    }
17086                }
17087                // It's implied that when a user requests installation, they want the app to be
17088                // installed and enabled.
17089                if (userId != UserHandle.USER_ALL) {
17090                    ps.setInstalled(true, userId);
17091                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17092                }
17093
17094                // When replacing an existing package, preserve the original install reason for all
17095                // users that had the package installed before.
17096                final Set<Integer> previousUserIds = new ArraySet<>();
17097                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17098                    final int installReasonCount = res.removedInfo.installReasons.size();
17099                    for (int i = 0; i < installReasonCount; i++) {
17100                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17101                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17102                        ps.setInstallReason(previousInstallReason, previousUserId);
17103                        previousUserIds.add(previousUserId);
17104                    }
17105                }
17106
17107                // Set install reason for users that are having the package newly installed.
17108                if (userId == UserHandle.USER_ALL) {
17109                    for (int currentUserId : sUserManager.getUserIds()) {
17110                        if (!previousUserIds.contains(currentUserId)) {
17111                            ps.setInstallReason(installReason, currentUserId);
17112                        }
17113                    }
17114                } else if (!previousUserIds.contains(userId)) {
17115                    ps.setInstallReason(installReason, userId);
17116                }
17117                mSettings.writeKernelMappingLPr(ps);
17118            }
17119            res.name = pkgName;
17120            res.uid = newPackage.applicationInfo.uid;
17121            res.pkg = newPackage;
17122            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17123            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17124            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17125            //to update install status
17126            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17127            mSettings.writeLPr();
17128            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17129        }
17130
17131        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17132    }
17133
17134    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17135        try {
17136            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17137            installPackageLI(args, res);
17138        } finally {
17139            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17140        }
17141    }
17142
17143    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17144        final int installFlags = args.installFlags;
17145        final String installerPackageName = args.installerPackageName;
17146        final String volumeUuid = args.volumeUuid;
17147        final File tmpPackageFile = new File(args.getCodePath());
17148        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17149        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17150                || (args.volumeUuid != null));
17151        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17152        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17153        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17154        boolean replace = false;
17155        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17156        if (args.move != null) {
17157            // moving a complete application; perform an initial scan on the new install location
17158            scanFlags |= SCAN_INITIAL;
17159        }
17160        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17161            scanFlags |= SCAN_DONT_KILL_APP;
17162        }
17163        if (instantApp) {
17164            scanFlags |= SCAN_AS_INSTANT_APP;
17165        }
17166        if (fullApp) {
17167            scanFlags |= SCAN_AS_FULL_APP;
17168        }
17169
17170        // Result object to be returned
17171        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17172
17173        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17174
17175        // Sanity check
17176        if (instantApp && (forwardLocked || onExternal)) {
17177            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17178                    + " external=" + onExternal);
17179            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17180            return;
17181        }
17182
17183        // Retrieve PackageSettings and parse package
17184        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17185                | PackageParser.PARSE_ENFORCE_CODE
17186                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17187                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17188                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17189                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17190        PackageParser pp = new PackageParser();
17191        pp.setSeparateProcesses(mSeparateProcesses);
17192        pp.setDisplayMetrics(mMetrics);
17193        pp.setCallback(mPackageParserCallback);
17194
17195        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17196        final PackageParser.Package pkg;
17197        try {
17198            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17199        } catch (PackageParserException e) {
17200            res.setError("Failed parse during installPackageLI", e);
17201            return;
17202        } finally {
17203            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17204        }
17205
17206        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17207        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17208            Slog.w(TAG, "Instant app package " + pkg.packageName
17209                    + " does not target O, this will be a fatal error.");
17210            // STOPSHIP: Make this a fatal error
17211            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
17212        }
17213        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17214            Slog.w(TAG, "Instant app package " + pkg.packageName
17215                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
17216            // STOPSHIP: Make this a fatal error
17217            pkg.applicationInfo.targetSandboxVersion = 2;
17218        }
17219
17220        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17221            // Static shared libraries have synthetic package names
17222            renameStaticSharedLibraryPackage(pkg);
17223
17224            // No static shared libs on external storage
17225            if (onExternal) {
17226                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17227                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17228                        "Packages declaring static-shared libs cannot be updated");
17229                return;
17230            }
17231        }
17232
17233        // If we are installing a clustered package add results for the children
17234        if (pkg.childPackages != null) {
17235            synchronized (mPackages) {
17236                final int childCount = pkg.childPackages.size();
17237                for (int i = 0; i < childCount; i++) {
17238                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17239                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17240                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17241                    childRes.pkg = childPkg;
17242                    childRes.name = childPkg.packageName;
17243                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17244                    if (childPs != null) {
17245                        childRes.origUsers = childPs.queryInstalledUsers(
17246                                sUserManager.getUserIds(), true);
17247                    }
17248                    if ((mPackages.containsKey(childPkg.packageName))) {
17249                        childRes.removedInfo = new PackageRemovedInfo(this);
17250                        childRes.removedInfo.removedPackage = childPkg.packageName;
17251                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17252                    }
17253                    if (res.addedChildPackages == null) {
17254                        res.addedChildPackages = new ArrayMap<>();
17255                    }
17256                    res.addedChildPackages.put(childPkg.packageName, childRes);
17257                }
17258            }
17259        }
17260
17261        // If package doesn't declare API override, mark that we have an install
17262        // time CPU ABI override.
17263        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17264            pkg.cpuAbiOverride = args.abiOverride;
17265        }
17266
17267        String pkgName = res.name = pkg.packageName;
17268        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17269            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17270                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17271                return;
17272            }
17273        }
17274
17275        try {
17276            // either use what we've been given or parse directly from the APK
17277            if (args.certificates != null) {
17278                try {
17279                    PackageParser.populateCertificates(pkg, args.certificates);
17280                } catch (PackageParserException e) {
17281                    // there was something wrong with the certificates we were given;
17282                    // try to pull them from the APK
17283                    PackageParser.collectCertificates(pkg, parseFlags);
17284                }
17285            } else {
17286                PackageParser.collectCertificates(pkg, parseFlags);
17287            }
17288        } catch (PackageParserException e) {
17289            res.setError("Failed collect during installPackageLI", e);
17290            return;
17291        }
17292
17293        // Get rid of all references to package scan path via parser.
17294        pp = null;
17295        String oldCodePath = null;
17296        boolean systemApp = false;
17297        synchronized (mPackages) {
17298            // Check if installing already existing package
17299            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17300                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17301                if (pkg.mOriginalPackages != null
17302                        && pkg.mOriginalPackages.contains(oldName)
17303                        && mPackages.containsKey(oldName)) {
17304                    // This package is derived from an original package,
17305                    // and this device has been updating from that original
17306                    // name.  We must continue using the original name, so
17307                    // rename the new package here.
17308                    pkg.setPackageName(oldName);
17309                    pkgName = pkg.packageName;
17310                    replace = true;
17311                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17312                            + oldName + " pkgName=" + pkgName);
17313                } else if (mPackages.containsKey(pkgName)) {
17314                    // This package, under its official name, already exists
17315                    // on the device; we should replace it.
17316                    replace = true;
17317                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17318                }
17319
17320                // Child packages are installed through the parent package
17321                if (pkg.parentPackage != null) {
17322                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17323                            "Package " + pkg.packageName + " is child of package "
17324                                    + pkg.parentPackage.parentPackage + ". Child packages "
17325                                    + "can be updated only through the parent package.");
17326                    return;
17327                }
17328
17329                if (replace) {
17330                    // Prevent apps opting out from runtime permissions
17331                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17332                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17333                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17334                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17335                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17336                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17337                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17338                                        + " doesn't support runtime permissions but the old"
17339                                        + " target SDK " + oldTargetSdk + " does.");
17340                        return;
17341                    }
17342                    // Prevent apps from downgrading their targetSandbox.
17343                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
17344                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
17345                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
17346                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17347                                "Package " + pkg.packageName + " new target sandbox "
17348                                + newTargetSandbox + " is incompatible with the previous value of"
17349                                + oldTargetSandbox + ".");
17350                        return;
17351                    }
17352
17353                    // Prevent installing of child packages
17354                    if (oldPackage.parentPackage != null) {
17355                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17356                                "Package " + pkg.packageName + " is child of package "
17357                                        + oldPackage.parentPackage + ". Child packages "
17358                                        + "can be updated only through the parent package.");
17359                        return;
17360                    }
17361                }
17362            }
17363
17364            PackageSetting ps = mSettings.mPackages.get(pkgName);
17365            if (ps != null) {
17366                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17367
17368                // Static shared libs have same package with different versions where
17369                // we internally use a synthetic package name to allow multiple versions
17370                // of the same package, therefore we need to compare signatures against
17371                // the package setting for the latest library version.
17372                PackageSetting signatureCheckPs = ps;
17373                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17374                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17375                    if (libraryEntry != null) {
17376                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17377                    }
17378                }
17379
17380                // Quick sanity check that we're signed correctly if updating;
17381                // we'll check this again later when scanning, but we want to
17382                // bail early here before tripping over redefined permissions.
17383                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17384                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17385                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17386                                + pkg.packageName + " upgrade keys do not match the "
17387                                + "previously installed version");
17388                        return;
17389                    }
17390                } else {
17391                    try {
17392                        verifySignaturesLP(signatureCheckPs, pkg);
17393                    } catch (PackageManagerException e) {
17394                        res.setError(e.error, e.getMessage());
17395                        return;
17396                    }
17397                }
17398
17399                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17400                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17401                    systemApp = (ps.pkg.applicationInfo.flags &
17402                            ApplicationInfo.FLAG_SYSTEM) != 0;
17403                }
17404                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17405            }
17406
17407            int N = pkg.permissions.size();
17408            for (int i = N-1; i >= 0; i--) {
17409                PackageParser.Permission perm = pkg.permissions.get(i);
17410                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17411
17412                // Don't allow anyone but the system to define ephemeral permissions.
17413                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17414                        && !systemApp) {
17415                    Slog.w(TAG, "Non-System package " + pkg.packageName
17416                            + " attempting to delcare ephemeral permission "
17417                            + perm.info.name + "; Removing ephemeral.");
17418                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17419                }
17420                // Check whether the newly-scanned package wants to define an already-defined perm
17421                if (bp != null) {
17422                    // If the defining package is signed with our cert, it's okay.  This
17423                    // also includes the "updating the same package" case, of course.
17424                    // "updating same package" could also involve key-rotation.
17425                    final boolean sigsOk;
17426                    if (bp.sourcePackage.equals(pkg.packageName)
17427                            && (bp.packageSetting instanceof PackageSetting)
17428                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17429                                    scanFlags))) {
17430                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17431                    } else {
17432                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17433                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17434                    }
17435                    if (!sigsOk) {
17436                        // If the owning package is the system itself, we log but allow
17437                        // install to proceed; we fail the install on all other permission
17438                        // redefinitions.
17439                        if (!bp.sourcePackage.equals("android")) {
17440                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17441                                    + pkg.packageName + " attempting to redeclare permission "
17442                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17443                            res.origPermission = perm.info.name;
17444                            res.origPackage = bp.sourcePackage;
17445                            return;
17446                        } else {
17447                            Slog.w(TAG, "Package " + pkg.packageName
17448                                    + " attempting to redeclare system permission "
17449                                    + perm.info.name + "; ignoring new declaration");
17450                            pkg.permissions.remove(i);
17451                        }
17452                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17453                        // Prevent apps to change protection level to dangerous from any other
17454                        // type as this would allow a privilege escalation where an app adds a
17455                        // normal/signature permission in other app's group and later redefines
17456                        // it as dangerous leading to the group auto-grant.
17457                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17458                                == PermissionInfo.PROTECTION_DANGEROUS) {
17459                            if (bp != null && !bp.isRuntime()) {
17460                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17461                                        + "non-runtime permission " + perm.info.name
17462                                        + " to runtime; keeping old protection level");
17463                                perm.info.protectionLevel = bp.protectionLevel;
17464                            }
17465                        }
17466                    }
17467                }
17468            }
17469        }
17470
17471        if (systemApp) {
17472            if (onExternal) {
17473                // Abort update; system app can't be replaced with app on sdcard
17474                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17475                        "Cannot install updates to system apps on sdcard");
17476                return;
17477            } else if (instantApp) {
17478                // Abort update; system app can't be replaced with an instant app
17479                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17480                        "Cannot update a system app with an instant app");
17481                return;
17482            }
17483        }
17484
17485        if (args.move != null) {
17486            // We did an in-place move, so dex is ready to roll
17487            scanFlags |= SCAN_NO_DEX;
17488            scanFlags |= SCAN_MOVE;
17489
17490            synchronized (mPackages) {
17491                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17492                if (ps == null) {
17493                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17494                            "Missing settings for moved package " + pkgName);
17495                }
17496
17497                // We moved the entire application as-is, so bring over the
17498                // previously derived ABI information.
17499                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17500                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17501            }
17502
17503        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17504            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17505            scanFlags |= SCAN_NO_DEX;
17506
17507            try {
17508                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17509                    args.abiOverride : pkg.cpuAbiOverride);
17510                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17511                        true /*extractLibs*/, mAppLib32InstallDir);
17512            } catch (PackageManagerException pme) {
17513                Slog.e(TAG, "Error deriving application ABI", pme);
17514                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17515                return;
17516            }
17517
17518            // Shared libraries for the package need to be updated.
17519            synchronized (mPackages) {
17520                try {
17521                    updateSharedLibrariesLPr(pkg, null);
17522                } catch (PackageManagerException e) {
17523                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17524                }
17525            }
17526
17527            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17528            // Do not run PackageDexOptimizer through the local performDexOpt
17529            // method because `pkg` may not be in `mPackages` yet.
17530            //
17531            // Also, don't fail application installs if the dexopt step fails.
17532            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17533                    null /* instructionSets */, false /* checkProfiles */,
17534                    getCompilerFilterForReason(REASON_INSTALL),
17535                    getOrCreateCompilerPackageStats(pkg),
17536                    mDexManager.isUsedByOtherApps(pkg.packageName));
17537            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17538
17539            // Notify BackgroundDexOptService that the package has been changed.
17540            // If this is an update of a package which used to fail to compile,
17541            // BDOS will remove it from its blacklist.
17542            // TODO: Layering violation
17543            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17544        }
17545
17546        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17547            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17548            return;
17549        }
17550
17551        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17552
17553        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17554                "installPackageLI")) {
17555            if (replace) {
17556                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17557                    // Static libs have a synthetic package name containing the version
17558                    // and cannot be updated as an update would get a new package name,
17559                    // unless this is the exact same version code which is useful for
17560                    // development.
17561                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17562                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17563                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17564                                + "static-shared libs cannot be updated");
17565                        return;
17566                    }
17567                }
17568                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17569                        installerPackageName, res, args.installReason);
17570            } else {
17571                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17572                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17573            }
17574        }
17575
17576        synchronized (mPackages) {
17577            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17578            if (ps != null) {
17579                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17580                ps.setUpdateAvailable(false /*updateAvailable*/);
17581            }
17582
17583            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17584            for (int i = 0; i < childCount; i++) {
17585                PackageParser.Package childPkg = pkg.childPackages.get(i);
17586                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17587                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17588                if (childPs != null) {
17589                    childRes.newUsers = childPs.queryInstalledUsers(
17590                            sUserManager.getUserIds(), true);
17591                }
17592            }
17593
17594            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17595                updateSequenceNumberLP(pkgName, res.newUsers);
17596                updateInstantAppInstallerLocked(pkgName);
17597            }
17598        }
17599    }
17600
17601    private void startIntentFilterVerifications(int userId, boolean replacing,
17602            PackageParser.Package pkg) {
17603        if (mIntentFilterVerifierComponent == null) {
17604            Slog.w(TAG, "No IntentFilter verification will not be done as "
17605                    + "there is no IntentFilterVerifier available!");
17606            return;
17607        }
17608
17609        final int verifierUid = getPackageUid(
17610                mIntentFilterVerifierComponent.getPackageName(),
17611                MATCH_DEBUG_TRIAGED_MISSING,
17612                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17613
17614        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17615        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17616        mHandler.sendMessage(msg);
17617
17618        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17619        for (int i = 0; i < childCount; i++) {
17620            PackageParser.Package childPkg = pkg.childPackages.get(i);
17621            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17622            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17623            mHandler.sendMessage(msg);
17624        }
17625    }
17626
17627    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17628            PackageParser.Package pkg) {
17629        int size = pkg.activities.size();
17630        if (size == 0) {
17631            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17632                    "No activity, so no need to verify any IntentFilter!");
17633            return;
17634        }
17635
17636        final boolean hasDomainURLs = hasDomainURLs(pkg);
17637        if (!hasDomainURLs) {
17638            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17639                    "No domain URLs, so no need to verify any IntentFilter!");
17640            return;
17641        }
17642
17643        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17644                + " if any IntentFilter from the " + size
17645                + " Activities needs verification ...");
17646
17647        int count = 0;
17648        final String packageName = pkg.packageName;
17649
17650        synchronized (mPackages) {
17651            // If this is a new install and we see that we've already run verification for this
17652            // package, we have nothing to do: it means the state was restored from backup.
17653            if (!replacing) {
17654                IntentFilterVerificationInfo ivi =
17655                        mSettings.getIntentFilterVerificationLPr(packageName);
17656                if (ivi != null) {
17657                    if (DEBUG_DOMAIN_VERIFICATION) {
17658                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17659                                + ivi.getStatusString());
17660                    }
17661                    return;
17662                }
17663            }
17664
17665            // If any filters need to be verified, then all need to be.
17666            boolean needToVerify = false;
17667            for (PackageParser.Activity a : pkg.activities) {
17668                for (ActivityIntentInfo filter : a.intents) {
17669                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17670                        if (DEBUG_DOMAIN_VERIFICATION) {
17671                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
17672                        }
17673                        needToVerify = true;
17674                        break;
17675                    }
17676                }
17677            }
17678
17679            if (needToVerify) {
17680                final int verificationId = mIntentFilterVerificationToken++;
17681                for (PackageParser.Activity a : pkg.activities) {
17682                    for (ActivityIntentInfo filter : a.intents) {
17683                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17684                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17685                                    "Verification needed for IntentFilter:" + filter.toString());
17686                            mIntentFilterVerifier.addOneIntentFilterVerification(
17687                                    verifierUid, userId, verificationId, filter, packageName);
17688                            count++;
17689                        }
17690                    }
17691                }
17692            }
17693        }
17694
17695        if (count > 0) {
17696            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17697                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17698                    +  " for userId:" + userId);
17699            mIntentFilterVerifier.startVerifications(userId);
17700        } else {
17701            if (DEBUG_DOMAIN_VERIFICATION) {
17702                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17703            }
17704        }
17705    }
17706
17707    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17708        final ComponentName cn  = filter.activity.getComponentName();
17709        final String packageName = cn.getPackageName();
17710
17711        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17712                packageName);
17713        if (ivi == null) {
17714            return true;
17715        }
17716        int status = ivi.getStatus();
17717        switch (status) {
17718            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17719            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17720                return true;
17721
17722            default:
17723                // Nothing to do
17724                return false;
17725        }
17726    }
17727
17728    private static boolean isMultiArch(ApplicationInfo info) {
17729        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17730    }
17731
17732    private static boolean isExternal(PackageParser.Package pkg) {
17733        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17734    }
17735
17736    private static boolean isExternal(PackageSetting ps) {
17737        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17738    }
17739
17740    private static boolean isSystemApp(PackageParser.Package pkg) {
17741        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17742    }
17743
17744    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17745        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17746    }
17747
17748    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17749        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17750    }
17751
17752    private static boolean isSystemApp(PackageSetting ps) {
17753        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17754    }
17755
17756    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17757        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17758    }
17759
17760    private int packageFlagsToInstallFlags(PackageSetting ps) {
17761        int installFlags = 0;
17762        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17763            // This existing package was an external ASEC install when we have
17764            // the external flag without a UUID
17765            installFlags |= PackageManager.INSTALL_EXTERNAL;
17766        }
17767        if (ps.isForwardLocked()) {
17768            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17769        }
17770        return installFlags;
17771    }
17772
17773    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
17774        if (isExternal(pkg)) {
17775            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17776                return StorageManager.UUID_PRIMARY_PHYSICAL;
17777            } else {
17778                return pkg.volumeUuid;
17779            }
17780        } else {
17781            return StorageManager.UUID_PRIVATE_INTERNAL;
17782        }
17783    }
17784
17785    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17786        if (isExternal(pkg)) {
17787            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17788                return mSettings.getExternalVersion();
17789            } else {
17790                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17791            }
17792        } else {
17793            return mSettings.getInternalVersion();
17794        }
17795    }
17796
17797    private void deleteTempPackageFiles() {
17798        final FilenameFilter filter = new FilenameFilter() {
17799            public boolean accept(File dir, String name) {
17800                return name.startsWith("vmdl") && name.endsWith(".tmp");
17801            }
17802        };
17803        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
17804            file.delete();
17805        }
17806    }
17807
17808    @Override
17809    public void deletePackageAsUser(String packageName, int versionCode,
17810            IPackageDeleteObserver observer, int userId, int flags) {
17811        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17812                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17813    }
17814
17815    @Override
17816    public void deletePackageVersioned(VersionedPackage versionedPackage,
17817            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17818        mContext.enforceCallingOrSelfPermission(
17819                android.Manifest.permission.DELETE_PACKAGES, null);
17820        Preconditions.checkNotNull(versionedPackage);
17821        Preconditions.checkNotNull(observer);
17822        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
17823                PackageManager.VERSION_CODE_HIGHEST,
17824                Integer.MAX_VALUE, "versionCode must be >= -1");
17825
17826        final String packageName = versionedPackage.getPackageName();
17827        final int versionCode = versionedPackage.getVersionCode();
17828        final String internalPackageName;
17829        synchronized (mPackages) {
17830            // Normalize package name to handle renamed packages and static libs
17831            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
17832                    versionedPackage.getVersionCode());
17833        }
17834
17835        final int uid = Binder.getCallingUid();
17836        if (!isOrphaned(internalPackageName)
17837                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17838            try {
17839                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17840                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17841                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17842                observer.onUserActionRequired(intent);
17843            } catch (RemoteException re) {
17844            }
17845            return;
17846        }
17847        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17848        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17849        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17850            mContext.enforceCallingOrSelfPermission(
17851                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17852                    "deletePackage for user " + userId);
17853        }
17854
17855        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17856            try {
17857                observer.onPackageDeleted(packageName,
17858                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17859            } catch (RemoteException re) {
17860            }
17861            return;
17862        }
17863
17864        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17865            try {
17866                observer.onPackageDeleted(packageName,
17867                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17868            } catch (RemoteException re) {
17869            }
17870            return;
17871        }
17872
17873        if (DEBUG_REMOVE) {
17874            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17875                    + " deleteAllUsers: " + deleteAllUsers + " version="
17876                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17877                    ? "VERSION_CODE_HIGHEST" : versionCode));
17878        }
17879        // Queue up an async operation since the package deletion may take a little while.
17880        mHandler.post(new Runnable() {
17881            public void run() {
17882                mHandler.removeCallbacks(this);
17883                int returnCode;
17884                if (!deleteAllUsers) {
17885                    returnCode = deletePackageX(internalPackageName, versionCode,
17886                            userId, deleteFlags);
17887                } else {
17888                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
17889                            internalPackageName, users);
17890                    // If nobody is blocking uninstall, proceed with delete for all users
17891                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17892                        returnCode = deletePackageX(internalPackageName, versionCode,
17893                                userId, deleteFlags);
17894                    } else {
17895                        // Otherwise uninstall individually for users with blockUninstalls=false
17896                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17897                        for (int userId : users) {
17898                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17899                                returnCode = deletePackageX(internalPackageName, versionCode,
17900                                        userId, userFlags);
17901                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17902                                    Slog.w(TAG, "Package delete failed for user " + userId
17903                                            + ", returnCode " + returnCode);
17904                                }
17905                            }
17906                        }
17907                        // The app has only been marked uninstalled for certain users.
17908                        // We still need to report that delete was blocked
17909                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17910                    }
17911                }
17912                try {
17913                    observer.onPackageDeleted(packageName, returnCode, null);
17914                } catch (RemoteException e) {
17915                    Log.i(TAG, "Observer no longer exists.");
17916                } //end catch
17917            } //end run
17918        });
17919    }
17920
17921    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17922        if (pkg.staticSharedLibName != null) {
17923            return pkg.manifestPackageName;
17924        }
17925        return pkg.packageName;
17926    }
17927
17928    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
17929        // Handle renamed packages
17930        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17931        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17932
17933        // Is this a static library?
17934        SparseArray<SharedLibraryEntry> versionedLib =
17935                mStaticLibsByDeclaringPackage.get(packageName);
17936        if (versionedLib == null || versionedLib.size() <= 0) {
17937            return packageName;
17938        }
17939
17940        // Figure out which lib versions the caller can see
17941        SparseIntArray versionsCallerCanSee = null;
17942        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17943        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17944                && callingAppId != Process.ROOT_UID) {
17945            versionsCallerCanSee = new SparseIntArray();
17946            String libName = versionedLib.valueAt(0).info.getName();
17947            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17948            if (uidPackages != null) {
17949                for (String uidPackage : uidPackages) {
17950                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17951                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17952                    if (libIdx >= 0) {
17953                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
17954                        versionsCallerCanSee.append(libVersion, libVersion);
17955                    }
17956                }
17957            }
17958        }
17959
17960        // Caller can see nothing - done
17961        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17962            return packageName;
17963        }
17964
17965        // Find the version the caller can see and the app version code
17966        SharedLibraryEntry highestVersion = null;
17967        final int versionCount = versionedLib.size();
17968        for (int i = 0; i < versionCount; i++) {
17969            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17970            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17971                    libEntry.info.getVersion()) < 0) {
17972                continue;
17973            }
17974            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
17975            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17976                if (libVersionCode == versionCode) {
17977                    return libEntry.apk;
17978                }
17979            } else if (highestVersion == null) {
17980                highestVersion = libEntry;
17981            } else if (libVersionCode  > highestVersion.info
17982                    .getDeclaringPackage().getVersionCode()) {
17983                highestVersion = libEntry;
17984            }
17985        }
17986
17987        if (highestVersion != null) {
17988            return highestVersion.apk;
17989        }
17990
17991        return packageName;
17992    }
17993
17994    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17995        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17996              || callingUid == Process.SYSTEM_UID) {
17997            return true;
17998        }
17999        final int callingUserId = UserHandle.getUserId(callingUid);
18000        // If the caller installed the pkgName, then allow it to silently uninstall.
18001        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18002            return true;
18003        }
18004
18005        // Allow package verifier to silently uninstall.
18006        if (mRequiredVerifierPackage != null &&
18007                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18008            return true;
18009        }
18010
18011        // Allow package uninstaller to silently uninstall.
18012        if (mRequiredUninstallerPackage != null &&
18013                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18014            return true;
18015        }
18016
18017        // Allow storage manager to silently uninstall.
18018        if (mStorageManagerPackage != null &&
18019                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18020            return true;
18021        }
18022        return false;
18023    }
18024
18025    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18026        int[] result = EMPTY_INT_ARRAY;
18027        for (int userId : userIds) {
18028            if (getBlockUninstallForUser(packageName, userId)) {
18029                result = ArrayUtils.appendInt(result, userId);
18030            }
18031        }
18032        return result;
18033    }
18034
18035    @Override
18036    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18037        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18038    }
18039
18040    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18041        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18042                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18043        try {
18044            if (dpm != null) {
18045                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18046                        /* callingUserOnly =*/ false);
18047                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18048                        : deviceOwnerComponentName.getPackageName();
18049                // Does the package contains the device owner?
18050                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18051                // this check is probably not needed, since DO should be registered as a device
18052                // admin on some user too. (Original bug for this: b/17657954)
18053                if (packageName.equals(deviceOwnerPackageName)) {
18054                    return true;
18055                }
18056                // Does it contain a device admin for any user?
18057                int[] users;
18058                if (userId == UserHandle.USER_ALL) {
18059                    users = sUserManager.getUserIds();
18060                } else {
18061                    users = new int[]{userId};
18062                }
18063                for (int i = 0; i < users.length; ++i) {
18064                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18065                        return true;
18066                    }
18067                }
18068            }
18069        } catch (RemoteException e) {
18070        }
18071        return false;
18072    }
18073
18074    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18075        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18076    }
18077
18078    /**
18079     *  This method is an internal method that could be get invoked either
18080     *  to delete an installed package or to clean up a failed installation.
18081     *  After deleting an installed package, a broadcast is sent to notify any
18082     *  listeners that the package has been removed. For cleaning up a failed
18083     *  installation, the broadcast is not necessary since the package's
18084     *  installation wouldn't have sent the initial broadcast either
18085     *  The key steps in deleting a package are
18086     *  deleting the package information in internal structures like mPackages,
18087     *  deleting the packages base directories through installd
18088     *  updating mSettings to reflect current status
18089     *  persisting settings for later use
18090     *  sending a broadcast if necessary
18091     */
18092    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18093        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18094        final boolean res;
18095
18096        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18097                ? UserHandle.USER_ALL : userId;
18098
18099        if (isPackageDeviceAdmin(packageName, removeUser)) {
18100            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18101            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18102        }
18103
18104        PackageSetting uninstalledPs = null;
18105        PackageParser.Package pkg = null;
18106
18107        // for the uninstall-updates case and restricted profiles, remember the per-
18108        // user handle installed state
18109        int[] allUsers;
18110        synchronized (mPackages) {
18111            uninstalledPs = mSettings.mPackages.get(packageName);
18112            if (uninstalledPs == null) {
18113                Slog.w(TAG, "Not removing non-existent package " + packageName);
18114                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18115            }
18116
18117            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18118                    && uninstalledPs.versionCode != versionCode) {
18119                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18120                        + uninstalledPs.versionCode + " != " + versionCode);
18121                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18122            }
18123
18124            // Static shared libs can be declared by any package, so let us not
18125            // allow removing a package if it provides a lib others depend on.
18126            pkg = mPackages.get(packageName);
18127
18128            allUsers = sUserManager.getUserIds();
18129
18130            if (pkg != null && pkg.staticSharedLibName != null) {
18131                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18132                        pkg.staticSharedLibVersion);
18133                if (libEntry != null) {
18134                    for (int currUserId : allUsers) {
18135                        if (userId != UserHandle.USER_ALL && userId != currUserId) {
18136                            continue;
18137                        }
18138                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18139                                libEntry.info, 0, currUserId);
18140                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18141                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18142                                    + " hosting lib " + libEntry.info.getName() + " version "
18143                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18144                                    + " for user " + currUserId);
18145                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18146                        }
18147                    }
18148                }
18149            }
18150
18151            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18152        }
18153
18154        final int freezeUser;
18155        if (isUpdatedSystemApp(uninstalledPs)
18156                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18157            // We're downgrading a system app, which will apply to all users, so
18158            // freeze them all during the downgrade
18159            freezeUser = UserHandle.USER_ALL;
18160        } else {
18161            freezeUser = removeUser;
18162        }
18163
18164        synchronized (mInstallLock) {
18165            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18166            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18167                    deleteFlags, "deletePackageX")) {
18168                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18169                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18170            }
18171            synchronized (mPackages) {
18172                if (res) {
18173                    if (pkg != null) {
18174                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18175                    }
18176                    updateSequenceNumberLP(packageName, info.removedUsers);
18177                    updateInstantAppInstallerLocked(packageName);
18178                }
18179            }
18180        }
18181
18182        if (res) {
18183            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18184            info.sendPackageRemovedBroadcasts(killApp);
18185            info.sendSystemPackageUpdatedBroadcasts();
18186            info.sendSystemPackageAppearedBroadcasts();
18187        }
18188        // Force a gc here.
18189        Runtime.getRuntime().gc();
18190        // Delete the resources here after sending the broadcast to let
18191        // other processes clean up before deleting resources.
18192        if (info.args != null) {
18193            synchronized (mInstallLock) {
18194                info.args.doPostDeleteLI(true);
18195            }
18196        }
18197
18198        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18199    }
18200
18201    static class PackageRemovedInfo {
18202        final PackageSender packageSender;
18203        String removedPackage;
18204        String installerPackageName;
18205        int uid = -1;
18206        int removedAppId = -1;
18207        int[] origUsers;
18208        int[] removedUsers = null;
18209        int[] broadcastUsers = null;
18210        SparseArray<Integer> installReasons;
18211        boolean isRemovedPackageSystemUpdate = false;
18212        boolean isUpdate;
18213        boolean dataRemoved;
18214        boolean removedForAllUsers;
18215        boolean isStaticSharedLib;
18216        // Clean up resources deleted packages.
18217        InstallArgs args = null;
18218        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18219        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18220
18221        PackageRemovedInfo(PackageSender packageSender) {
18222            this.packageSender = packageSender;
18223        }
18224
18225        void sendPackageRemovedBroadcasts(boolean killApp) {
18226            sendPackageRemovedBroadcastInternal(killApp);
18227            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18228            for (int i = 0; i < childCount; i++) {
18229                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18230                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18231            }
18232        }
18233
18234        void sendSystemPackageUpdatedBroadcasts() {
18235            if (isRemovedPackageSystemUpdate) {
18236                sendSystemPackageUpdatedBroadcastsInternal();
18237                final int childCount = (removedChildPackages != null)
18238                        ? removedChildPackages.size() : 0;
18239                for (int i = 0; i < childCount; i++) {
18240                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18241                    if (childInfo.isRemovedPackageSystemUpdate) {
18242                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18243                    }
18244                }
18245            }
18246        }
18247
18248        void sendSystemPackageAppearedBroadcasts() {
18249            final int packageCount = (appearedChildPackages != null)
18250                    ? appearedChildPackages.size() : 0;
18251            for (int i = 0; i < packageCount; i++) {
18252                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18253                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18254                    true, UserHandle.getAppId(installedInfo.uid),
18255                    installedInfo.newUsers);
18256            }
18257        }
18258
18259        private void sendSystemPackageUpdatedBroadcastsInternal() {
18260            Bundle extras = new Bundle(2);
18261            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18262            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18263            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18264                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18265            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18266                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18267            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18268                null, null, 0, removedPackage, null, null);
18269            if (installerPackageName != null) {
18270                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18271                        removedPackage, extras, 0 /*flags*/,
18272                        installerPackageName, null, null);
18273                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18274                        removedPackage, extras, 0 /*flags*/,
18275                        installerPackageName, null, null);
18276            }
18277        }
18278
18279        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18280            // Don't send static shared library removal broadcasts as these
18281            // libs are visible only the the apps that depend on them an one
18282            // cannot remove the library if it has a dependency.
18283            if (isStaticSharedLib) {
18284                return;
18285            }
18286            Bundle extras = new Bundle(2);
18287            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18288            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18289            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18290            if (isUpdate || isRemovedPackageSystemUpdate) {
18291                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18292            }
18293            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18294            if (removedPackage != null) {
18295                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18296                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
18297                if (installerPackageName != null) {
18298                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18299                            removedPackage, extras, 0 /*flags*/,
18300                            installerPackageName, null, broadcastUsers);
18301                }
18302                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18303                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18304                        removedPackage, extras,
18305                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18306                        null, null, broadcastUsers);
18307                }
18308            }
18309            if (removedAppId >= 0) {
18310                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
18311                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
18312            }
18313        }
18314
18315        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18316            removedUsers = userIds;
18317            if (removedUsers == null) {
18318                broadcastUsers = null;
18319                return;
18320            }
18321
18322            broadcastUsers = EMPTY_INT_ARRAY;
18323            for (int i = userIds.length - 1; i >= 0; --i) {
18324                final int userId = userIds[i];
18325                if (deletedPackageSetting.getInstantApp(userId)) {
18326                    continue;
18327                }
18328                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18329            }
18330        }
18331    }
18332
18333    /*
18334     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18335     * flag is not set, the data directory is removed as well.
18336     * make sure this flag is set for partially installed apps. If not its meaningless to
18337     * delete a partially installed application.
18338     */
18339    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18340            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18341        String packageName = ps.name;
18342        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18343        // Retrieve object to delete permissions for shared user later on
18344        final PackageParser.Package deletedPkg;
18345        final PackageSetting deletedPs;
18346        // reader
18347        synchronized (mPackages) {
18348            deletedPkg = mPackages.get(packageName);
18349            deletedPs = mSettings.mPackages.get(packageName);
18350            if (outInfo != null) {
18351                outInfo.removedPackage = packageName;
18352                outInfo.installerPackageName = ps.installerPackageName;
18353                outInfo.isStaticSharedLib = deletedPkg != null
18354                        && deletedPkg.staticSharedLibName != null;
18355                outInfo.populateUsers(deletedPs == null ? null
18356                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18357            }
18358        }
18359
18360        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
18361
18362        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18363            final PackageParser.Package resolvedPkg;
18364            if (deletedPkg != null) {
18365                resolvedPkg = deletedPkg;
18366            } else {
18367                // We don't have a parsed package when it lives on an ejected
18368                // adopted storage device, so fake something together
18369                resolvedPkg = new PackageParser.Package(ps.name);
18370                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18371            }
18372            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18373                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18374            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18375            if (outInfo != null) {
18376                outInfo.dataRemoved = true;
18377            }
18378            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18379        }
18380
18381        int removedAppId = -1;
18382
18383        // writer
18384        synchronized (mPackages) {
18385            boolean installedStateChanged = false;
18386            if (deletedPs != null) {
18387                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18388                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18389                    clearDefaultBrowserIfNeeded(packageName);
18390                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18391                    removedAppId = mSettings.removePackageLPw(packageName);
18392                    if (outInfo != null) {
18393                        outInfo.removedAppId = removedAppId;
18394                    }
18395                    updatePermissionsLPw(deletedPs.name, null, 0);
18396                    if (deletedPs.sharedUser != null) {
18397                        // Remove permissions associated with package. Since runtime
18398                        // permissions are per user we have to kill the removed package
18399                        // or packages running under the shared user of the removed
18400                        // package if revoking the permissions requested only by the removed
18401                        // package is successful and this causes a change in gids.
18402                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18403                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18404                                    userId);
18405                            if (userIdToKill == UserHandle.USER_ALL
18406                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18407                                // If gids changed for this user, kill all affected packages.
18408                                mHandler.post(new Runnable() {
18409                                    @Override
18410                                    public void run() {
18411                                        // This has to happen with no lock held.
18412                                        killApplication(deletedPs.name, deletedPs.appId,
18413                                                KILL_APP_REASON_GIDS_CHANGED);
18414                                    }
18415                                });
18416                                break;
18417                            }
18418                        }
18419                    }
18420                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18421                }
18422                // make sure to preserve per-user disabled state if this removal was just
18423                // a downgrade of a system app to the factory package
18424                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18425                    if (DEBUG_REMOVE) {
18426                        Slog.d(TAG, "Propagating install state across downgrade");
18427                    }
18428                    for (int userId : allUserHandles) {
18429                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18430                        if (DEBUG_REMOVE) {
18431                            Slog.d(TAG, "    user " + userId + " => " + installed);
18432                        }
18433                        if (installed != ps.getInstalled(userId)) {
18434                            installedStateChanged = true;
18435                        }
18436                        ps.setInstalled(installed, userId);
18437                    }
18438                }
18439            }
18440            // can downgrade to reader
18441            if (writeSettings) {
18442                // Save settings now
18443                mSettings.writeLPr();
18444            }
18445            if (installedStateChanged) {
18446                mSettings.writeKernelMappingLPr(ps);
18447            }
18448        }
18449        if (removedAppId != -1) {
18450            // A user ID was deleted here. Go through all users and remove it
18451            // from KeyStore.
18452            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18453        }
18454    }
18455
18456    static boolean locationIsPrivileged(File path) {
18457        try {
18458            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18459                    .getCanonicalPath();
18460            return path.getCanonicalPath().startsWith(privilegedAppDir);
18461        } catch (IOException e) {
18462            Slog.e(TAG, "Unable to access code path " + path);
18463        }
18464        return false;
18465    }
18466
18467    /*
18468     * Tries to delete system package.
18469     */
18470    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18471            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18472            boolean writeSettings) {
18473        if (deletedPs.parentPackageName != null) {
18474            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18475            return false;
18476        }
18477
18478        final boolean applyUserRestrictions
18479                = (allUserHandles != null) && (outInfo.origUsers != null);
18480        final PackageSetting disabledPs;
18481        // Confirm if the system package has been updated
18482        // An updated system app can be deleted. This will also have to restore
18483        // the system pkg from system partition
18484        // reader
18485        synchronized (mPackages) {
18486            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18487        }
18488
18489        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18490                + " disabledPs=" + disabledPs);
18491
18492        if (disabledPs == null) {
18493            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18494            return false;
18495        } else if (DEBUG_REMOVE) {
18496            Slog.d(TAG, "Deleting system pkg from data partition");
18497        }
18498
18499        if (DEBUG_REMOVE) {
18500            if (applyUserRestrictions) {
18501                Slog.d(TAG, "Remembering install states:");
18502                for (int userId : allUserHandles) {
18503                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18504                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18505                }
18506            }
18507        }
18508
18509        // Delete the updated package
18510        outInfo.isRemovedPackageSystemUpdate = true;
18511        if (outInfo.removedChildPackages != null) {
18512            final int childCount = (deletedPs.childPackageNames != null)
18513                    ? deletedPs.childPackageNames.size() : 0;
18514            for (int i = 0; i < childCount; i++) {
18515                String childPackageName = deletedPs.childPackageNames.get(i);
18516                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18517                        .contains(childPackageName)) {
18518                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18519                            childPackageName);
18520                    if (childInfo != null) {
18521                        childInfo.isRemovedPackageSystemUpdate = true;
18522                    }
18523                }
18524            }
18525        }
18526
18527        if (disabledPs.versionCode < deletedPs.versionCode) {
18528            // Delete data for downgrades
18529            flags &= ~PackageManager.DELETE_KEEP_DATA;
18530        } else {
18531            // Preserve data by setting flag
18532            flags |= PackageManager.DELETE_KEEP_DATA;
18533        }
18534
18535        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18536                outInfo, writeSettings, disabledPs.pkg);
18537        if (!ret) {
18538            return false;
18539        }
18540
18541        // writer
18542        synchronized (mPackages) {
18543            // Reinstate the old system package
18544            enableSystemPackageLPw(disabledPs.pkg);
18545            // Remove any native libraries from the upgraded package.
18546            removeNativeBinariesLI(deletedPs);
18547        }
18548
18549        // Install the system package
18550        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18551        int parseFlags = mDefParseFlags
18552                | PackageParser.PARSE_MUST_BE_APK
18553                | PackageParser.PARSE_IS_SYSTEM
18554                | PackageParser.PARSE_IS_SYSTEM_DIR;
18555        if (locationIsPrivileged(disabledPs.codePath)) {
18556            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18557        }
18558
18559        final PackageParser.Package newPkg;
18560        try {
18561            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18562                0 /* currentTime */, null);
18563        } catch (PackageManagerException e) {
18564            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18565                    + e.getMessage());
18566            return false;
18567        }
18568
18569        try {
18570            // update shared libraries for the newly re-installed system package
18571            updateSharedLibrariesLPr(newPkg, null);
18572        } catch (PackageManagerException e) {
18573            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18574        }
18575
18576        prepareAppDataAfterInstallLIF(newPkg);
18577
18578        // writer
18579        synchronized (mPackages) {
18580            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18581
18582            // Propagate the permissions state as we do not want to drop on the floor
18583            // runtime permissions. The update permissions method below will take
18584            // care of removing obsolete permissions and grant install permissions.
18585            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18586            updatePermissionsLPw(newPkg.packageName, newPkg,
18587                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18588
18589            if (applyUserRestrictions) {
18590                boolean installedStateChanged = false;
18591                if (DEBUG_REMOVE) {
18592                    Slog.d(TAG, "Propagating install state across reinstall");
18593                }
18594                for (int userId : allUserHandles) {
18595                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18596                    if (DEBUG_REMOVE) {
18597                        Slog.d(TAG, "    user " + userId + " => " + installed);
18598                    }
18599                    if (installed != ps.getInstalled(userId)) {
18600                        installedStateChanged = true;
18601                    }
18602                    ps.setInstalled(installed, userId);
18603
18604                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18605                }
18606                // Regardless of writeSettings we need to ensure that this restriction
18607                // state propagation is persisted
18608                mSettings.writeAllUsersPackageRestrictionsLPr();
18609                if (installedStateChanged) {
18610                    mSettings.writeKernelMappingLPr(ps);
18611                }
18612            }
18613            // can downgrade to reader here
18614            if (writeSettings) {
18615                mSettings.writeLPr();
18616            }
18617        }
18618        return true;
18619    }
18620
18621    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18622            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18623            PackageRemovedInfo outInfo, boolean writeSettings,
18624            PackageParser.Package replacingPackage) {
18625        synchronized (mPackages) {
18626            if (outInfo != null) {
18627                outInfo.uid = ps.appId;
18628            }
18629
18630            if (outInfo != null && outInfo.removedChildPackages != null) {
18631                final int childCount = (ps.childPackageNames != null)
18632                        ? ps.childPackageNames.size() : 0;
18633                for (int i = 0; i < childCount; i++) {
18634                    String childPackageName = ps.childPackageNames.get(i);
18635                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18636                    if (childPs == null) {
18637                        return false;
18638                    }
18639                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18640                            childPackageName);
18641                    if (childInfo != null) {
18642                        childInfo.uid = childPs.appId;
18643                    }
18644                }
18645            }
18646        }
18647
18648        // Delete package data from internal structures and also remove data if flag is set
18649        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18650
18651        // Delete the child packages data
18652        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18653        for (int i = 0; i < childCount; i++) {
18654            PackageSetting childPs;
18655            synchronized (mPackages) {
18656                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18657            }
18658            if (childPs != null) {
18659                PackageRemovedInfo childOutInfo = (outInfo != null
18660                        && outInfo.removedChildPackages != null)
18661                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18662                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18663                        && (replacingPackage != null
18664                        && !replacingPackage.hasChildPackage(childPs.name))
18665                        ? flags & ~DELETE_KEEP_DATA : flags;
18666                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18667                        deleteFlags, writeSettings);
18668            }
18669        }
18670
18671        // Delete application code and resources only for parent packages
18672        if (ps.parentPackageName == null) {
18673            if (deleteCodeAndResources && (outInfo != null)) {
18674                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18675                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18676                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18677            }
18678        }
18679
18680        return true;
18681    }
18682
18683    @Override
18684    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18685            int userId) {
18686        mContext.enforceCallingOrSelfPermission(
18687                android.Manifest.permission.DELETE_PACKAGES, null);
18688        synchronized (mPackages) {
18689            // Cannot block uninstall of static shared libs as they are
18690            // considered a part of the using app (emulating static linking).
18691            // Also static libs are installed always on internal storage.
18692            PackageParser.Package pkg = mPackages.get(packageName);
18693            if (pkg != null && pkg.staticSharedLibName != null) {
18694                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18695                        + " providing static shared library: " + pkg.staticSharedLibName);
18696                return false;
18697            }
18698            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18699            mSettings.writePackageRestrictionsLPr(userId);
18700        }
18701        return true;
18702    }
18703
18704    @Override
18705    public boolean getBlockUninstallForUser(String packageName, int userId) {
18706        synchronized (mPackages) {
18707            return mSettings.getBlockUninstallLPr(userId, packageName);
18708        }
18709    }
18710
18711    @Override
18712    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18713        int callingUid = Binder.getCallingUid();
18714        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
18715            throw new SecurityException(
18716                    "setRequiredForSystemUser can only be run by the system or root");
18717        }
18718        synchronized (mPackages) {
18719            PackageSetting ps = mSettings.mPackages.get(packageName);
18720            if (ps == null) {
18721                Log.w(TAG, "Package doesn't exist: " + packageName);
18722                return false;
18723            }
18724            if (systemUserApp) {
18725                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18726            } else {
18727                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18728            }
18729            mSettings.writeLPr();
18730        }
18731        return true;
18732    }
18733
18734    /*
18735     * This method handles package deletion in general
18736     */
18737    private boolean deletePackageLIF(String packageName, UserHandle user,
18738            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18739            PackageRemovedInfo outInfo, boolean writeSettings,
18740            PackageParser.Package replacingPackage) {
18741        if (packageName == null) {
18742            Slog.w(TAG, "Attempt to delete null packageName.");
18743            return false;
18744        }
18745
18746        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18747
18748        PackageSetting ps;
18749        synchronized (mPackages) {
18750            ps = mSettings.mPackages.get(packageName);
18751            if (ps == null) {
18752                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18753                return false;
18754            }
18755
18756            if (ps.parentPackageName != null && (!isSystemApp(ps)
18757                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18758                if (DEBUG_REMOVE) {
18759                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18760                            + ((user == null) ? UserHandle.USER_ALL : user));
18761                }
18762                final int removedUserId = (user != null) ? user.getIdentifier()
18763                        : UserHandle.USER_ALL;
18764                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18765                    return false;
18766                }
18767                markPackageUninstalledForUserLPw(ps, user);
18768                scheduleWritePackageRestrictionsLocked(user);
18769                return true;
18770            }
18771        }
18772
18773        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18774                && user.getIdentifier() != UserHandle.USER_ALL)) {
18775            // The caller is asking that the package only be deleted for a single
18776            // user.  To do this, we just mark its uninstalled state and delete
18777            // its data. If this is a system app, we only allow this to happen if
18778            // they have set the special DELETE_SYSTEM_APP which requests different
18779            // semantics than normal for uninstalling system apps.
18780            markPackageUninstalledForUserLPw(ps, user);
18781
18782            if (!isSystemApp(ps)) {
18783                // Do not uninstall the APK if an app should be cached
18784                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18785                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18786                    // Other user still have this package installed, so all
18787                    // we need to do is clear this user's data and save that
18788                    // it is uninstalled.
18789                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18790                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18791                        return false;
18792                    }
18793                    scheduleWritePackageRestrictionsLocked(user);
18794                    return true;
18795                } else {
18796                    // We need to set it back to 'installed' so the uninstall
18797                    // broadcasts will be sent correctly.
18798                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18799                    ps.setInstalled(true, user.getIdentifier());
18800                    mSettings.writeKernelMappingLPr(ps);
18801                }
18802            } else {
18803                // This is a system app, so we assume that the
18804                // other users still have this package installed, so all
18805                // we need to do is clear this user's data and save that
18806                // it is uninstalled.
18807                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18808                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18809                    return false;
18810                }
18811                scheduleWritePackageRestrictionsLocked(user);
18812                return true;
18813            }
18814        }
18815
18816        // If we are deleting a composite package for all users, keep track
18817        // of result for each child.
18818        if (ps.childPackageNames != null && outInfo != null) {
18819            synchronized (mPackages) {
18820                final int childCount = ps.childPackageNames.size();
18821                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18822                for (int i = 0; i < childCount; i++) {
18823                    String childPackageName = ps.childPackageNames.get(i);
18824                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18825                    childInfo.removedPackage = childPackageName;
18826                    childInfo.installerPackageName = ps.installerPackageName;
18827                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18828                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18829                    if (childPs != null) {
18830                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18831                    }
18832                }
18833            }
18834        }
18835
18836        boolean ret = false;
18837        if (isSystemApp(ps)) {
18838            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18839            // When an updated system application is deleted we delete the existing resources
18840            // as well and fall back to existing code in system partition
18841            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18842        } else {
18843            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18844            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18845                    outInfo, writeSettings, replacingPackage);
18846        }
18847
18848        // Take a note whether we deleted the package for all users
18849        if (outInfo != null) {
18850            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18851            if (outInfo.removedChildPackages != null) {
18852                synchronized (mPackages) {
18853                    final int childCount = outInfo.removedChildPackages.size();
18854                    for (int i = 0; i < childCount; i++) {
18855                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18856                        if (childInfo != null) {
18857                            childInfo.removedForAllUsers = mPackages.get(
18858                                    childInfo.removedPackage) == null;
18859                        }
18860                    }
18861                }
18862            }
18863            // If we uninstalled an update to a system app there may be some
18864            // child packages that appeared as they are declared in the system
18865            // app but were not declared in the update.
18866            if (isSystemApp(ps)) {
18867                synchronized (mPackages) {
18868                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18869                    final int childCount = (updatedPs.childPackageNames != null)
18870                            ? updatedPs.childPackageNames.size() : 0;
18871                    for (int i = 0; i < childCount; i++) {
18872                        String childPackageName = updatedPs.childPackageNames.get(i);
18873                        if (outInfo.removedChildPackages == null
18874                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18875                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18876                            if (childPs == null) {
18877                                continue;
18878                            }
18879                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18880                            installRes.name = childPackageName;
18881                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18882                            installRes.pkg = mPackages.get(childPackageName);
18883                            installRes.uid = childPs.pkg.applicationInfo.uid;
18884                            if (outInfo.appearedChildPackages == null) {
18885                                outInfo.appearedChildPackages = new ArrayMap<>();
18886                            }
18887                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18888                        }
18889                    }
18890                }
18891            }
18892        }
18893
18894        return ret;
18895    }
18896
18897    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18898        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18899                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18900        for (int nextUserId : userIds) {
18901            if (DEBUG_REMOVE) {
18902                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18903            }
18904            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18905                    false /*installed*/,
18906                    true /*stopped*/,
18907                    true /*notLaunched*/,
18908                    false /*hidden*/,
18909                    false /*suspended*/,
18910                    false /*instantApp*/,
18911                    null /*lastDisableAppCaller*/,
18912                    null /*enabledComponents*/,
18913                    null /*disabledComponents*/,
18914                    ps.readUserState(nextUserId).domainVerificationStatus,
18915                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18916        }
18917        mSettings.writeKernelMappingLPr(ps);
18918    }
18919
18920    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18921            PackageRemovedInfo outInfo) {
18922        final PackageParser.Package pkg;
18923        synchronized (mPackages) {
18924            pkg = mPackages.get(ps.name);
18925        }
18926
18927        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18928                : new int[] {userId};
18929        for (int nextUserId : userIds) {
18930            if (DEBUG_REMOVE) {
18931                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18932                        + nextUserId);
18933            }
18934
18935            destroyAppDataLIF(pkg, userId,
18936                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18937            destroyAppProfilesLIF(pkg, userId);
18938            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18939            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18940            schedulePackageCleaning(ps.name, nextUserId, false);
18941            synchronized (mPackages) {
18942                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18943                    scheduleWritePackageRestrictionsLocked(nextUserId);
18944                }
18945                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18946            }
18947        }
18948
18949        if (outInfo != null) {
18950            outInfo.removedPackage = ps.name;
18951            outInfo.installerPackageName = ps.installerPackageName;
18952            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18953            outInfo.removedAppId = ps.appId;
18954            outInfo.removedUsers = userIds;
18955            outInfo.broadcastUsers = userIds;
18956        }
18957
18958        return true;
18959    }
18960
18961    private final class ClearStorageConnection implements ServiceConnection {
18962        IMediaContainerService mContainerService;
18963
18964        @Override
18965        public void onServiceConnected(ComponentName name, IBinder service) {
18966            synchronized (this) {
18967                mContainerService = IMediaContainerService.Stub
18968                        .asInterface(Binder.allowBlocking(service));
18969                notifyAll();
18970            }
18971        }
18972
18973        @Override
18974        public void onServiceDisconnected(ComponentName name) {
18975        }
18976    }
18977
18978    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18979        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18980
18981        final boolean mounted;
18982        if (Environment.isExternalStorageEmulated()) {
18983            mounted = true;
18984        } else {
18985            final String status = Environment.getExternalStorageState();
18986
18987            mounted = status.equals(Environment.MEDIA_MOUNTED)
18988                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18989        }
18990
18991        if (!mounted) {
18992            return;
18993        }
18994
18995        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18996        int[] users;
18997        if (userId == UserHandle.USER_ALL) {
18998            users = sUserManager.getUserIds();
18999        } else {
19000            users = new int[] { userId };
19001        }
19002        final ClearStorageConnection conn = new ClearStorageConnection();
19003        if (mContext.bindServiceAsUser(
19004                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19005            try {
19006                for (int curUser : users) {
19007                    long timeout = SystemClock.uptimeMillis() + 5000;
19008                    synchronized (conn) {
19009                        long now;
19010                        while (conn.mContainerService == null &&
19011                                (now = SystemClock.uptimeMillis()) < timeout) {
19012                            try {
19013                                conn.wait(timeout - now);
19014                            } catch (InterruptedException e) {
19015                            }
19016                        }
19017                    }
19018                    if (conn.mContainerService == null) {
19019                        return;
19020                    }
19021
19022                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19023                    clearDirectory(conn.mContainerService,
19024                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19025                    if (allData) {
19026                        clearDirectory(conn.mContainerService,
19027                                userEnv.buildExternalStorageAppDataDirs(packageName));
19028                        clearDirectory(conn.mContainerService,
19029                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19030                    }
19031                }
19032            } finally {
19033                mContext.unbindService(conn);
19034            }
19035        }
19036    }
19037
19038    @Override
19039    public void clearApplicationProfileData(String packageName) {
19040        enforceSystemOrRoot("Only the system can clear all profile data");
19041
19042        final PackageParser.Package pkg;
19043        synchronized (mPackages) {
19044            pkg = mPackages.get(packageName);
19045        }
19046
19047        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19048            synchronized (mInstallLock) {
19049                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19050            }
19051        }
19052    }
19053
19054    @Override
19055    public void clearApplicationUserData(final String packageName,
19056            final IPackageDataObserver observer, final int userId) {
19057        mContext.enforceCallingOrSelfPermission(
19058                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19059
19060        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19061                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19062
19063        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19064            throw new SecurityException("Cannot clear data for a protected package: "
19065                    + packageName);
19066        }
19067        // Queue up an async operation since the package deletion may take a little while.
19068        mHandler.post(new Runnable() {
19069            public void run() {
19070                mHandler.removeCallbacks(this);
19071                final boolean succeeded;
19072                try (PackageFreezer freezer = freezePackage(packageName,
19073                        "clearApplicationUserData")) {
19074                    synchronized (mInstallLock) {
19075                        succeeded = clearApplicationUserDataLIF(packageName, userId);
19076                    }
19077                    clearExternalStorageDataSync(packageName, userId, true);
19078                    synchronized (mPackages) {
19079                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19080                                packageName, userId);
19081                    }
19082                }
19083                if (succeeded) {
19084                    // invoke DeviceStorageMonitor's update method to clear any notifications
19085                    DeviceStorageMonitorInternal dsm = LocalServices
19086                            .getService(DeviceStorageMonitorInternal.class);
19087                    if (dsm != null) {
19088                        dsm.checkMemory();
19089                    }
19090                }
19091                if(observer != null) {
19092                    try {
19093                        observer.onRemoveCompleted(packageName, succeeded);
19094                    } catch (RemoteException e) {
19095                        Log.i(TAG, "Observer no longer exists.");
19096                    }
19097                } //end if observer
19098            } //end run
19099        });
19100    }
19101
19102    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19103        if (packageName == null) {
19104            Slog.w(TAG, "Attempt to delete null packageName.");
19105            return false;
19106        }
19107
19108        // Try finding details about the requested package
19109        PackageParser.Package pkg;
19110        synchronized (mPackages) {
19111            pkg = mPackages.get(packageName);
19112            if (pkg == null) {
19113                final PackageSetting ps = mSettings.mPackages.get(packageName);
19114                if (ps != null) {
19115                    pkg = ps.pkg;
19116                }
19117            }
19118
19119            if (pkg == null) {
19120                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19121                return false;
19122            }
19123
19124            PackageSetting ps = (PackageSetting) pkg.mExtras;
19125            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19126        }
19127
19128        clearAppDataLIF(pkg, userId,
19129                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19130
19131        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19132        removeKeystoreDataIfNeeded(userId, appId);
19133
19134        UserManagerInternal umInternal = getUserManagerInternal();
19135        final int flags;
19136        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19137            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19138        } else if (umInternal.isUserRunning(userId)) {
19139            flags = StorageManager.FLAG_STORAGE_DE;
19140        } else {
19141            flags = 0;
19142        }
19143        prepareAppDataContentsLIF(pkg, userId, flags);
19144
19145        return true;
19146    }
19147
19148    /**
19149     * Reverts user permission state changes (permissions and flags) in
19150     * all packages for a given user.
19151     *
19152     * @param userId The device user for which to do a reset.
19153     */
19154    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19155        final int packageCount = mPackages.size();
19156        for (int i = 0; i < packageCount; i++) {
19157            PackageParser.Package pkg = mPackages.valueAt(i);
19158            PackageSetting ps = (PackageSetting) pkg.mExtras;
19159            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19160        }
19161    }
19162
19163    private void resetNetworkPolicies(int userId) {
19164        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19165    }
19166
19167    /**
19168     * Reverts user permission state changes (permissions and flags).
19169     *
19170     * @param ps The package for which to reset.
19171     * @param userId The device user for which to do a reset.
19172     */
19173    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19174            final PackageSetting ps, final int userId) {
19175        if (ps.pkg == null) {
19176            return;
19177        }
19178
19179        // These are flags that can change base on user actions.
19180        final int userSettableMask = FLAG_PERMISSION_USER_SET
19181                | FLAG_PERMISSION_USER_FIXED
19182                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19183                | FLAG_PERMISSION_REVIEW_REQUIRED;
19184
19185        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19186                | FLAG_PERMISSION_POLICY_FIXED;
19187
19188        boolean writeInstallPermissions = false;
19189        boolean writeRuntimePermissions = false;
19190
19191        final int permissionCount = ps.pkg.requestedPermissions.size();
19192        for (int i = 0; i < permissionCount; i++) {
19193            String permission = ps.pkg.requestedPermissions.get(i);
19194
19195            BasePermission bp = mSettings.mPermissions.get(permission);
19196            if (bp == null) {
19197                continue;
19198            }
19199
19200            // If shared user we just reset the state to which only this app contributed.
19201            if (ps.sharedUser != null) {
19202                boolean used = false;
19203                final int packageCount = ps.sharedUser.packages.size();
19204                for (int j = 0; j < packageCount; j++) {
19205                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19206                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19207                            && pkg.pkg.requestedPermissions.contains(permission)) {
19208                        used = true;
19209                        break;
19210                    }
19211                }
19212                if (used) {
19213                    continue;
19214                }
19215            }
19216
19217            PermissionsState permissionsState = ps.getPermissionsState();
19218
19219            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
19220
19221            // Always clear the user settable flags.
19222            final boolean hasInstallState = permissionsState.getInstallPermissionState(
19223                    bp.name) != null;
19224            // If permission review is enabled and this is a legacy app, mark the
19225            // permission as requiring a review as this is the initial state.
19226            int flags = 0;
19227            if (mPermissionReviewRequired
19228                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19229                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19230            }
19231            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19232                if (hasInstallState) {
19233                    writeInstallPermissions = true;
19234                } else {
19235                    writeRuntimePermissions = true;
19236                }
19237            }
19238
19239            // Below is only runtime permission handling.
19240            if (!bp.isRuntime()) {
19241                continue;
19242            }
19243
19244            // Never clobber system or policy.
19245            if ((oldFlags & policyOrSystemFlags) != 0) {
19246                continue;
19247            }
19248
19249            // If this permission was granted by default, make sure it is.
19250            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19251                if (permissionsState.grantRuntimePermission(bp, userId)
19252                        != PERMISSION_OPERATION_FAILURE) {
19253                    writeRuntimePermissions = true;
19254                }
19255            // If permission review is enabled the permissions for a legacy apps
19256            // are represented as constantly granted runtime ones, so don't revoke.
19257            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19258                // Otherwise, reset the permission.
19259                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19260                switch (revokeResult) {
19261                    case PERMISSION_OPERATION_SUCCESS:
19262                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19263                        writeRuntimePermissions = true;
19264                        final int appId = ps.appId;
19265                        mHandler.post(new Runnable() {
19266                            @Override
19267                            public void run() {
19268                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19269                            }
19270                        });
19271                    } break;
19272                }
19273            }
19274        }
19275
19276        // Synchronously write as we are taking permissions away.
19277        if (writeRuntimePermissions) {
19278            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19279        }
19280
19281        // Synchronously write as we are taking permissions away.
19282        if (writeInstallPermissions) {
19283            mSettings.writeLPr();
19284        }
19285    }
19286
19287    /**
19288     * Remove entries from the keystore daemon. Will only remove it if the
19289     * {@code appId} is valid.
19290     */
19291    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19292        if (appId < 0) {
19293            return;
19294        }
19295
19296        final KeyStore keyStore = KeyStore.getInstance();
19297        if (keyStore != null) {
19298            if (userId == UserHandle.USER_ALL) {
19299                for (final int individual : sUserManager.getUserIds()) {
19300                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19301                }
19302            } else {
19303                keyStore.clearUid(UserHandle.getUid(userId, appId));
19304            }
19305        } else {
19306            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19307        }
19308    }
19309
19310    @Override
19311    public void deleteApplicationCacheFiles(final String packageName,
19312            final IPackageDataObserver observer) {
19313        final int userId = UserHandle.getCallingUserId();
19314        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19315    }
19316
19317    @Override
19318    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19319            final IPackageDataObserver observer) {
19320        mContext.enforceCallingOrSelfPermission(
19321                android.Manifest.permission.DELETE_CACHE_FILES, null);
19322        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19323                /* requireFullPermission= */ true, /* checkShell= */ false,
19324                "delete application cache files");
19325
19326        final PackageParser.Package pkg;
19327        synchronized (mPackages) {
19328            pkg = mPackages.get(packageName);
19329        }
19330
19331        // Queue up an async operation since the package deletion may take a little while.
19332        mHandler.post(new Runnable() {
19333            public void run() {
19334                synchronized (mInstallLock) {
19335                    final int flags = StorageManager.FLAG_STORAGE_DE
19336                            | StorageManager.FLAG_STORAGE_CE;
19337                    // We're only clearing cache files, so we don't care if the
19338                    // app is unfrozen and still able to run
19339                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19340                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19341                }
19342                clearExternalStorageDataSync(packageName, userId, false);
19343                if (observer != null) {
19344                    try {
19345                        observer.onRemoveCompleted(packageName, true);
19346                    } catch (RemoteException e) {
19347                        Log.i(TAG, "Observer no longer exists.");
19348                    }
19349                }
19350            }
19351        });
19352    }
19353
19354    @Override
19355    public void getPackageSizeInfo(final String packageName, int userHandle,
19356            final IPackageStatsObserver observer) {
19357        throw new UnsupportedOperationException(
19358                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19359    }
19360
19361    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19362        final PackageSetting ps;
19363        synchronized (mPackages) {
19364            ps = mSettings.mPackages.get(packageName);
19365            if (ps == null) {
19366                Slog.w(TAG, "Failed to find settings for " + packageName);
19367                return false;
19368            }
19369        }
19370
19371        final String[] packageNames = { packageName };
19372        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19373        final String[] codePaths = { ps.codePathString };
19374
19375        try {
19376            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19377                    ps.appId, ceDataInodes, codePaths, stats);
19378
19379            // For now, ignore code size of packages on system partition
19380            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19381                stats.codeSize = 0;
19382            }
19383
19384            // External clients expect these to be tracked separately
19385            stats.dataSize -= stats.cacheSize;
19386
19387        } catch (InstallerException e) {
19388            Slog.w(TAG, String.valueOf(e));
19389            return false;
19390        }
19391
19392        return true;
19393    }
19394
19395    private int getUidTargetSdkVersionLockedLPr(int uid) {
19396        Object obj = mSettings.getUserIdLPr(uid);
19397        if (obj instanceof SharedUserSetting) {
19398            final SharedUserSetting sus = (SharedUserSetting) obj;
19399            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19400            final Iterator<PackageSetting> it = sus.packages.iterator();
19401            while (it.hasNext()) {
19402                final PackageSetting ps = it.next();
19403                if (ps.pkg != null) {
19404                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19405                    if (v < vers) vers = v;
19406                }
19407            }
19408            return vers;
19409        } else if (obj instanceof PackageSetting) {
19410            final PackageSetting ps = (PackageSetting) obj;
19411            if (ps.pkg != null) {
19412                return ps.pkg.applicationInfo.targetSdkVersion;
19413            }
19414        }
19415        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19416    }
19417
19418    @Override
19419    public void addPreferredActivity(IntentFilter filter, int match,
19420            ComponentName[] set, ComponentName activity, int userId) {
19421        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19422                "Adding preferred");
19423    }
19424
19425    private void addPreferredActivityInternal(IntentFilter filter, int match,
19426            ComponentName[] set, ComponentName activity, boolean always, int userId,
19427            String opname) {
19428        // writer
19429        int callingUid = Binder.getCallingUid();
19430        enforceCrossUserPermission(callingUid, userId,
19431                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19432        if (filter.countActions() == 0) {
19433            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19434            return;
19435        }
19436        synchronized (mPackages) {
19437            if (mContext.checkCallingOrSelfPermission(
19438                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19439                    != PackageManager.PERMISSION_GRANTED) {
19440                if (getUidTargetSdkVersionLockedLPr(callingUid)
19441                        < Build.VERSION_CODES.FROYO) {
19442                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19443                            + callingUid);
19444                    return;
19445                }
19446                mContext.enforceCallingOrSelfPermission(
19447                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19448            }
19449
19450            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19451            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19452                    + userId + ":");
19453            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19454            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19455            scheduleWritePackageRestrictionsLocked(userId);
19456            postPreferredActivityChangedBroadcast(userId);
19457        }
19458    }
19459
19460    private void postPreferredActivityChangedBroadcast(int userId) {
19461        mHandler.post(() -> {
19462            final IActivityManager am = ActivityManager.getService();
19463            if (am == null) {
19464                return;
19465            }
19466
19467            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19468            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19469            try {
19470                am.broadcastIntent(null, intent, null, null,
19471                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19472                        null, false, false, userId);
19473            } catch (RemoteException e) {
19474            }
19475        });
19476    }
19477
19478    @Override
19479    public void replacePreferredActivity(IntentFilter filter, int match,
19480            ComponentName[] set, ComponentName activity, int userId) {
19481        if (filter.countActions() != 1) {
19482            throw new IllegalArgumentException(
19483                    "replacePreferredActivity expects filter to have only 1 action.");
19484        }
19485        if (filter.countDataAuthorities() != 0
19486                || filter.countDataPaths() != 0
19487                || filter.countDataSchemes() > 1
19488                || filter.countDataTypes() != 0) {
19489            throw new IllegalArgumentException(
19490                    "replacePreferredActivity expects filter to have no data authorities, " +
19491                    "paths, or types; and at most one scheme.");
19492        }
19493
19494        final int callingUid = Binder.getCallingUid();
19495        enforceCrossUserPermission(callingUid, userId,
19496                true /* requireFullPermission */, false /* checkShell */,
19497                "replace preferred activity");
19498        synchronized (mPackages) {
19499            if (mContext.checkCallingOrSelfPermission(
19500                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19501                    != PackageManager.PERMISSION_GRANTED) {
19502                if (getUidTargetSdkVersionLockedLPr(callingUid)
19503                        < Build.VERSION_CODES.FROYO) {
19504                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19505                            + Binder.getCallingUid());
19506                    return;
19507                }
19508                mContext.enforceCallingOrSelfPermission(
19509                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19510            }
19511
19512            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19513            if (pir != null) {
19514                // Get all of the existing entries that exactly match this filter.
19515                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19516                if (existing != null && existing.size() == 1) {
19517                    PreferredActivity cur = existing.get(0);
19518                    if (DEBUG_PREFERRED) {
19519                        Slog.i(TAG, "Checking replace of preferred:");
19520                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19521                        if (!cur.mPref.mAlways) {
19522                            Slog.i(TAG, "  -- CUR; not mAlways!");
19523                        } else {
19524                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19525                            Slog.i(TAG, "  -- CUR: mSet="
19526                                    + Arrays.toString(cur.mPref.mSetComponents));
19527                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19528                            Slog.i(TAG, "  -- NEW: mMatch="
19529                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19530                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19531                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19532                        }
19533                    }
19534                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19535                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19536                            && cur.mPref.sameSet(set)) {
19537                        // Setting the preferred activity to what it happens to be already
19538                        if (DEBUG_PREFERRED) {
19539                            Slog.i(TAG, "Replacing with same preferred activity "
19540                                    + cur.mPref.mShortComponent + " for user "
19541                                    + userId + ":");
19542                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19543                        }
19544                        return;
19545                    }
19546                }
19547
19548                if (existing != null) {
19549                    if (DEBUG_PREFERRED) {
19550                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19551                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19552                    }
19553                    for (int i = 0; i < existing.size(); i++) {
19554                        PreferredActivity pa = existing.get(i);
19555                        if (DEBUG_PREFERRED) {
19556                            Slog.i(TAG, "Removing existing preferred activity "
19557                                    + pa.mPref.mComponent + ":");
19558                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19559                        }
19560                        pir.removeFilter(pa);
19561                    }
19562                }
19563            }
19564            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19565                    "Replacing preferred");
19566        }
19567    }
19568
19569    @Override
19570    public void clearPackagePreferredActivities(String packageName) {
19571        final int uid = Binder.getCallingUid();
19572        // writer
19573        synchronized (mPackages) {
19574            PackageParser.Package pkg = mPackages.get(packageName);
19575            if (pkg == null || pkg.applicationInfo.uid != uid) {
19576                if (mContext.checkCallingOrSelfPermission(
19577                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19578                        != PackageManager.PERMISSION_GRANTED) {
19579                    if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
19580                            < Build.VERSION_CODES.FROYO) {
19581                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19582                                + Binder.getCallingUid());
19583                        return;
19584                    }
19585                    mContext.enforceCallingOrSelfPermission(
19586                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19587                }
19588            }
19589
19590            int user = UserHandle.getCallingUserId();
19591            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19592                scheduleWritePackageRestrictionsLocked(user);
19593            }
19594        }
19595    }
19596
19597    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19598    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19599        ArrayList<PreferredActivity> removed = null;
19600        boolean changed = false;
19601        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19602            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19603            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19604            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19605                continue;
19606            }
19607            Iterator<PreferredActivity> it = pir.filterIterator();
19608            while (it.hasNext()) {
19609                PreferredActivity pa = it.next();
19610                // Mark entry for removal only if it matches the package name
19611                // and the entry is of type "always".
19612                if (packageName == null ||
19613                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19614                                && pa.mPref.mAlways)) {
19615                    if (removed == null) {
19616                        removed = new ArrayList<PreferredActivity>();
19617                    }
19618                    removed.add(pa);
19619                }
19620            }
19621            if (removed != null) {
19622                for (int j=0; j<removed.size(); j++) {
19623                    PreferredActivity pa = removed.get(j);
19624                    pir.removeFilter(pa);
19625                }
19626                changed = true;
19627            }
19628        }
19629        if (changed) {
19630            postPreferredActivityChangedBroadcast(userId);
19631        }
19632        return changed;
19633    }
19634
19635    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19636    private void clearIntentFilterVerificationsLPw(int userId) {
19637        final int packageCount = mPackages.size();
19638        for (int i = 0; i < packageCount; i++) {
19639            PackageParser.Package pkg = mPackages.valueAt(i);
19640            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19641        }
19642    }
19643
19644    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19645    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19646        if (userId == UserHandle.USER_ALL) {
19647            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19648                    sUserManager.getUserIds())) {
19649                for (int oneUserId : sUserManager.getUserIds()) {
19650                    scheduleWritePackageRestrictionsLocked(oneUserId);
19651                }
19652            }
19653        } else {
19654            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19655                scheduleWritePackageRestrictionsLocked(userId);
19656            }
19657        }
19658    }
19659
19660    /** Clears state for all users, and touches intent filter verification policy */
19661    void clearDefaultBrowserIfNeeded(String packageName) {
19662        for (int oneUserId : sUserManager.getUserIds()) {
19663            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19664        }
19665    }
19666
19667    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19668        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19669        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19670            if (packageName.equals(defaultBrowserPackageName)) {
19671                setDefaultBrowserPackageName(null, userId);
19672            }
19673        }
19674    }
19675
19676    @Override
19677    public void resetApplicationPreferences(int userId) {
19678        mContext.enforceCallingOrSelfPermission(
19679                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19680        final long identity = Binder.clearCallingIdentity();
19681        // writer
19682        try {
19683            synchronized (mPackages) {
19684                clearPackagePreferredActivitiesLPw(null, userId);
19685                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19686                // TODO: We have to reset the default SMS and Phone. This requires
19687                // significant refactoring to keep all default apps in the package
19688                // manager (cleaner but more work) or have the services provide
19689                // callbacks to the package manager to request a default app reset.
19690                applyFactoryDefaultBrowserLPw(userId);
19691                clearIntentFilterVerificationsLPw(userId);
19692                primeDomainVerificationsLPw(userId);
19693                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19694                scheduleWritePackageRestrictionsLocked(userId);
19695            }
19696            resetNetworkPolicies(userId);
19697        } finally {
19698            Binder.restoreCallingIdentity(identity);
19699        }
19700    }
19701
19702    @Override
19703    public int getPreferredActivities(List<IntentFilter> outFilters,
19704            List<ComponentName> outActivities, String packageName) {
19705
19706        int num = 0;
19707        final int userId = UserHandle.getCallingUserId();
19708        // reader
19709        synchronized (mPackages) {
19710            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19711            if (pir != null) {
19712                final Iterator<PreferredActivity> it = pir.filterIterator();
19713                while (it.hasNext()) {
19714                    final PreferredActivity pa = it.next();
19715                    if (packageName == null
19716                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19717                                    && pa.mPref.mAlways)) {
19718                        if (outFilters != null) {
19719                            outFilters.add(new IntentFilter(pa));
19720                        }
19721                        if (outActivities != null) {
19722                            outActivities.add(pa.mPref.mComponent);
19723                        }
19724                    }
19725                }
19726            }
19727        }
19728
19729        return num;
19730    }
19731
19732    @Override
19733    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19734            int userId) {
19735        int callingUid = Binder.getCallingUid();
19736        if (callingUid != Process.SYSTEM_UID) {
19737            throw new SecurityException(
19738                    "addPersistentPreferredActivity can only be run by the system");
19739        }
19740        if (filter.countActions() == 0) {
19741            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19742            return;
19743        }
19744        synchronized (mPackages) {
19745            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19746                    ":");
19747            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19748            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19749                    new PersistentPreferredActivity(filter, activity));
19750            scheduleWritePackageRestrictionsLocked(userId);
19751            postPreferredActivityChangedBroadcast(userId);
19752        }
19753    }
19754
19755    @Override
19756    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19757        int callingUid = Binder.getCallingUid();
19758        if (callingUid != Process.SYSTEM_UID) {
19759            throw new SecurityException(
19760                    "clearPackagePersistentPreferredActivities can only be run by the system");
19761        }
19762        ArrayList<PersistentPreferredActivity> removed = null;
19763        boolean changed = false;
19764        synchronized (mPackages) {
19765            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19766                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19767                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19768                        .valueAt(i);
19769                if (userId != thisUserId) {
19770                    continue;
19771                }
19772                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19773                while (it.hasNext()) {
19774                    PersistentPreferredActivity ppa = it.next();
19775                    // Mark entry for removal only if it matches the package name.
19776                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19777                        if (removed == null) {
19778                            removed = new ArrayList<PersistentPreferredActivity>();
19779                        }
19780                        removed.add(ppa);
19781                    }
19782                }
19783                if (removed != null) {
19784                    for (int j=0; j<removed.size(); j++) {
19785                        PersistentPreferredActivity ppa = removed.get(j);
19786                        ppir.removeFilter(ppa);
19787                    }
19788                    changed = true;
19789                }
19790            }
19791
19792            if (changed) {
19793                scheduleWritePackageRestrictionsLocked(userId);
19794                postPreferredActivityChangedBroadcast(userId);
19795            }
19796        }
19797    }
19798
19799    /**
19800     * Common machinery for picking apart a restored XML blob and passing
19801     * it to a caller-supplied functor to be applied to the running system.
19802     */
19803    private void restoreFromXml(XmlPullParser parser, int userId,
19804            String expectedStartTag, BlobXmlRestorer functor)
19805            throws IOException, XmlPullParserException {
19806        int type;
19807        while ((type = parser.next()) != XmlPullParser.START_TAG
19808                && type != XmlPullParser.END_DOCUMENT) {
19809        }
19810        if (type != XmlPullParser.START_TAG) {
19811            // oops didn't find a start tag?!
19812            if (DEBUG_BACKUP) {
19813                Slog.e(TAG, "Didn't find start tag during restore");
19814            }
19815            return;
19816        }
19817Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19818        // this is supposed to be TAG_PREFERRED_BACKUP
19819        if (!expectedStartTag.equals(parser.getName())) {
19820            if (DEBUG_BACKUP) {
19821                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19822            }
19823            return;
19824        }
19825
19826        // skip interfering stuff, then we're aligned with the backing implementation
19827        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19828Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19829        functor.apply(parser, userId);
19830    }
19831
19832    private interface BlobXmlRestorer {
19833        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19834    }
19835
19836    /**
19837     * Non-Binder method, support for the backup/restore mechanism: write the
19838     * full set of preferred activities in its canonical XML format.  Returns the
19839     * XML output as a byte array, or null if there is none.
19840     */
19841    @Override
19842    public byte[] getPreferredActivityBackup(int userId) {
19843        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19844            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19845        }
19846
19847        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19848        try {
19849            final XmlSerializer serializer = new FastXmlSerializer();
19850            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19851            serializer.startDocument(null, true);
19852            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19853
19854            synchronized (mPackages) {
19855                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19856            }
19857
19858            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19859            serializer.endDocument();
19860            serializer.flush();
19861        } catch (Exception e) {
19862            if (DEBUG_BACKUP) {
19863                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19864            }
19865            return null;
19866        }
19867
19868        return dataStream.toByteArray();
19869    }
19870
19871    @Override
19872    public void restorePreferredActivities(byte[] backup, int userId) {
19873        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19874            throw new SecurityException("Only the system may call restorePreferredActivities()");
19875        }
19876
19877        try {
19878            final XmlPullParser parser = Xml.newPullParser();
19879            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19880            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19881                    new BlobXmlRestorer() {
19882                        @Override
19883                        public void apply(XmlPullParser parser, int userId)
19884                                throws XmlPullParserException, IOException {
19885                            synchronized (mPackages) {
19886                                mSettings.readPreferredActivitiesLPw(parser, userId);
19887                            }
19888                        }
19889                    } );
19890        } catch (Exception e) {
19891            if (DEBUG_BACKUP) {
19892                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19893            }
19894        }
19895    }
19896
19897    /**
19898     * Non-Binder method, support for the backup/restore mechanism: write the
19899     * default browser (etc) settings in its canonical XML format.  Returns the default
19900     * browser XML representation as a byte array, or null if there is none.
19901     */
19902    @Override
19903    public byte[] getDefaultAppsBackup(int userId) {
19904        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19905            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19906        }
19907
19908        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19909        try {
19910            final XmlSerializer serializer = new FastXmlSerializer();
19911            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19912            serializer.startDocument(null, true);
19913            serializer.startTag(null, TAG_DEFAULT_APPS);
19914
19915            synchronized (mPackages) {
19916                mSettings.writeDefaultAppsLPr(serializer, userId);
19917            }
19918
19919            serializer.endTag(null, TAG_DEFAULT_APPS);
19920            serializer.endDocument();
19921            serializer.flush();
19922        } catch (Exception e) {
19923            if (DEBUG_BACKUP) {
19924                Slog.e(TAG, "Unable to write default apps for backup", e);
19925            }
19926            return null;
19927        }
19928
19929        return dataStream.toByteArray();
19930    }
19931
19932    @Override
19933    public void restoreDefaultApps(byte[] backup, int userId) {
19934        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19935            throw new SecurityException("Only the system may call restoreDefaultApps()");
19936        }
19937
19938        try {
19939            final XmlPullParser parser = Xml.newPullParser();
19940            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19941            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19942                    new BlobXmlRestorer() {
19943                        @Override
19944                        public void apply(XmlPullParser parser, int userId)
19945                                throws XmlPullParserException, IOException {
19946                            synchronized (mPackages) {
19947                                mSettings.readDefaultAppsLPw(parser, userId);
19948                            }
19949                        }
19950                    } );
19951        } catch (Exception e) {
19952            if (DEBUG_BACKUP) {
19953                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19954            }
19955        }
19956    }
19957
19958    @Override
19959    public byte[] getIntentFilterVerificationBackup(int userId) {
19960        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19961            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19962        }
19963
19964        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19965        try {
19966            final XmlSerializer serializer = new FastXmlSerializer();
19967            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19968            serializer.startDocument(null, true);
19969            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19970
19971            synchronized (mPackages) {
19972                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19973            }
19974
19975            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19976            serializer.endDocument();
19977            serializer.flush();
19978        } catch (Exception e) {
19979            if (DEBUG_BACKUP) {
19980                Slog.e(TAG, "Unable to write default apps for backup", e);
19981            }
19982            return null;
19983        }
19984
19985        return dataStream.toByteArray();
19986    }
19987
19988    @Override
19989    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19990        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19991            throw new SecurityException("Only the system may call restorePreferredActivities()");
19992        }
19993
19994        try {
19995            final XmlPullParser parser = Xml.newPullParser();
19996            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19997            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19998                    new BlobXmlRestorer() {
19999                        @Override
20000                        public void apply(XmlPullParser parser, int userId)
20001                                throws XmlPullParserException, IOException {
20002                            synchronized (mPackages) {
20003                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20004                                mSettings.writeLPr();
20005                            }
20006                        }
20007                    } );
20008        } catch (Exception e) {
20009            if (DEBUG_BACKUP) {
20010                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20011            }
20012        }
20013    }
20014
20015    @Override
20016    public byte[] getPermissionGrantBackup(int userId) {
20017        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20018            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20019        }
20020
20021        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20022        try {
20023            final XmlSerializer serializer = new FastXmlSerializer();
20024            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20025            serializer.startDocument(null, true);
20026            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20027
20028            synchronized (mPackages) {
20029                serializeRuntimePermissionGrantsLPr(serializer, userId);
20030            }
20031
20032            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20033            serializer.endDocument();
20034            serializer.flush();
20035        } catch (Exception e) {
20036            if (DEBUG_BACKUP) {
20037                Slog.e(TAG, "Unable to write default apps for backup", e);
20038            }
20039            return null;
20040        }
20041
20042        return dataStream.toByteArray();
20043    }
20044
20045    @Override
20046    public void restorePermissionGrants(byte[] backup, int userId) {
20047        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20048            throw new SecurityException("Only the system may call restorePermissionGrants()");
20049        }
20050
20051        try {
20052            final XmlPullParser parser = Xml.newPullParser();
20053            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20054            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20055                    new BlobXmlRestorer() {
20056                        @Override
20057                        public void apply(XmlPullParser parser, int userId)
20058                                throws XmlPullParserException, IOException {
20059                            synchronized (mPackages) {
20060                                processRestoredPermissionGrantsLPr(parser, userId);
20061                            }
20062                        }
20063                    } );
20064        } catch (Exception e) {
20065            if (DEBUG_BACKUP) {
20066                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20067            }
20068        }
20069    }
20070
20071    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20072            throws IOException {
20073        serializer.startTag(null, TAG_ALL_GRANTS);
20074
20075        final int N = mSettings.mPackages.size();
20076        for (int i = 0; i < N; i++) {
20077            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20078            boolean pkgGrantsKnown = false;
20079
20080            PermissionsState packagePerms = ps.getPermissionsState();
20081
20082            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20083                final int grantFlags = state.getFlags();
20084                // only look at grants that are not system/policy fixed
20085                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20086                    final boolean isGranted = state.isGranted();
20087                    // And only back up the user-twiddled state bits
20088                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20089                        final String packageName = mSettings.mPackages.keyAt(i);
20090                        if (!pkgGrantsKnown) {
20091                            serializer.startTag(null, TAG_GRANT);
20092                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20093                            pkgGrantsKnown = true;
20094                        }
20095
20096                        final boolean userSet =
20097                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20098                        final boolean userFixed =
20099                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20100                        final boolean revoke =
20101                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20102
20103                        serializer.startTag(null, TAG_PERMISSION);
20104                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20105                        if (isGranted) {
20106                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20107                        }
20108                        if (userSet) {
20109                            serializer.attribute(null, ATTR_USER_SET, "true");
20110                        }
20111                        if (userFixed) {
20112                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20113                        }
20114                        if (revoke) {
20115                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20116                        }
20117                        serializer.endTag(null, TAG_PERMISSION);
20118                    }
20119                }
20120            }
20121
20122            if (pkgGrantsKnown) {
20123                serializer.endTag(null, TAG_GRANT);
20124            }
20125        }
20126
20127        serializer.endTag(null, TAG_ALL_GRANTS);
20128    }
20129
20130    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20131            throws XmlPullParserException, IOException {
20132        String pkgName = null;
20133        int outerDepth = parser.getDepth();
20134        int type;
20135        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20136                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20137            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20138                continue;
20139            }
20140
20141            final String tagName = parser.getName();
20142            if (tagName.equals(TAG_GRANT)) {
20143                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20144                if (DEBUG_BACKUP) {
20145                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20146                }
20147            } else if (tagName.equals(TAG_PERMISSION)) {
20148
20149                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20150                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20151
20152                int newFlagSet = 0;
20153                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20154                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20155                }
20156                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20157                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20158                }
20159                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20160                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20161                }
20162                if (DEBUG_BACKUP) {
20163                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20164                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20165                }
20166                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20167                if (ps != null) {
20168                    // Already installed so we apply the grant immediately
20169                    if (DEBUG_BACKUP) {
20170                        Slog.v(TAG, "        + already installed; applying");
20171                    }
20172                    PermissionsState perms = ps.getPermissionsState();
20173                    BasePermission bp = mSettings.mPermissions.get(permName);
20174                    if (bp != null) {
20175                        if (isGranted) {
20176                            perms.grantRuntimePermission(bp, userId);
20177                        }
20178                        if (newFlagSet != 0) {
20179                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20180                        }
20181                    }
20182                } else {
20183                    // Need to wait for post-restore install to apply the grant
20184                    if (DEBUG_BACKUP) {
20185                        Slog.v(TAG, "        - not yet installed; saving for later");
20186                    }
20187                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20188                            isGranted, newFlagSet, userId);
20189                }
20190            } else {
20191                PackageManagerService.reportSettingsProblem(Log.WARN,
20192                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20193                XmlUtils.skipCurrentTag(parser);
20194            }
20195        }
20196
20197        scheduleWriteSettingsLocked();
20198        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20199    }
20200
20201    @Override
20202    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20203            int sourceUserId, int targetUserId, int flags) {
20204        mContext.enforceCallingOrSelfPermission(
20205                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20206        int callingUid = Binder.getCallingUid();
20207        enforceOwnerRights(ownerPackage, callingUid);
20208        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20209        if (intentFilter.countActions() == 0) {
20210            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20211            return;
20212        }
20213        synchronized (mPackages) {
20214            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20215                    ownerPackage, targetUserId, flags);
20216            CrossProfileIntentResolver resolver =
20217                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20218            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20219            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20220            if (existing != null) {
20221                int size = existing.size();
20222                for (int i = 0; i < size; i++) {
20223                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20224                        return;
20225                    }
20226                }
20227            }
20228            resolver.addFilter(newFilter);
20229            scheduleWritePackageRestrictionsLocked(sourceUserId);
20230        }
20231    }
20232
20233    @Override
20234    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20235        mContext.enforceCallingOrSelfPermission(
20236                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20237        int callingUid = Binder.getCallingUid();
20238        enforceOwnerRights(ownerPackage, callingUid);
20239        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20240        synchronized (mPackages) {
20241            CrossProfileIntentResolver resolver =
20242                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20243            ArraySet<CrossProfileIntentFilter> set =
20244                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20245            for (CrossProfileIntentFilter filter : set) {
20246                if (filter.getOwnerPackage().equals(ownerPackage)) {
20247                    resolver.removeFilter(filter);
20248                }
20249            }
20250            scheduleWritePackageRestrictionsLocked(sourceUserId);
20251        }
20252    }
20253
20254    // Enforcing that callingUid is owning pkg on userId
20255    private void enforceOwnerRights(String pkg, int callingUid) {
20256        // The system owns everything.
20257        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20258            return;
20259        }
20260        int callingUserId = UserHandle.getUserId(callingUid);
20261        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20262        if (pi == null) {
20263            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20264                    + callingUserId);
20265        }
20266        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20267            throw new SecurityException("Calling uid " + callingUid
20268                    + " does not own package " + pkg);
20269        }
20270    }
20271
20272    @Override
20273    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20274        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20275    }
20276
20277    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20278        UserManagerService ums = UserManagerService.getInstance();
20279        if (ums != null) {
20280            final UserInfo parent = ums.getProfileParent(userId);
20281            final int launcherUid = (parent != null) ? parent.id : userId;
20282            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20283            if (launcherComponent != null) {
20284                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20285                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20286                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20287                        .setPackage(launcherComponent.getPackageName());
20288                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20289            }
20290        }
20291    }
20292
20293    /**
20294     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20295     * then reports the most likely home activity or null if there are more than one.
20296     */
20297    private ComponentName getDefaultHomeActivity(int userId) {
20298        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20299        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20300        if (cn != null) {
20301            return cn;
20302        }
20303
20304        // Find the launcher with the highest priority and return that component if there are no
20305        // other home activity with the same priority.
20306        int lastPriority = Integer.MIN_VALUE;
20307        ComponentName lastComponent = null;
20308        final int size = allHomeCandidates.size();
20309        for (int i = 0; i < size; i++) {
20310            final ResolveInfo ri = allHomeCandidates.get(i);
20311            if (ri.priority > lastPriority) {
20312                lastComponent = ri.activityInfo.getComponentName();
20313                lastPriority = ri.priority;
20314            } else if (ri.priority == lastPriority) {
20315                // Two components found with same priority.
20316                lastComponent = null;
20317            }
20318        }
20319        return lastComponent;
20320    }
20321
20322    private Intent getHomeIntent() {
20323        Intent intent = new Intent(Intent.ACTION_MAIN);
20324        intent.addCategory(Intent.CATEGORY_HOME);
20325        intent.addCategory(Intent.CATEGORY_DEFAULT);
20326        return intent;
20327    }
20328
20329    private IntentFilter getHomeFilter() {
20330        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20331        filter.addCategory(Intent.CATEGORY_HOME);
20332        filter.addCategory(Intent.CATEGORY_DEFAULT);
20333        return filter;
20334    }
20335
20336    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20337            int userId) {
20338        Intent intent  = getHomeIntent();
20339        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20340                PackageManager.GET_META_DATA, userId);
20341        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20342                true, false, false, userId);
20343
20344        allHomeCandidates.clear();
20345        if (list != null) {
20346            for (ResolveInfo ri : list) {
20347                allHomeCandidates.add(ri);
20348            }
20349        }
20350        return (preferred == null || preferred.activityInfo == null)
20351                ? null
20352                : new ComponentName(preferred.activityInfo.packageName,
20353                        preferred.activityInfo.name);
20354    }
20355
20356    @Override
20357    public void setHomeActivity(ComponentName comp, int userId) {
20358        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20359        getHomeActivitiesAsUser(homeActivities, userId);
20360
20361        boolean found = false;
20362
20363        final int size = homeActivities.size();
20364        final ComponentName[] set = new ComponentName[size];
20365        for (int i = 0; i < size; i++) {
20366            final ResolveInfo candidate = homeActivities.get(i);
20367            final ActivityInfo info = candidate.activityInfo;
20368            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20369            set[i] = activityName;
20370            if (!found && activityName.equals(comp)) {
20371                found = true;
20372            }
20373        }
20374        if (!found) {
20375            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20376                    + userId);
20377        }
20378        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20379                set, comp, userId);
20380    }
20381
20382    private @Nullable String getSetupWizardPackageName() {
20383        final Intent intent = new Intent(Intent.ACTION_MAIN);
20384        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20385
20386        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20387                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20388                        | MATCH_DISABLED_COMPONENTS,
20389                UserHandle.myUserId());
20390        if (matches.size() == 1) {
20391            return matches.get(0).getComponentInfo().packageName;
20392        } else {
20393            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20394                    + ": matches=" + matches);
20395            return null;
20396        }
20397    }
20398
20399    private @Nullable String getStorageManagerPackageName() {
20400        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20401
20402        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20403                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20404                        | MATCH_DISABLED_COMPONENTS,
20405                UserHandle.myUserId());
20406        if (matches.size() == 1) {
20407            return matches.get(0).getComponentInfo().packageName;
20408        } else {
20409            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20410                    + matches.size() + ": matches=" + matches);
20411            return null;
20412        }
20413    }
20414
20415    @Override
20416    public void setApplicationEnabledSetting(String appPackageName,
20417            int newState, int flags, int userId, String callingPackage) {
20418        if (!sUserManager.exists(userId)) return;
20419        if (callingPackage == null) {
20420            callingPackage = Integer.toString(Binder.getCallingUid());
20421        }
20422        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20423    }
20424
20425    @Override
20426    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20427        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20428        synchronized (mPackages) {
20429            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20430            if (pkgSetting != null) {
20431                pkgSetting.setUpdateAvailable(updateAvailable);
20432            }
20433        }
20434    }
20435
20436    @Override
20437    public void setComponentEnabledSetting(ComponentName componentName,
20438            int newState, int flags, int userId) {
20439        if (!sUserManager.exists(userId)) return;
20440        setEnabledSetting(componentName.getPackageName(),
20441                componentName.getClassName(), newState, flags, userId, null);
20442    }
20443
20444    private void setEnabledSetting(final String packageName, String className, int newState,
20445            final int flags, int userId, String callingPackage) {
20446        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20447              || newState == COMPONENT_ENABLED_STATE_ENABLED
20448              || newState == COMPONENT_ENABLED_STATE_DISABLED
20449              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20450              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20451            throw new IllegalArgumentException("Invalid new component state: "
20452                    + newState);
20453        }
20454        PackageSetting pkgSetting;
20455        final int uid = Binder.getCallingUid();
20456        final int permission;
20457        if (uid == Process.SYSTEM_UID) {
20458            permission = PackageManager.PERMISSION_GRANTED;
20459        } else {
20460            permission = mContext.checkCallingOrSelfPermission(
20461                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20462        }
20463        enforceCrossUserPermission(uid, userId,
20464                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20465        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20466        boolean sendNow = false;
20467        boolean isApp = (className == null);
20468        String componentName = isApp ? packageName : className;
20469        int packageUid = -1;
20470        ArrayList<String> components;
20471
20472        // writer
20473        synchronized (mPackages) {
20474            pkgSetting = mSettings.mPackages.get(packageName);
20475            if (pkgSetting == null) {
20476                if (className == null) {
20477                    throw new IllegalArgumentException("Unknown package: " + packageName);
20478                }
20479                throw new IllegalArgumentException(
20480                        "Unknown component: " + packageName + "/" + className);
20481            }
20482        }
20483
20484        // Limit who can change which apps
20485        if (!UserHandle.isSameApp(uid, pkgSetting.appId)) {
20486            // Don't allow apps that don't have permission to modify other apps
20487            if (!allowedByPermission) {
20488                throw new SecurityException(
20489                        "Permission Denial: attempt to change component state from pid="
20490                        + Binder.getCallingPid()
20491                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
20492            }
20493            // Don't allow changing protected packages.
20494            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20495                throw new SecurityException("Cannot disable a protected package: " + packageName);
20496            }
20497        }
20498
20499        synchronized (mPackages) {
20500            if (uid == Process.SHELL_UID
20501                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20502                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20503                // unless it is a test package.
20504                int oldState = pkgSetting.getEnabled(userId);
20505                if (className == null
20506                    &&
20507                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20508                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20509                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20510                    &&
20511                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20512                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20513                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20514                    // ok
20515                } else {
20516                    throw new SecurityException(
20517                            "Shell cannot change component state for " + packageName + "/"
20518                            + className + " to " + newState);
20519                }
20520            }
20521            if (className == null) {
20522                // We're dealing with an application/package level state change
20523                if (pkgSetting.getEnabled(userId) == newState) {
20524                    // Nothing to do
20525                    return;
20526                }
20527                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20528                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20529                    // Don't care about who enables an app.
20530                    callingPackage = null;
20531                }
20532                pkgSetting.setEnabled(newState, userId, callingPackage);
20533                // pkgSetting.pkg.mSetEnabled = newState;
20534            } else {
20535                // We're dealing with a component level state change
20536                // First, verify that this is a valid class name.
20537                PackageParser.Package pkg = pkgSetting.pkg;
20538                if (pkg == null || !pkg.hasComponentClassName(className)) {
20539                    if (pkg != null &&
20540                            pkg.applicationInfo.targetSdkVersion >=
20541                                    Build.VERSION_CODES.JELLY_BEAN) {
20542                        throw new IllegalArgumentException("Component class " + className
20543                                + " does not exist in " + packageName);
20544                    } else {
20545                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20546                                + className + " does not exist in " + packageName);
20547                    }
20548                }
20549                switch (newState) {
20550                case COMPONENT_ENABLED_STATE_ENABLED:
20551                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20552                        return;
20553                    }
20554                    break;
20555                case COMPONENT_ENABLED_STATE_DISABLED:
20556                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20557                        return;
20558                    }
20559                    break;
20560                case COMPONENT_ENABLED_STATE_DEFAULT:
20561                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20562                        return;
20563                    }
20564                    break;
20565                default:
20566                    Slog.e(TAG, "Invalid new component state: " + newState);
20567                    return;
20568                }
20569            }
20570            scheduleWritePackageRestrictionsLocked(userId);
20571            updateSequenceNumberLP(packageName, new int[] { userId });
20572            final long callingId = Binder.clearCallingIdentity();
20573            try {
20574                updateInstantAppInstallerLocked(packageName);
20575            } finally {
20576                Binder.restoreCallingIdentity(callingId);
20577            }
20578            components = mPendingBroadcasts.get(userId, packageName);
20579            final boolean newPackage = components == null;
20580            if (newPackage) {
20581                components = new ArrayList<String>();
20582            }
20583            if (!components.contains(componentName)) {
20584                components.add(componentName);
20585            }
20586            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20587                sendNow = true;
20588                // Purge entry from pending broadcast list if another one exists already
20589                // since we are sending one right away.
20590                mPendingBroadcasts.remove(userId, packageName);
20591            } else {
20592                if (newPackage) {
20593                    mPendingBroadcasts.put(userId, packageName, components);
20594                }
20595                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20596                    // Schedule a message
20597                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20598                }
20599            }
20600        }
20601
20602        long callingId = Binder.clearCallingIdentity();
20603        try {
20604            if (sendNow) {
20605                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20606                sendPackageChangedBroadcast(packageName,
20607                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20608            }
20609        } finally {
20610            Binder.restoreCallingIdentity(callingId);
20611        }
20612    }
20613
20614    @Override
20615    public void flushPackageRestrictionsAsUser(int userId) {
20616        if (!sUserManager.exists(userId)) {
20617            return;
20618        }
20619        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20620                false /* checkShell */, "flushPackageRestrictions");
20621        synchronized (mPackages) {
20622            mSettings.writePackageRestrictionsLPr(userId);
20623            mDirtyUsers.remove(userId);
20624            if (mDirtyUsers.isEmpty()) {
20625                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20626            }
20627        }
20628    }
20629
20630    private void sendPackageChangedBroadcast(String packageName,
20631            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20632        if (DEBUG_INSTALL)
20633            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20634                    + componentNames);
20635        Bundle extras = new Bundle(4);
20636        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20637        String nameList[] = new String[componentNames.size()];
20638        componentNames.toArray(nameList);
20639        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20640        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20641        extras.putInt(Intent.EXTRA_UID, packageUid);
20642        // If this is not reporting a change of the overall package, then only send it
20643        // to registered receivers.  We don't want to launch a swath of apps for every
20644        // little component state change.
20645        final int flags = !componentNames.contains(packageName)
20646                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20647        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20648                new int[] {UserHandle.getUserId(packageUid)});
20649    }
20650
20651    @Override
20652    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20653        if (!sUserManager.exists(userId)) return;
20654        final int uid = Binder.getCallingUid();
20655        final int permission = mContext.checkCallingOrSelfPermission(
20656                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20657        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20658        enforceCrossUserPermission(uid, userId,
20659                true /* requireFullPermission */, true /* checkShell */, "stop package");
20660        // writer
20661        synchronized (mPackages) {
20662            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20663                    allowedByPermission, uid, userId)) {
20664                scheduleWritePackageRestrictionsLocked(userId);
20665            }
20666        }
20667    }
20668
20669    @Override
20670    public String getInstallerPackageName(String packageName) {
20671        // reader
20672        synchronized (mPackages) {
20673            return mSettings.getInstallerPackageNameLPr(packageName);
20674        }
20675    }
20676
20677    public boolean isOrphaned(String packageName) {
20678        // reader
20679        synchronized (mPackages) {
20680            return mSettings.isOrphaned(packageName);
20681        }
20682    }
20683
20684    @Override
20685    public int getApplicationEnabledSetting(String packageName, int userId) {
20686        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20687        int uid = Binder.getCallingUid();
20688        enforceCrossUserPermission(uid, userId,
20689                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20690        // reader
20691        synchronized (mPackages) {
20692            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20693        }
20694    }
20695
20696    @Override
20697    public int getComponentEnabledSetting(ComponentName componentName, int userId) {
20698        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20699        int uid = Binder.getCallingUid();
20700        enforceCrossUserPermission(uid, userId,
20701                false /* requireFullPermission */, false /* checkShell */, "get component enabled");
20702        // reader
20703        synchronized (mPackages) {
20704            return mSettings.getComponentEnabledSettingLPr(componentName, userId);
20705        }
20706    }
20707
20708    @Override
20709    public void enterSafeMode() {
20710        enforceSystemOrRoot("Only the system can request entering safe mode");
20711
20712        if (!mSystemReady) {
20713            mSafeMode = true;
20714        }
20715    }
20716
20717    @Override
20718    public void systemReady() {
20719        mSystemReady = true;
20720        final ContentResolver resolver = mContext.getContentResolver();
20721        ContentObserver co = new ContentObserver(mHandler) {
20722            @Override
20723            public void onChange(boolean selfChange) {
20724                mEphemeralAppsDisabled =
20725                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20726                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20727            }
20728        };
20729        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20730                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20731                false, co, UserHandle.USER_SYSTEM);
20732        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20733                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20734        co.onChange(true);
20735
20736        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20737        // disabled after already being started.
20738        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20739                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20740
20741        // Read the compatibilty setting when the system is ready.
20742        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20743                mContext.getContentResolver(),
20744                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20745        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20746        if (DEBUG_SETTINGS) {
20747            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20748        }
20749
20750        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20751
20752        synchronized (mPackages) {
20753            // Verify that all of the preferred activity components actually
20754            // exist.  It is possible for applications to be updated and at
20755            // that point remove a previously declared activity component that
20756            // had been set as a preferred activity.  We try to clean this up
20757            // the next time we encounter that preferred activity, but it is
20758            // possible for the user flow to never be able to return to that
20759            // situation so here we do a sanity check to make sure we haven't
20760            // left any junk around.
20761            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20762            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20763                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20764                removed.clear();
20765                for (PreferredActivity pa : pir.filterSet()) {
20766                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20767                        removed.add(pa);
20768                    }
20769                }
20770                if (removed.size() > 0) {
20771                    for (int r=0; r<removed.size(); r++) {
20772                        PreferredActivity pa = removed.get(r);
20773                        Slog.w(TAG, "Removing dangling preferred activity: "
20774                                + pa.mPref.mComponent);
20775                        pir.removeFilter(pa);
20776                    }
20777                    mSettings.writePackageRestrictionsLPr(
20778                            mSettings.mPreferredActivities.keyAt(i));
20779                }
20780            }
20781
20782            for (int userId : UserManagerService.getInstance().getUserIds()) {
20783                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20784                    grantPermissionsUserIds = ArrayUtils.appendInt(
20785                            grantPermissionsUserIds, userId);
20786                }
20787            }
20788        }
20789        sUserManager.systemReady();
20790
20791        // If we upgraded grant all default permissions before kicking off.
20792        for (int userId : grantPermissionsUserIds) {
20793            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20794        }
20795
20796        // If we did not grant default permissions, we preload from this the
20797        // default permission exceptions lazily to ensure we don't hit the
20798        // disk on a new user creation.
20799        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20800            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20801        }
20802
20803        // Kick off any messages waiting for system ready
20804        if (mPostSystemReadyMessages != null) {
20805            for (Message msg : mPostSystemReadyMessages) {
20806                msg.sendToTarget();
20807            }
20808            mPostSystemReadyMessages = null;
20809        }
20810
20811        // Watch for external volumes that come and go over time
20812        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20813        storage.registerListener(mStorageListener);
20814
20815        mInstallerService.systemReady();
20816        mPackageDexOptimizer.systemReady();
20817
20818        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20819                StorageManagerInternal.class);
20820        StorageManagerInternal.addExternalStoragePolicy(
20821                new StorageManagerInternal.ExternalStorageMountPolicy() {
20822            @Override
20823            public int getMountMode(int uid, String packageName) {
20824                if (Process.isIsolated(uid)) {
20825                    return Zygote.MOUNT_EXTERNAL_NONE;
20826                }
20827                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20828                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20829                }
20830                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20831                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20832                }
20833                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20834                    return Zygote.MOUNT_EXTERNAL_READ;
20835                }
20836                return Zygote.MOUNT_EXTERNAL_WRITE;
20837            }
20838
20839            @Override
20840            public boolean hasExternalStorage(int uid, String packageName) {
20841                return true;
20842            }
20843        });
20844
20845        // Now that we're mostly running, clean up stale users and apps
20846        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20847        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20848
20849        if (mPrivappPermissionsViolations != null) {
20850            Slog.wtf(TAG,"Signature|privileged permissions not in "
20851                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
20852            mPrivappPermissionsViolations = null;
20853        }
20854    }
20855
20856    public void waitForAppDataPrepared() {
20857        if (mPrepareAppDataFuture == null) {
20858            return;
20859        }
20860        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20861        mPrepareAppDataFuture = null;
20862    }
20863
20864    @Override
20865    public boolean isSafeMode() {
20866        return mSafeMode;
20867    }
20868
20869    @Override
20870    public boolean hasSystemUidErrors() {
20871        return mHasSystemUidErrors;
20872    }
20873
20874    static String arrayToString(int[] array) {
20875        StringBuffer buf = new StringBuffer(128);
20876        buf.append('[');
20877        if (array != null) {
20878            for (int i=0; i<array.length; i++) {
20879                if (i > 0) buf.append(", ");
20880                buf.append(array[i]);
20881            }
20882        }
20883        buf.append(']');
20884        return buf.toString();
20885    }
20886
20887    static class DumpState {
20888        public static final int DUMP_LIBS = 1 << 0;
20889        public static final int DUMP_FEATURES = 1 << 1;
20890        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
20891        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
20892        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
20893        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
20894        public static final int DUMP_PERMISSIONS = 1 << 6;
20895        public static final int DUMP_PACKAGES = 1 << 7;
20896        public static final int DUMP_SHARED_USERS = 1 << 8;
20897        public static final int DUMP_MESSAGES = 1 << 9;
20898        public static final int DUMP_PROVIDERS = 1 << 10;
20899        public static final int DUMP_VERIFIERS = 1 << 11;
20900        public static final int DUMP_PREFERRED = 1 << 12;
20901        public static final int DUMP_PREFERRED_XML = 1 << 13;
20902        public static final int DUMP_KEYSETS = 1 << 14;
20903        public static final int DUMP_VERSION = 1 << 15;
20904        public static final int DUMP_INSTALLS = 1 << 16;
20905        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
20906        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
20907        public static final int DUMP_FROZEN = 1 << 19;
20908        public static final int DUMP_DEXOPT = 1 << 20;
20909        public static final int DUMP_COMPILER_STATS = 1 << 21;
20910        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
20911        public static final int DUMP_CHANGES = 1 << 23;
20912
20913        public static final int OPTION_SHOW_FILTERS = 1 << 0;
20914
20915        private int mTypes;
20916
20917        private int mOptions;
20918
20919        private boolean mTitlePrinted;
20920
20921        private SharedUserSetting mSharedUser;
20922
20923        public boolean isDumping(int type) {
20924            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
20925                return true;
20926            }
20927
20928            return (mTypes & type) != 0;
20929        }
20930
20931        public void setDump(int type) {
20932            mTypes |= type;
20933        }
20934
20935        public boolean isOptionEnabled(int option) {
20936            return (mOptions & option) != 0;
20937        }
20938
20939        public void setOptionEnabled(int option) {
20940            mOptions |= option;
20941        }
20942
20943        public boolean onTitlePrinted() {
20944            final boolean printed = mTitlePrinted;
20945            mTitlePrinted = true;
20946            return printed;
20947        }
20948
20949        public boolean getTitlePrinted() {
20950            return mTitlePrinted;
20951        }
20952
20953        public void setTitlePrinted(boolean enabled) {
20954            mTitlePrinted = enabled;
20955        }
20956
20957        public SharedUserSetting getSharedUser() {
20958            return mSharedUser;
20959        }
20960
20961        public void setSharedUser(SharedUserSetting user) {
20962            mSharedUser = user;
20963        }
20964    }
20965
20966    @Override
20967    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20968            FileDescriptor err, String[] args, ShellCallback callback,
20969            ResultReceiver resultReceiver) {
20970        (new PackageManagerShellCommand(this)).exec(
20971                this, in, out, err, args, callback, resultReceiver);
20972    }
20973
20974    @Override
20975    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20976        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20977
20978        DumpState dumpState = new DumpState();
20979        boolean fullPreferred = false;
20980        boolean checkin = false;
20981
20982        String packageName = null;
20983        ArraySet<String> permissionNames = null;
20984
20985        int opti = 0;
20986        while (opti < args.length) {
20987            String opt = args[opti];
20988            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20989                break;
20990            }
20991            opti++;
20992
20993            if ("-a".equals(opt)) {
20994                // Right now we only know how to print all.
20995            } else if ("-h".equals(opt)) {
20996                pw.println("Package manager dump options:");
20997                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20998                pw.println("    --checkin: dump for a checkin");
20999                pw.println("    -f: print details of intent filters");
21000                pw.println("    -h: print this help");
21001                pw.println("  cmd may be one of:");
21002                pw.println("    l[ibraries]: list known shared libraries");
21003                pw.println("    f[eatures]: list device features");
21004                pw.println("    k[eysets]: print known keysets");
21005                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21006                pw.println("    perm[issions]: dump permissions");
21007                pw.println("    permission [name ...]: dump declaration and use of given permission");
21008                pw.println("    pref[erred]: print preferred package settings");
21009                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21010                pw.println("    prov[iders]: dump content providers");
21011                pw.println("    p[ackages]: dump installed packages");
21012                pw.println("    s[hared-users]: dump shared user IDs");
21013                pw.println("    m[essages]: print collected runtime messages");
21014                pw.println("    v[erifiers]: print package verifier info");
21015                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21016                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21017                pw.println("    version: print database version info");
21018                pw.println("    write: write current settings now");
21019                pw.println("    installs: details about install sessions");
21020                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21021                pw.println("    dexopt: dump dexopt state");
21022                pw.println("    compiler-stats: dump compiler statistics");
21023                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21024                pw.println("    <package.name>: info about given package");
21025                return;
21026            } else if ("--checkin".equals(opt)) {
21027                checkin = true;
21028            } else if ("-f".equals(opt)) {
21029                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21030            } else if ("--proto".equals(opt)) {
21031                dumpProto(fd);
21032                return;
21033            } else {
21034                pw.println("Unknown argument: " + opt + "; use -h for help");
21035            }
21036        }
21037
21038        // Is the caller requesting to dump a particular piece of data?
21039        if (opti < args.length) {
21040            String cmd = args[opti];
21041            opti++;
21042            // Is this a package name?
21043            if ("android".equals(cmd) || cmd.contains(".")) {
21044                packageName = cmd;
21045                // When dumping a single package, we always dump all of its
21046                // filter information since the amount of data will be reasonable.
21047                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21048            } else if ("check-permission".equals(cmd)) {
21049                if (opti >= args.length) {
21050                    pw.println("Error: check-permission missing permission argument");
21051                    return;
21052                }
21053                String perm = args[opti];
21054                opti++;
21055                if (opti >= args.length) {
21056                    pw.println("Error: check-permission missing package argument");
21057                    return;
21058                }
21059
21060                String pkg = args[opti];
21061                opti++;
21062                int user = UserHandle.getUserId(Binder.getCallingUid());
21063                if (opti < args.length) {
21064                    try {
21065                        user = Integer.parseInt(args[opti]);
21066                    } catch (NumberFormatException e) {
21067                        pw.println("Error: check-permission user argument is not a number: "
21068                                + args[opti]);
21069                        return;
21070                    }
21071                }
21072
21073                // Normalize package name to handle renamed packages and static libs
21074                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21075
21076                pw.println(checkPermission(perm, pkg, user));
21077                return;
21078            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21079                dumpState.setDump(DumpState.DUMP_LIBS);
21080            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21081                dumpState.setDump(DumpState.DUMP_FEATURES);
21082            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21083                if (opti >= args.length) {
21084                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21085                            | DumpState.DUMP_SERVICE_RESOLVERS
21086                            | DumpState.DUMP_RECEIVER_RESOLVERS
21087                            | DumpState.DUMP_CONTENT_RESOLVERS);
21088                } else {
21089                    while (opti < args.length) {
21090                        String name = args[opti];
21091                        if ("a".equals(name) || "activity".equals(name)) {
21092                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21093                        } else if ("s".equals(name) || "service".equals(name)) {
21094                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21095                        } else if ("r".equals(name) || "receiver".equals(name)) {
21096                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21097                        } else if ("c".equals(name) || "content".equals(name)) {
21098                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21099                        } else {
21100                            pw.println("Error: unknown resolver table type: " + name);
21101                            return;
21102                        }
21103                        opti++;
21104                    }
21105                }
21106            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21107                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21108            } else if ("permission".equals(cmd)) {
21109                if (opti >= args.length) {
21110                    pw.println("Error: permission requires permission name");
21111                    return;
21112                }
21113                permissionNames = new ArraySet<>();
21114                while (opti < args.length) {
21115                    permissionNames.add(args[opti]);
21116                    opti++;
21117                }
21118                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21119                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21120            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21121                dumpState.setDump(DumpState.DUMP_PREFERRED);
21122            } else if ("preferred-xml".equals(cmd)) {
21123                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21124                if (opti < args.length && "--full".equals(args[opti])) {
21125                    fullPreferred = true;
21126                    opti++;
21127                }
21128            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21129                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21130            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21131                dumpState.setDump(DumpState.DUMP_PACKAGES);
21132            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21133                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21134            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21135                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21136            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21137                dumpState.setDump(DumpState.DUMP_MESSAGES);
21138            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21139                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21140            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21141                    || "intent-filter-verifiers".equals(cmd)) {
21142                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21143            } else if ("version".equals(cmd)) {
21144                dumpState.setDump(DumpState.DUMP_VERSION);
21145            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21146                dumpState.setDump(DumpState.DUMP_KEYSETS);
21147            } else if ("installs".equals(cmd)) {
21148                dumpState.setDump(DumpState.DUMP_INSTALLS);
21149            } else if ("frozen".equals(cmd)) {
21150                dumpState.setDump(DumpState.DUMP_FROZEN);
21151            } else if ("dexopt".equals(cmd)) {
21152                dumpState.setDump(DumpState.DUMP_DEXOPT);
21153            } else if ("compiler-stats".equals(cmd)) {
21154                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21155            } else if ("enabled-overlays".equals(cmd)) {
21156                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
21157            } else if ("changes".equals(cmd)) {
21158                dumpState.setDump(DumpState.DUMP_CHANGES);
21159            } else if ("write".equals(cmd)) {
21160                synchronized (mPackages) {
21161                    mSettings.writeLPr();
21162                    pw.println("Settings written.");
21163                    return;
21164                }
21165            }
21166        }
21167
21168        if (checkin) {
21169            pw.println("vers,1");
21170        }
21171
21172        // reader
21173        synchronized (mPackages) {
21174            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21175                if (!checkin) {
21176                    if (dumpState.onTitlePrinted())
21177                        pw.println();
21178                    pw.println("Database versions:");
21179                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21180                }
21181            }
21182
21183            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21184                if (!checkin) {
21185                    if (dumpState.onTitlePrinted())
21186                        pw.println();
21187                    pw.println("Verifiers:");
21188                    pw.print("  Required: ");
21189                    pw.print(mRequiredVerifierPackage);
21190                    pw.print(" (uid=");
21191                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21192                            UserHandle.USER_SYSTEM));
21193                    pw.println(")");
21194                } else if (mRequiredVerifierPackage != null) {
21195                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21196                    pw.print(",");
21197                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21198                            UserHandle.USER_SYSTEM));
21199                }
21200            }
21201
21202            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21203                    packageName == null) {
21204                if (mIntentFilterVerifierComponent != null) {
21205                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21206                    if (!checkin) {
21207                        if (dumpState.onTitlePrinted())
21208                            pw.println();
21209                        pw.println("Intent Filter Verifier:");
21210                        pw.print("  Using: ");
21211                        pw.print(verifierPackageName);
21212                        pw.print(" (uid=");
21213                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21214                                UserHandle.USER_SYSTEM));
21215                        pw.println(")");
21216                    } else if (verifierPackageName != null) {
21217                        pw.print("ifv,"); pw.print(verifierPackageName);
21218                        pw.print(",");
21219                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21220                                UserHandle.USER_SYSTEM));
21221                    }
21222                } else {
21223                    pw.println();
21224                    pw.println("No Intent Filter Verifier available!");
21225                }
21226            }
21227
21228            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21229                boolean printedHeader = false;
21230                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21231                while (it.hasNext()) {
21232                    String libName = it.next();
21233                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21234                    if (versionedLib == null) {
21235                        continue;
21236                    }
21237                    final int versionCount = versionedLib.size();
21238                    for (int i = 0; i < versionCount; i++) {
21239                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21240                        if (!checkin) {
21241                            if (!printedHeader) {
21242                                if (dumpState.onTitlePrinted())
21243                                    pw.println();
21244                                pw.println("Libraries:");
21245                                printedHeader = true;
21246                            }
21247                            pw.print("  ");
21248                        } else {
21249                            pw.print("lib,");
21250                        }
21251                        pw.print(libEntry.info.getName());
21252                        if (libEntry.info.isStatic()) {
21253                            pw.print(" version=" + libEntry.info.getVersion());
21254                        }
21255                        if (!checkin) {
21256                            pw.print(" -> ");
21257                        }
21258                        if (libEntry.path != null) {
21259                            pw.print(" (jar) ");
21260                            pw.print(libEntry.path);
21261                        } else {
21262                            pw.print(" (apk) ");
21263                            pw.print(libEntry.apk);
21264                        }
21265                        pw.println();
21266                    }
21267                }
21268            }
21269
21270            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21271                if (dumpState.onTitlePrinted())
21272                    pw.println();
21273                if (!checkin) {
21274                    pw.println("Features:");
21275                }
21276
21277                synchronized (mAvailableFeatures) {
21278                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21279                        if (checkin) {
21280                            pw.print("feat,");
21281                            pw.print(feat.name);
21282                            pw.print(",");
21283                            pw.println(feat.version);
21284                        } else {
21285                            pw.print("  ");
21286                            pw.print(feat.name);
21287                            if (feat.version > 0) {
21288                                pw.print(" version=");
21289                                pw.print(feat.version);
21290                            }
21291                            pw.println();
21292                        }
21293                    }
21294                }
21295            }
21296
21297            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21298                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21299                        : "Activity Resolver Table:", "  ", packageName,
21300                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21301                    dumpState.setTitlePrinted(true);
21302                }
21303            }
21304            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21305                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21306                        : "Receiver Resolver Table:", "  ", packageName,
21307                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21308                    dumpState.setTitlePrinted(true);
21309                }
21310            }
21311            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21312                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21313                        : "Service Resolver Table:", "  ", packageName,
21314                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21315                    dumpState.setTitlePrinted(true);
21316                }
21317            }
21318            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21319                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21320                        : "Provider Resolver Table:", "  ", packageName,
21321                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21322                    dumpState.setTitlePrinted(true);
21323                }
21324            }
21325
21326            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21327                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21328                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21329                    int user = mSettings.mPreferredActivities.keyAt(i);
21330                    if (pir.dump(pw,
21331                            dumpState.getTitlePrinted()
21332                                ? "\nPreferred Activities User " + user + ":"
21333                                : "Preferred Activities User " + user + ":", "  ",
21334                            packageName, true, false)) {
21335                        dumpState.setTitlePrinted(true);
21336                    }
21337                }
21338            }
21339
21340            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21341                pw.flush();
21342                FileOutputStream fout = new FileOutputStream(fd);
21343                BufferedOutputStream str = new BufferedOutputStream(fout);
21344                XmlSerializer serializer = new FastXmlSerializer();
21345                try {
21346                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21347                    serializer.startDocument(null, true);
21348                    serializer.setFeature(
21349                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21350                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21351                    serializer.endDocument();
21352                    serializer.flush();
21353                } catch (IllegalArgumentException e) {
21354                    pw.println("Failed writing: " + e);
21355                } catch (IllegalStateException e) {
21356                    pw.println("Failed writing: " + e);
21357                } catch (IOException e) {
21358                    pw.println("Failed writing: " + e);
21359                }
21360            }
21361
21362            if (!checkin
21363                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21364                    && packageName == null) {
21365                pw.println();
21366                int count = mSettings.mPackages.size();
21367                if (count == 0) {
21368                    pw.println("No applications!");
21369                    pw.println();
21370                } else {
21371                    final String prefix = "  ";
21372                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21373                    if (allPackageSettings.size() == 0) {
21374                        pw.println("No domain preferred apps!");
21375                        pw.println();
21376                    } else {
21377                        pw.println("App verification status:");
21378                        pw.println();
21379                        count = 0;
21380                        for (PackageSetting ps : allPackageSettings) {
21381                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21382                            if (ivi == null || ivi.getPackageName() == null) continue;
21383                            pw.println(prefix + "Package: " + ivi.getPackageName());
21384                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21385                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21386                            pw.println();
21387                            count++;
21388                        }
21389                        if (count == 0) {
21390                            pw.println(prefix + "No app verification established.");
21391                            pw.println();
21392                        }
21393                        for (int userId : sUserManager.getUserIds()) {
21394                            pw.println("App linkages for user " + userId + ":");
21395                            pw.println();
21396                            count = 0;
21397                            for (PackageSetting ps : allPackageSettings) {
21398                                final long status = ps.getDomainVerificationStatusForUser(userId);
21399                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21400                                        && !DEBUG_DOMAIN_VERIFICATION) {
21401                                    continue;
21402                                }
21403                                pw.println(prefix + "Package: " + ps.name);
21404                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21405                                String statusStr = IntentFilterVerificationInfo.
21406                                        getStatusStringFromValue(status);
21407                                pw.println(prefix + "Status:  " + statusStr);
21408                                pw.println();
21409                                count++;
21410                            }
21411                            if (count == 0) {
21412                                pw.println(prefix + "No configured app linkages.");
21413                                pw.println();
21414                            }
21415                        }
21416                    }
21417                }
21418            }
21419
21420            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21421                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21422                if (packageName == null && permissionNames == null) {
21423                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21424                        if (iperm == 0) {
21425                            if (dumpState.onTitlePrinted())
21426                                pw.println();
21427                            pw.println("AppOp Permissions:");
21428                        }
21429                        pw.print("  AppOp Permission ");
21430                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21431                        pw.println(":");
21432                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21433                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21434                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21435                        }
21436                    }
21437                }
21438            }
21439
21440            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21441                boolean printedSomething = false;
21442                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21443                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21444                        continue;
21445                    }
21446                    if (!printedSomething) {
21447                        if (dumpState.onTitlePrinted())
21448                            pw.println();
21449                        pw.println("Registered ContentProviders:");
21450                        printedSomething = true;
21451                    }
21452                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21453                    pw.print("    "); pw.println(p.toString());
21454                }
21455                printedSomething = false;
21456                for (Map.Entry<String, PackageParser.Provider> entry :
21457                        mProvidersByAuthority.entrySet()) {
21458                    PackageParser.Provider p = entry.getValue();
21459                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21460                        continue;
21461                    }
21462                    if (!printedSomething) {
21463                        if (dumpState.onTitlePrinted())
21464                            pw.println();
21465                        pw.println("ContentProvider Authorities:");
21466                        printedSomething = true;
21467                    }
21468                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21469                    pw.print("    "); pw.println(p.toString());
21470                    if (p.info != null && p.info.applicationInfo != null) {
21471                        final String appInfo = p.info.applicationInfo.toString();
21472                        pw.print("      applicationInfo="); pw.println(appInfo);
21473                    }
21474                }
21475            }
21476
21477            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21478                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21479            }
21480
21481            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21482                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21483            }
21484
21485            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21486                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21487            }
21488
21489            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21490                if (dumpState.onTitlePrinted()) pw.println();
21491                pw.println("Package Changes:");
21492                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21493                final int K = mChangedPackages.size();
21494                for (int i = 0; i < K; i++) {
21495                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21496                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21497                    final int N = changes.size();
21498                    if (N == 0) {
21499                        pw.print("    "); pw.println("No packages changed");
21500                    } else {
21501                        for (int j = 0; j < N; j++) {
21502                            final String pkgName = changes.valueAt(j);
21503                            final int sequenceNumber = changes.keyAt(j);
21504                            pw.print("    ");
21505                            pw.print("seq=");
21506                            pw.print(sequenceNumber);
21507                            pw.print(", package=");
21508                            pw.println(pkgName);
21509                        }
21510                    }
21511                }
21512            }
21513
21514            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21515                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21516            }
21517
21518            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21519                // XXX should handle packageName != null by dumping only install data that
21520                // the given package is involved with.
21521                if (dumpState.onTitlePrinted()) pw.println();
21522
21523                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21524                ipw.println();
21525                ipw.println("Frozen packages:");
21526                ipw.increaseIndent();
21527                if (mFrozenPackages.size() == 0) {
21528                    ipw.println("(none)");
21529                } else {
21530                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21531                        ipw.println(mFrozenPackages.valueAt(i));
21532                    }
21533                }
21534                ipw.decreaseIndent();
21535            }
21536
21537            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21538                if (dumpState.onTitlePrinted()) pw.println();
21539                dumpDexoptStateLPr(pw, packageName);
21540            }
21541
21542            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21543                if (dumpState.onTitlePrinted()) pw.println();
21544                dumpCompilerStatsLPr(pw, packageName);
21545            }
21546
21547            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21548                if (dumpState.onTitlePrinted()) pw.println();
21549                dumpEnabledOverlaysLPr(pw);
21550            }
21551
21552            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21553                if (dumpState.onTitlePrinted()) pw.println();
21554                mSettings.dumpReadMessagesLPr(pw, dumpState);
21555
21556                pw.println();
21557                pw.println("Package warning messages:");
21558                BufferedReader in = null;
21559                String line = null;
21560                try {
21561                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21562                    while ((line = in.readLine()) != null) {
21563                        if (line.contains("ignored: updated version")) continue;
21564                        pw.println(line);
21565                    }
21566                } catch (IOException ignored) {
21567                } finally {
21568                    IoUtils.closeQuietly(in);
21569                }
21570            }
21571
21572            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21573                BufferedReader in = null;
21574                String line = null;
21575                try {
21576                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21577                    while ((line = in.readLine()) != null) {
21578                        if (line.contains("ignored: updated version")) continue;
21579                        pw.print("msg,");
21580                        pw.println(line);
21581                    }
21582                } catch (IOException ignored) {
21583                } finally {
21584                    IoUtils.closeQuietly(in);
21585                }
21586            }
21587        }
21588
21589        // PackageInstaller should be called outside of mPackages lock
21590        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21591            // XXX should handle packageName != null by dumping only install data that
21592            // the given package is involved with.
21593            if (dumpState.onTitlePrinted()) pw.println();
21594            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21595        }
21596    }
21597
21598    private void dumpProto(FileDescriptor fd) {
21599        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21600
21601        synchronized (mPackages) {
21602            final long requiredVerifierPackageToken =
21603                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21604            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21605            proto.write(
21606                    PackageServiceDumpProto.PackageShortProto.UID,
21607                    getPackageUid(
21608                            mRequiredVerifierPackage,
21609                            MATCH_DEBUG_TRIAGED_MISSING,
21610                            UserHandle.USER_SYSTEM));
21611            proto.end(requiredVerifierPackageToken);
21612
21613            if (mIntentFilterVerifierComponent != null) {
21614                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21615                final long verifierPackageToken =
21616                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21617                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21618                proto.write(
21619                        PackageServiceDumpProto.PackageShortProto.UID,
21620                        getPackageUid(
21621                                verifierPackageName,
21622                                MATCH_DEBUG_TRIAGED_MISSING,
21623                                UserHandle.USER_SYSTEM));
21624                proto.end(verifierPackageToken);
21625            }
21626
21627            dumpSharedLibrariesProto(proto);
21628            dumpFeaturesProto(proto);
21629            mSettings.dumpPackagesProto(proto);
21630            mSettings.dumpSharedUsersProto(proto);
21631            dumpMessagesProto(proto);
21632        }
21633        proto.flush();
21634    }
21635
21636    private void dumpMessagesProto(ProtoOutputStream proto) {
21637        BufferedReader in = null;
21638        String line = null;
21639        try {
21640            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
21641            while ((line = in.readLine()) != null) {
21642                if (line.contains("ignored: updated version")) continue;
21643                proto.write(PackageServiceDumpProto.MESSAGES, line);
21644            }
21645        } catch (IOException ignored) {
21646        } finally {
21647            IoUtils.closeQuietly(in);
21648        }
21649    }
21650
21651    private void dumpFeaturesProto(ProtoOutputStream proto) {
21652        synchronized (mAvailableFeatures) {
21653            final int count = mAvailableFeatures.size();
21654            for (int i = 0; i < count; i++) {
21655                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
21656                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
21657                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
21658                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
21659                proto.end(featureToken);
21660            }
21661        }
21662    }
21663
21664    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21665        final int count = mSharedLibraries.size();
21666        for (int i = 0; i < count; i++) {
21667            final String libName = mSharedLibraries.keyAt(i);
21668            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21669            if (versionedLib == null) {
21670                continue;
21671            }
21672            final int versionCount = versionedLib.size();
21673            for (int j = 0; j < versionCount; j++) {
21674                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21675                final long sharedLibraryToken =
21676                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21677                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21678                final boolean isJar = (libEntry.path != null);
21679                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21680                if (isJar) {
21681                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21682                } else {
21683                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21684                }
21685                proto.end(sharedLibraryToken);
21686            }
21687        }
21688    }
21689
21690    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21691        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21692        ipw.println();
21693        ipw.println("Dexopt state:");
21694        ipw.increaseIndent();
21695        Collection<PackageParser.Package> packages = null;
21696        if (packageName != null) {
21697            PackageParser.Package targetPackage = mPackages.get(packageName);
21698            if (targetPackage != null) {
21699                packages = Collections.singletonList(targetPackage);
21700            } else {
21701                ipw.println("Unable to find package: " + packageName);
21702                return;
21703            }
21704        } else {
21705            packages = mPackages.values();
21706        }
21707
21708        for (PackageParser.Package pkg : packages) {
21709            ipw.println("[" + pkg.packageName + "]");
21710            ipw.increaseIndent();
21711            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
21712            ipw.decreaseIndent();
21713        }
21714    }
21715
21716    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21717        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21718        ipw.println();
21719        ipw.println("Compiler stats:");
21720        ipw.increaseIndent();
21721        Collection<PackageParser.Package> packages = null;
21722        if (packageName != null) {
21723            PackageParser.Package targetPackage = mPackages.get(packageName);
21724            if (targetPackage != null) {
21725                packages = Collections.singletonList(targetPackage);
21726            } else {
21727                ipw.println("Unable to find package: " + packageName);
21728                return;
21729            }
21730        } else {
21731            packages = mPackages.values();
21732        }
21733
21734        for (PackageParser.Package pkg : packages) {
21735            ipw.println("[" + pkg.packageName + "]");
21736            ipw.increaseIndent();
21737
21738            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21739            if (stats == null) {
21740                ipw.println("(No recorded stats)");
21741            } else {
21742                stats.dump(ipw);
21743            }
21744            ipw.decreaseIndent();
21745        }
21746    }
21747
21748    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
21749        pw.println("Enabled overlay paths:");
21750        final int N = mEnabledOverlayPaths.size();
21751        for (int i = 0; i < N; i++) {
21752            final int userId = mEnabledOverlayPaths.keyAt(i);
21753            pw.println(String.format("    User %d:", userId));
21754            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
21755                mEnabledOverlayPaths.valueAt(i);
21756            final int M = userSpecificOverlays.size();
21757            for (int j = 0; j < M; j++) {
21758                final String targetPackageName = userSpecificOverlays.keyAt(j);
21759                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
21760                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
21761            }
21762        }
21763    }
21764
21765    private String dumpDomainString(String packageName) {
21766        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21767                .getList();
21768        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21769
21770        ArraySet<String> result = new ArraySet<>();
21771        if (iviList.size() > 0) {
21772            for (IntentFilterVerificationInfo ivi : iviList) {
21773                for (String host : ivi.getDomains()) {
21774                    result.add(host);
21775                }
21776            }
21777        }
21778        if (filters != null && filters.size() > 0) {
21779            for (IntentFilter filter : filters) {
21780                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21781                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21782                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21783                    result.addAll(filter.getHostsList());
21784                }
21785            }
21786        }
21787
21788        StringBuilder sb = new StringBuilder(result.size() * 16);
21789        for (String domain : result) {
21790            if (sb.length() > 0) sb.append(" ");
21791            sb.append(domain);
21792        }
21793        return sb.toString();
21794    }
21795
21796    // ------- apps on sdcard specific code -------
21797    static final boolean DEBUG_SD_INSTALL = false;
21798
21799    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21800
21801    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21802
21803    private boolean mMediaMounted = false;
21804
21805    static String getEncryptKey() {
21806        try {
21807            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21808                    SD_ENCRYPTION_KEYSTORE_NAME);
21809            if (sdEncKey == null) {
21810                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21811                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21812                if (sdEncKey == null) {
21813                    Slog.e(TAG, "Failed to create encryption keys");
21814                    return null;
21815                }
21816            }
21817            return sdEncKey;
21818        } catch (NoSuchAlgorithmException nsae) {
21819            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21820            return null;
21821        } catch (IOException ioe) {
21822            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21823            return null;
21824        }
21825    }
21826
21827    /*
21828     * Update media status on PackageManager.
21829     */
21830    @Override
21831    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
21832        int callingUid = Binder.getCallingUid();
21833        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
21834            throw new SecurityException("Media status can only be updated by the system");
21835        }
21836        // reader; this apparently protects mMediaMounted, but should probably
21837        // be a different lock in that case.
21838        synchronized (mPackages) {
21839            Log.i(TAG, "Updating external media status from "
21840                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
21841                    + (mediaStatus ? "mounted" : "unmounted"));
21842            if (DEBUG_SD_INSTALL)
21843                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
21844                        + ", mMediaMounted=" + mMediaMounted);
21845            if (mediaStatus == mMediaMounted) {
21846                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
21847                        : 0, -1);
21848                mHandler.sendMessage(msg);
21849                return;
21850            }
21851            mMediaMounted = mediaStatus;
21852        }
21853        // Queue up an async operation since the package installation may take a
21854        // little while.
21855        mHandler.post(new Runnable() {
21856            public void run() {
21857                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
21858            }
21859        });
21860    }
21861
21862    /**
21863     * Called by StorageManagerService when the initial ASECs to scan are available.
21864     * Should block until all the ASEC containers are finished being scanned.
21865     */
21866    public void scanAvailableAsecs() {
21867        updateExternalMediaStatusInner(true, false, false);
21868    }
21869
21870    /*
21871     * Collect information of applications on external media, map them against
21872     * existing containers and update information based on current mount status.
21873     * Please note that we always have to report status if reportStatus has been
21874     * set to true especially when unloading packages.
21875     */
21876    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
21877            boolean externalStorage) {
21878        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
21879        int[] uidArr = EmptyArray.INT;
21880
21881        final String[] list = PackageHelper.getSecureContainerList();
21882        if (ArrayUtils.isEmpty(list)) {
21883            Log.i(TAG, "No secure containers found");
21884        } else {
21885            // Process list of secure containers and categorize them
21886            // as active or stale based on their package internal state.
21887
21888            // reader
21889            synchronized (mPackages) {
21890                for (String cid : list) {
21891                    // Leave stages untouched for now; installer service owns them
21892                    if (PackageInstallerService.isStageName(cid)) continue;
21893
21894                    if (DEBUG_SD_INSTALL)
21895                        Log.i(TAG, "Processing container " + cid);
21896                    String pkgName = getAsecPackageName(cid);
21897                    if (pkgName == null) {
21898                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
21899                        continue;
21900                    }
21901                    if (DEBUG_SD_INSTALL)
21902                        Log.i(TAG, "Looking for pkg : " + pkgName);
21903
21904                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
21905                    if (ps == null) {
21906                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
21907                        continue;
21908                    }
21909
21910                    /*
21911                     * Skip packages that are not external if we're unmounting
21912                     * external storage.
21913                     */
21914                    if (externalStorage && !isMounted && !isExternal(ps)) {
21915                        continue;
21916                    }
21917
21918                    final AsecInstallArgs args = new AsecInstallArgs(cid,
21919                            getAppDexInstructionSets(ps), ps.isForwardLocked());
21920                    // The package status is changed only if the code path
21921                    // matches between settings and the container id.
21922                    if (ps.codePathString != null
21923                            && ps.codePathString.startsWith(args.getCodePath())) {
21924                        if (DEBUG_SD_INSTALL) {
21925                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
21926                                    + " at code path: " + ps.codePathString);
21927                        }
21928
21929                        // We do have a valid package installed on sdcard
21930                        processCids.put(args, ps.codePathString);
21931                        final int uid = ps.appId;
21932                        if (uid != -1) {
21933                            uidArr = ArrayUtils.appendInt(uidArr, uid);
21934                        }
21935                    } else {
21936                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
21937                                + ps.codePathString);
21938                    }
21939                }
21940            }
21941
21942            Arrays.sort(uidArr);
21943        }
21944
21945        // Process packages with valid entries.
21946        if (isMounted) {
21947            if (DEBUG_SD_INSTALL)
21948                Log.i(TAG, "Loading packages");
21949            loadMediaPackages(processCids, uidArr, externalStorage);
21950            startCleaningPackages();
21951            mInstallerService.onSecureContainersAvailable();
21952        } else {
21953            if (DEBUG_SD_INSTALL)
21954                Log.i(TAG, "Unloading packages");
21955            unloadMediaPackages(processCids, uidArr, reportStatus);
21956        }
21957    }
21958
21959    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21960            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21961        final int size = infos.size();
21962        final String[] packageNames = new String[size];
21963        final int[] packageUids = new int[size];
21964        for (int i = 0; i < size; i++) {
21965            final ApplicationInfo info = infos.get(i);
21966            packageNames[i] = info.packageName;
21967            packageUids[i] = info.uid;
21968        }
21969        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21970                finishedReceiver);
21971    }
21972
21973    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21974            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21975        sendResourcesChangedBroadcast(mediaStatus, replacing,
21976                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21977    }
21978
21979    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21980            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21981        int size = pkgList.length;
21982        if (size > 0) {
21983            // Send broadcasts here
21984            Bundle extras = new Bundle();
21985            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21986            if (uidArr != null) {
21987                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21988            }
21989            if (replacing) {
21990                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21991            }
21992            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21993                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21994            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21995        }
21996    }
21997
21998   /*
21999     * Look at potentially valid container ids from processCids If package
22000     * information doesn't match the one on record or package scanning fails,
22001     * the cid is added to list of removeCids. We currently don't delete stale
22002     * containers.
22003     */
22004    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
22005            boolean externalStorage) {
22006        ArrayList<String> pkgList = new ArrayList<String>();
22007        Set<AsecInstallArgs> keys = processCids.keySet();
22008
22009        for (AsecInstallArgs args : keys) {
22010            String codePath = processCids.get(args);
22011            if (DEBUG_SD_INSTALL)
22012                Log.i(TAG, "Loading container : " + args.cid);
22013            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
22014            try {
22015                // Make sure there are no container errors first.
22016                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
22017                    Slog.e(TAG, "Failed to mount cid : " + args.cid
22018                            + " when installing from sdcard");
22019                    continue;
22020                }
22021                // Check code path here.
22022                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
22023                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
22024                            + " does not match one in settings " + codePath);
22025                    continue;
22026                }
22027                // Parse package
22028                int parseFlags = mDefParseFlags;
22029                if (args.isExternalAsec()) {
22030                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
22031                }
22032                if (args.isFwdLocked()) {
22033                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
22034                }
22035
22036                synchronized (mInstallLock) {
22037                    PackageParser.Package pkg = null;
22038                    try {
22039                        // Sadly we don't know the package name yet to freeze it
22040                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
22041                                SCAN_IGNORE_FROZEN, 0, null);
22042                    } catch (PackageManagerException e) {
22043                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
22044                    }
22045                    // Scan the package
22046                    if (pkg != null) {
22047                        /*
22048                         * TODO why is the lock being held? doPostInstall is
22049                         * called in other places without the lock. This needs
22050                         * to be straightened out.
22051                         */
22052                        // writer
22053                        synchronized (mPackages) {
22054                            retCode = PackageManager.INSTALL_SUCCEEDED;
22055                            pkgList.add(pkg.packageName);
22056                            // Post process args
22057                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
22058                                    pkg.applicationInfo.uid);
22059                        }
22060                    } else {
22061                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
22062                    }
22063                }
22064
22065            } finally {
22066                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
22067                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
22068                }
22069            }
22070        }
22071        // writer
22072        synchronized (mPackages) {
22073            // If the platform SDK has changed since the last time we booted,
22074            // we need to re-grant app permission to catch any new ones that
22075            // appear. This is really a hack, and means that apps can in some
22076            // cases get permissions that the user didn't initially explicitly
22077            // allow... it would be nice to have some better way to handle
22078            // this situation.
22079            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
22080                    : mSettings.getInternalVersion();
22081            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
22082                    : StorageManager.UUID_PRIVATE_INTERNAL;
22083
22084            int updateFlags = UPDATE_PERMISSIONS_ALL;
22085            if (ver.sdkVersion != mSdkVersion) {
22086                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22087                        + mSdkVersion + "; regranting permissions for external");
22088                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22089            }
22090            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22091
22092            // Yay, everything is now upgraded
22093            ver.forceCurrent();
22094
22095            // can downgrade to reader
22096            // Persist settings
22097            mSettings.writeLPr();
22098        }
22099        // Send a broadcast to let everyone know we are done processing
22100        if (pkgList.size() > 0) {
22101            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
22102        }
22103    }
22104
22105   /*
22106     * Utility method to unload a list of specified containers
22107     */
22108    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
22109        // Just unmount all valid containers.
22110        for (AsecInstallArgs arg : cidArgs) {
22111            synchronized (mInstallLock) {
22112                arg.doPostDeleteLI(false);
22113           }
22114       }
22115   }
22116
22117    /*
22118     * Unload packages mounted on external media. This involves deleting package
22119     * data from internal structures, sending broadcasts about disabled packages,
22120     * gc'ing to free up references, unmounting all secure containers
22121     * corresponding to packages on external media, and posting a
22122     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
22123     * that we always have to post this message if status has been requested no
22124     * matter what.
22125     */
22126    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
22127            final boolean reportStatus) {
22128        if (DEBUG_SD_INSTALL)
22129            Log.i(TAG, "unloading media packages");
22130        ArrayList<String> pkgList = new ArrayList<String>();
22131        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
22132        final Set<AsecInstallArgs> keys = processCids.keySet();
22133        for (AsecInstallArgs args : keys) {
22134            String pkgName = args.getPackageName();
22135            if (DEBUG_SD_INSTALL)
22136                Log.i(TAG, "Trying to unload pkg : " + pkgName);
22137            // Delete package internally
22138            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22139            synchronized (mInstallLock) {
22140                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22141                final boolean res;
22142                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
22143                        "unloadMediaPackages")) {
22144                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
22145                            null);
22146                }
22147                if (res) {
22148                    pkgList.add(pkgName);
22149                } else {
22150                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
22151                    failedList.add(args);
22152                }
22153            }
22154        }
22155
22156        // reader
22157        synchronized (mPackages) {
22158            // We didn't update the settings after removing each package;
22159            // write them now for all packages.
22160            mSettings.writeLPr();
22161        }
22162
22163        // We have to absolutely send UPDATED_MEDIA_STATUS only
22164        // after confirming that all the receivers processed the ordered
22165        // broadcast when packages get disabled, force a gc to clean things up.
22166        // and unload all the containers.
22167        if (pkgList.size() > 0) {
22168            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
22169                    new IIntentReceiver.Stub() {
22170                public void performReceive(Intent intent, int resultCode, String data,
22171                        Bundle extras, boolean ordered, boolean sticky,
22172                        int sendingUser) throws RemoteException {
22173                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
22174                            reportStatus ? 1 : 0, 1, keys);
22175                    mHandler.sendMessage(msg);
22176                }
22177            });
22178        } else {
22179            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
22180                    keys);
22181            mHandler.sendMessage(msg);
22182        }
22183    }
22184
22185    private void loadPrivatePackages(final VolumeInfo vol) {
22186        mHandler.post(new Runnable() {
22187            @Override
22188            public void run() {
22189                loadPrivatePackagesInner(vol);
22190            }
22191        });
22192    }
22193
22194    private void loadPrivatePackagesInner(VolumeInfo vol) {
22195        final String volumeUuid = vol.fsUuid;
22196        if (TextUtils.isEmpty(volumeUuid)) {
22197            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22198            return;
22199        }
22200
22201        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22202        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22203        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22204
22205        final VersionInfo ver;
22206        final List<PackageSetting> packages;
22207        synchronized (mPackages) {
22208            ver = mSettings.findOrCreateVersion(volumeUuid);
22209            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22210        }
22211
22212        for (PackageSetting ps : packages) {
22213            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22214            synchronized (mInstallLock) {
22215                final PackageParser.Package pkg;
22216                try {
22217                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22218                    loaded.add(pkg.applicationInfo);
22219
22220                } catch (PackageManagerException e) {
22221                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22222                }
22223
22224                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22225                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22226                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22227                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22228                }
22229            }
22230        }
22231
22232        // Reconcile app data for all started/unlocked users
22233        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22234        final UserManager um = mContext.getSystemService(UserManager.class);
22235        UserManagerInternal umInternal = getUserManagerInternal();
22236        for (UserInfo user : um.getUsers()) {
22237            final int flags;
22238            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22239                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22240            } else if (umInternal.isUserRunning(user.id)) {
22241                flags = StorageManager.FLAG_STORAGE_DE;
22242            } else {
22243                continue;
22244            }
22245
22246            try {
22247                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22248                synchronized (mInstallLock) {
22249                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22250                }
22251            } catch (IllegalStateException e) {
22252                // Device was probably ejected, and we'll process that event momentarily
22253                Slog.w(TAG, "Failed to prepare storage: " + e);
22254            }
22255        }
22256
22257        synchronized (mPackages) {
22258            int updateFlags = UPDATE_PERMISSIONS_ALL;
22259            if (ver.sdkVersion != mSdkVersion) {
22260                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22261                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22262                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22263            }
22264            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22265
22266            // Yay, everything is now upgraded
22267            ver.forceCurrent();
22268
22269            mSettings.writeLPr();
22270        }
22271
22272        for (PackageFreezer freezer : freezers) {
22273            freezer.close();
22274        }
22275
22276        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22277        sendResourcesChangedBroadcast(true, false, loaded, null);
22278    }
22279
22280    private void unloadPrivatePackages(final VolumeInfo vol) {
22281        mHandler.post(new Runnable() {
22282            @Override
22283            public void run() {
22284                unloadPrivatePackagesInner(vol);
22285            }
22286        });
22287    }
22288
22289    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22290        final String volumeUuid = vol.fsUuid;
22291        if (TextUtils.isEmpty(volumeUuid)) {
22292            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22293            return;
22294        }
22295
22296        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22297        synchronized (mInstallLock) {
22298        synchronized (mPackages) {
22299            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22300            for (PackageSetting ps : packages) {
22301                if (ps.pkg == null) continue;
22302
22303                final ApplicationInfo info = ps.pkg.applicationInfo;
22304                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22305                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22306
22307                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22308                        "unloadPrivatePackagesInner")) {
22309                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22310                            false, null)) {
22311                        unloaded.add(info);
22312                    } else {
22313                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22314                    }
22315                }
22316
22317                // Try very hard to release any references to this package
22318                // so we don't risk the system server being killed due to
22319                // open FDs
22320                AttributeCache.instance().removePackage(ps.name);
22321            }
22322
22323            mSettings.writeLPr();
22324        }
22325        }
22326
22327        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22328        sendResourcesChangedBroadcast(false, false, unloaded, null);
22329
22330        // Try very hard to release any references to this path so we don't risk
22331        // the system server being killed due to open FDs
22332        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22333
22334        for (int i = 0; i < 3; i++) {
22335            System.gc();
22336            System.runFinalization();
22337        }
22338    }
22339
22340    private void assertPackageKnown(String volumeUuid, String packageName)
22341            throws PackageManagerException {
22342        synchronized (mPackages) {
22343            // Normalize package name to handle renamed packages
22344            packageName = normalizePackageNameLPr(packageName);
22345
22346            final PackageSetting ps = mSettings.mPackages.get(packageName);
22347            if (ps == null) {
22348                throw new PackageManagerException("Package " + packageName + " is unknown");
22349            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22350                throw new PackageManagerException(
22351                        "Package " + packageName + " found on unknown volume " + volumeUuid
22352                                + "; expected volume " + ps.volumeUuid);
22353            }
22354        }
22355    }
22356
22357    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22358            throws PackageManagerException {
22359        synchronized (mPackages) {
22360            // Normalize package name to handle renamed packages
22361            packageName = normalizePackageNameLPr(packageName);
22362
22363            final PackageSetting ps = mSettings.mPackages.get(packageName);
22364            if (ps == null) {
22365                throw new PackageManagerException("Package " + packageName + " is unknown");
22366            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22367                throw new PackageManagerException(
22368                        "Package " + packageName + " found on unknown volume " + volumeUuid
22369                                + "; expected volume " + ps.volumeUuid);
22370            } else if (!ps.getInstalled(userId)) {
22371                throw new PackageManagerException(
22372                        "Package " + packageName + " not installed for user " + userId);
22373            }
22374        }
22375    }
22376
22377    private List<String> collectAbsoluteCodePaths() {
22378        synchronized (mPackages) {
22379            List<String> codePaths = new ArrayList<>();
22380            final int packageCount = mSettings.mPackages.size();
22381            for (int i = 0; i < packageCount; i++) {
22382                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22383                codePaths.add(ps.codePath.getAbsolutePath());
22384            }
22385            return codePaths;
22386        }
22387    }
22388
22389    /**
22390     * Examine all apps present on given mounted volume, and destroy apps that
22391     * aren't expected, either due to uninstallation or reinstallation on
22392     * another volume.
22393     */
22394    private void reconcileApps(String volumeUuid) {
22395        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22396        List<File> filesToDelete = null;
22397
22398        final File[] files = FileUtils.listFilesOrEmpty(
22399                Environment.getDataAppDirectory(volumeUuid));
22400        for (File file : files) {
22401            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22402                    && !PackageInstallerService.isStageName(file.getName());
22403            if (!isPackage) {
22404                // Ignore entries which are not packages
22405                continue;
22406            }
22407
22408            String absolutePath = file.getAbsolutePath();
22409
22410            boolean pathValid = false;
22411            final int absoluteCodePathCount = absoluteCodePaths.size();
22412            for (int i = 0; i < absoluteCodePathCount; i++) {
22413                String absoluteCodePath = absoluteCodePaths.get(i);
22414                if (absolutePath.startsWith(absoluteCodePath)) {
22415                    pathValid = true;
22416                    break;
22417                }
22418            }
22419
22420            if (!pathValid) {
22421                if (filesToDelete == null) {
22422                    filesToDelete = new ArrayList<>();
22423                }
22424                filesToDelete.add(file);
22425            }
22426        }
22427
22428        if (filesToDelete != null) {
22429            final int fileToDeleteCount = filesToDelete.size();
22430            for (int i = 0; i < fileToDeleteCount; i++) {
22431                File fileToDelete = filesToDelete.get(i);
22432                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22433                synchronized (mInstallLock) {
22434                    removeCodePathLI(fileToDelete);
22435                }
22436            }
22437        }
22438    }
22439
22440    /**
22441     * Reconcile all app data for the given user.
22442     * <p>
22443     * Verifies that directories exist and that ownership and labeling is
22444     * correct for all installed apps on all mounted volumes.
22445     */
22446    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22447        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22448        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22449            final String volumeUuid = vol.getFsUuid();
22450            synchronized (mInstallLock) {
22451                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22452            }
22453        }
22454    }
22455
22456    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22457            boolean migrateAppData) {
22458        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22459    }
22460
22461    /**
22462     * Reconcile all app data on given mounted volume.
22463     * <p>
22464     * Destroys app data that isn't expected, either due to uninstallation or
22465     * reinstallation on another volume.
22466     * <p>
22467     * Verifies that directories exist and that ownership and labeling is
22468     * correct for all installed apps.
22469     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22470     */
22471    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22472            boolean migrateAppData, boolean onlyCoreApps) {
22473        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22474                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22475        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22476
22477        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22478        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22479
22480        // First look for stale data that doesn't belong, and check if things
22481        // have changed since we did our last restorecon
22482        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22483            if (StorageManager.isFileEncryptedNativeOrEmulated()
22484                    && !StorageManager.isUserKeyUnlocked(userId)) {
22485                throw new RuntimeException(
22486                        "Yikes, someone asked us to reconcile CE storage while " + userId
22487                                + " was still locked; this would have caused massive data loss!");
22488            }
22489
22490            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22491            for (File file : files) {
22492                final String packageName = file.getName();
22493                try {
22494                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22495                } catch (PackageManagerException e) {
22496                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22497                    try {
22498                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22499                                StorageManager.FLAG_STORAGE_CE, 0);
22500                    } catch (InstallerException e2) {
22501                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22502                    }
22503                }
22504            }
22505        }
22506        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22507            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22508            for (File file : files) {
22509                final String packageName = file.getName();
22510                try {
22511                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22512                } catch (PackageManagerException e) {
22513                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22514                    try {
22515                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22516                                StorageManager.FLAG_STORAGE_DE, 0);
22517                    } catch (InstallerException e2) {
22518                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22519                    }
22520                }
22521            }
22522        }
22523
22524        // Ensure that data directories are ready to roll for all packages
22525        // installed for this volume and user
22526        final List<PackageSetting> packages;
22527        synchronized (mPackages) {
22528            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22529        }
22530        int preparedCount = 0;
22531        for (PackageSetting ps : packages) {
22532            final String packageName = ps.name;
22533            if (ps.pkg == null) {
22534                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22535                // TODO: might be due to legacy ASEC apps; we should circle back
22536                // and reconcile again once they're scanned
22537                continue;
22538            }
22539            // Skip non-core apps if requested
22540            if (onlyCoreApps && !ps.pkg.coreApp) {
22541                result.add(packageName);
22542                continue;
22543            }
22544
22545            if (ps.getInstalled(userId)) {
22546                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22547                preparedCount++;
22548            }
22549        }
22550
22551        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22552        return result;
22553    }
22554
22555    /**
22556     * Prepare app data for the given app just after it was installed or
22557     * upgraded. This method carefully only touches users that it's installed
22558     * for, and it forces a restorecon to handle any seinfo changes.
22559     * <p>
22560     * Verifies that directories exist and that ownership and labeling is
22561     * correct for all installed apps. If there is an ownership mismatch, it
22562     * will try recovering system apps by wiping data; third-party app data is
22563     * left intact.
22564     * <p>
22565     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22566     */
22567    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22568        final PackageSetting ps;
22569        synchronized (mPackages) {
22570            ps = mSettings.mPackages.get(pkg.packageName);
22571            mSettings.writeKernelMappingLPr(ps);
22572        }
22573
22574        final UserManager um = mContext.getSystemService(UserManager.class);
22575        UserManagerInternal umInternal = getUserManagerInternal();
22576        for (UserInfo user : um.getUsers()) {
22577            final int flags;
22578            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22579                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22580            } else if (umInternal.isUserRunning(user.id)) {
22581                flags = StorageManager.FLAG_STORAGE_DE;
22582            } else {
22583                continue;
22584            }
22585
22586            if (ps.getInstalled(user.id)) {
22587                // TODO: when user data is locked, mark that we're still dirty
22588                prepareAppDataLIF(pkg, user.id, flags);
22589            }
22590        }
22591    }
22592
22593    /**
22594     * Prepare app data for the given app.
22595     * <p>
22596     * Verifies that directories exist and that ownership and labeling is
22597     * correct for all installed apps. If there is an ownership mismatch, this
22598     * will try recovering system apps by wiping data; third-party app data is
22599     * left intact.
22600     */
22601    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22602        if (pkg == null) {
22603            Slog.wtf(TAG, "Package was null!", new Throwable());
22604            return;
22605        }
22606        prepareAppDataLeafLIF(pkg, userId, flags);
22607        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22608        for (int i = 0; i < childCount; i++) {
22609            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22610        }
22611    }
22612
22613    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22614            boolean maybeMigrateAppData) {
22615        prepareAppDataLIF(pkg, userId, flags);
22616
22617        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22618            // We may have just shuffled around app data directories, so
22619            // prepare them one more time
22620            prepareAppDataLIF(pkg, userId, flags);
22621        }
22622    }
22623
22624    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22625        if (DEBUG_APP_DATA) {
22626            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22627                    + Integer.toHexString(flags));
22628        }
22629
22630        final String volumeUuid = pkg.volumeUuid;
22631        final String packageName = pkg.packageName;
22632        final ApplicationInfo app = pkg.applicationInfo;
22633        final int appId = UserHandle.getAppId(app.uid);
22634
22635        Preconditions.checkNotNull(app.seInfo);
22636
22637        long ceDataInode = -1;
22638        try {
22639            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22640                    appId, app.seInfo, app.targetSdkVersion);
22641        } catch (InstallerException e) {
22642            if (app.isSystemApp()) {
22643                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22644                        + ", but trying to recover: " + e);
22645                destroyAppDataLeafLIF(pkg, userId, flags);
22646                try {
22647                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22648                            appId, app.seInfo, app.targetSdkVersion);
22649                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22650                } catch (InstallerException e2) {
22651                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22652                }
22653            } else {
22654                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22655            }
22656        }
22657
22658        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22659            // TODO: mark this structure as dirty so we persist it!
22660            synchronized (mPackages) {
22661                final PackageSetting ps = mSettings.mPackages.get(packageName);
22662                if (ps != null) {
22663                    ps.setCeDataInode(ceDataInode, userId);
22664                }
22665            }
22666        }
22667
22668        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22669    }
22670
22671    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22672        if (pkg == null) {
22673            Slog.wtf(TAG, "Package was null!", new Throwable());
22674            return;
22675        }
22676        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22677        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22678        for (int i = 0; i < childCount; i++) {
22679            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22680        }
22681    }
22682
22683    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22684        final String volumeUuid = pkg.volumeUuid;
22685        final String packageName = pkg.packageName;
22686        final ApplicationInfo app = pkg.applicationInfo;
22687
22688        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22689            // Create a native library symlink only if we have native libraries
22690            // and if the native libraries are 32 bit libraries. We do not provide
22691            // this symlink for 64 bit libraries.
22692            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22693                final String nativeLibPath = app.nativeLibraryDir;
22694                try {
22695                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22696                            nativeLibPath, userId);
22697                } catch (InstallerException e) {
22698                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22699                }
22700            }
22701        }
22702    }
22703
22704    /**
22705     * For system apps on non-FBE devices, this method migrates any existing
22706     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22707     * requested by the app.
22708     */
22709    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22710        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
22711                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22712            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22713                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22714            try {
22715                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22716                        storageTarget);
22717            } catch (InstallerException e) {
22718                logCriticalInfo(Log.WARN,
22719                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22720            }
22721            return true;
22722        } else {
22723            return false;
22724        }
22725    }
22726
22727    public PackageFreezer freezePackage(String packageName, String killReason) {
22728        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22729    }
22730
22731    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22732        return new PackageFreezer(packageName, userId, killReason);
22733    }
22734
22735    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22736            String killReason) {
22737        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22738    }
22739
22740    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22741            String killReason) {
22742        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22743            return new PackageFreezer();
22744        } else {
22745            return freezePackage(packageName, userId, killReason);
22746        }
22747    }
22748
22749    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22750            String killReason) {
22751        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22752    }
22753
22754    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22755            String killReason) {
22756        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22757            return new PackageFreezer();
22758        } else {
22759            return freezePackage(packageName, userId, killReason);
22760        }
22761    }
22762
22763    /**
22764     * Class that freezes and kills the given package upon creation, and
22765     * unfreezes it upon closing. This is typically used when doing surgery on
22766     * app code/data to prevent the app from running while you're working.
22767     */
22768    private class PackageFreezer implements AutoCloseable {
22769        private final String mPackageName;
22770        private final PackageFreezer[] mChildren;
22771
22772        private final boolean mWeFroze;
22773
22774        private final AtomicBoolean mClosed = new AtomicBoolean();
22775        private final CloseGuard mCloseGuard = CloseGuard.get();
22776
22777        /**
22778         * Create and return a stub freezer that doesn't actually do anything,
22779         * typically used when someone requested
22780         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22781         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22782         */
22783        public PackageFreezer() {
22784            mPackageName = null;
22785            mChildren = null;
22786            mWeFroze = false;
22787            mCloseGuard.open("close");
22788        }
22789
22790        public PackageFreezer(String packageName, int userId, String killReason) {
22791            synchronized (mPackages) {
22792                mPackageName = packageName;
22793                mWeFroze = mFrozenPackages.add(mPackageName);
22794
22795                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22796                if (ps != null) {
22797                    killApplication(ps.name, ps.appId, userId, killReason);
22798                }
22799
22800                final PackageParser.Package p = mPackages.get(packageName);
22801                if (p != null && p.childPackages != null) {
22802                    final int N = p.childPackages.size();
22803                    mChildren = new PackageFreezer[N];
22804                    for (int i = 0; i < N; i++) {
22805                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22806                                userId, killReason);
22807                    }
22808                } else {
22809                    mChildren = null;
22810                }
22811            }
22812            mCloseGuard.open("close");
22813        }
22814
22815        @Override
22816        protected void finalize() throws Throwable {
22817            try {
22818                mCloseGuard.warnIfOpen();
22819                close();
22820            } finally {
22821                super.finalize();
22822            }
22823        }
22824
22825        @Override
22826        public void close() {
22827            mCloseGuard.close();
22828            if (mClosed.compareAndSet(false, true)) {
22829                synchronized (mPackages) {
22830                    if (mWeFroze) {
22831                        mFrozenPackages.remove(mPackageName);
22832                    }
22833
22834                    if (mChildren != null) {
22835                        for (PackageFreezer freezer : mChildren) {
22836                            freezer.close();
22837                        }
22838                    }
22839                }
22840            }
22841        }
22842    }
22843
22844    /**
22845     * Verify that given package is currently frozen.
22846     */
22847    private void checkPackageFrozen(String packageName) {
22848        synchronized (mPackages) {
22849            if (!mFrozenPackages.contains(packageName)) {
22850                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22851            }
22852        }
22853    }
22854
22855    @Override
22856    public int movePackage(final String packageName, final String volumeUuid) {
22857        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22858
22859        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
22860        final int moveId = mNextMoveId.getAndIncrement();
22861        mHandler.post(new Runnable() {
22862            @Override
22863            public void run() {
22864                try {
22865                    movePackageInternal(packageName, volumeUuid, moveId, user);
22866                } catch (PackageManagerException e) {
22867                    Slog.w(TAG, "Failed to move " + packageName, e);
22868                    mMoveCallbacks.notifyStatusChanged(moveId,
22869                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22870                }
22871            }
22872        });
22873        return moveId;
22874    }
22875
22876    private void movePackageInternal(final String packageName, final String volumeUuid,
22877            final int moveId, UserHandle user) throws PackageManagerException {
22878        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22879        final PackageManager pm = mContext.getPackageManager();
22880
22881        final boolean currentAsec;
22882        final String currentVolumeUuid;
22883        final File codeFile;
22884        final String installerPackageName;
22885        final String packageAbiOverride;
22886        final int appId;
22887        final String seinfo;
22888        final String label;
22889        final int targetSdkVersion;
22890        final PackageFreezer freezer;
22891        final int[] installedUserIds;
22892
22893        // reader
22894        synchronized (mPackages) {
22895            final PackageParser.Package pkg = mPackages.get(packageName);
22896            final PackageSetting ps = mSettings.mPackages.get(packageName);
22897            if (pkg == null || ps == null) {
22898                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22899            }
22900
22901            if (pkg.applicationInfo.isSystemApp()) {
22902                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22903                        "Cannot move system application");
22904            }
22905
22906            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22907            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22908                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22909            if (isInternalStorage && !allow3rdPartyOnInternal) {
22910                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22911                        "3rd party apps are not allowed on internal storage");
22912            }
22913
22914            if (pkg.applicationInfo.isExternalAsec()) {
22915                currentAsec = true;
22916                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22917            } else if (pkg.applicationInfo.isForwardLocked()) {
22918                currentAsec = true;
22919                currentVolumeUuid = "forward_locked";
22920            } else {
22921                currentAsec = false;
22922                currentVolumeUuid = ps.volumeUuid;
22923
22924                final File probe = new File(pkg.codePath);
22925                final File probeOat = new File(probe, "oat");
22926                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22927                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22928                            "Move only supported for modern cluster style installs");
22929                }
22930            }
22931
22932            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22933                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22934                        "Package already moved to " + volumeUuid);
22935            }
22936            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22937                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22938                        "Device admin cannot be moved");
22939            }
22940
22941            if (mFrozenPackages.contains(packageName)) {
22942                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22943                        "Failed to move already frozen package");
22944            }
22945
22946            codeFile = new File(pkg.codePath);
22947            installerPackageName = ps.installerPackageName;
22948            packageAbiOverride = ps.cpuAbiOverrideString;
22949            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22950            seinfo = pkg.applicationInfo.seInfo;
22951            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22952            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22953            freezer = freezePackage(packageName, "movePackageInternal");
22954            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22955        }
22956
22957        final Bundle extras = new Bundle();
22958        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22959        extras.putString(Intent.EXTRA_TITLE, label);
22960        mMoveCallbacks.notifyCreated(moveId, extras);
22961
22962        int installFlags;
22963        final boolean moveCompleteApp;
22964        final File measurePath;
22965
22966        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22967            installFlags = INSTALL_INTERNAL;
22968            moveCompleteApp = !currentAsec;
22969            measurePath = Environment.getDataAppDirectory(volumeUuid);
22970        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22971            installFlags = INSTALL_EXTERNAL;
22972            moveCompleteApp = false;
22973            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22974        } else {
22975            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22976            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22977                    || !volume.isMountedWritable()) {
22978                freezer.close();
22979                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22980                        "Move location not mounted private volume");
22981            }
22982
22983            Preconditions.checkState(!currentAsec);
22984
22985            installFlags = INSTALL_INTERNAL;
22986            moveCompleteApp = true;
22987            measurePath = Environment.getDataAppDirectory(volumeUuid);
22988        }
22989
22990        final PackageStats stats = new PackageStats(null, -1);
22991        synchronized (mInstaller) {
22992            for (int userId : installedUserIds) {
22993                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22994                    freezer.close();
22995                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22996                            "Failed to measure package size");
22997                }
22998            }
22999        }
23000
23001        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23002                + stats.dataSize);
23003
23004        final long startFreeBytes = measurePath.getUsableSpace();
23005        final long sizeBytes;
23006        if (moveCompleteApp) {
23007            sizeBytes = stats.codeSize + stats.dataSize;
23008        } else {
23009            sizeBytes = stats.codeSize;
23010        }
23011
23012        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23013            freezer.close();
23014            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23015                    "Not enough free space to move");
23016        }
23017
23018        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23019
23020        final CountDownLatch installedLatch = new CountDownLatch(1);
23021        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23022            @Override
23023            public void onUserActionRequired(Intent intent) throws RemoteException {
23024                throw new IllegalStateException();
23025            }
23026
23027            @Override
23028            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23029                    Bundle extras) throws RemoteException {
23030                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23031                        + PackageManager.installStatusToString(returnCode, msg));
23032
23033                installedLatch.countDown();
23034                freezer.close();
23035
23036                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23037                switch (status) {
23038                    case PackageInstaller.STATUS_SUCCESS:
23039                        mMoveCallbacks.notifyStatusChanged(moveId,
23040                                PackageManager.MOVE_SUCCEEDED);
23041                        break;
23042                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23043                        mMoveCallbacks.notifyStatusChanged(moveId,
23044                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23045                        break;
23046                    default:
23047                        mMoveCallbacks.notifyStatusChanged(moveId,
23048                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23049                        break;
23050                }
23051            }
23052        };
23053
23054        final MoveInfo move;
23055        if (moveCompleteApp) {
23056            // Kick off a thread to report progress estimates
23057            new Thread() {
23058                @Override
23059                public void run() {
23060                    while (true) {
23061                        try {
23062                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23063                                break;
23064                            }
23065                        } catch (InterruptedException ignored) {
23066                        }
23067
23068                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23069                        final int progress = 10 + (int) MathUtils.constrain(
23070                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23071                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23072                    }
23073                }
23074            }.start();
23075
23076            final String dataAppName = codeFile.getName();
23077            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23078                    dataAppName, appId, seinfo, targetSdkVersion);
23079        } else {
23080            move = null;
23081        }
23082
23083        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23084
23085        final Message msg = mHandler.obtainMessage(INIT_COPY);
23086        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23087        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23088                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23089                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23090                PackageManager.INSTALL_REASON_UNKNOWN);
23091        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23092        msg.obj = params;
23093
23094        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23095                System.identityHashCode(msg.obj));
23096        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23097                System.identityHashCode(msg.obj));
23098
23099        mHandler.sendMessage(msg);
23100    }
23101
23102    @Override
23103    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23104        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23105
23106        final int realMoveId = mNextMoveId.getAndIncrement();
23107        final Bundle extras = new Bundle();
23108        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23109        mMoveCallbacks.notifyCreated(realMoveId, extras);
23110
23111        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23112            @Override
23113            public void onCreated(int moveId, Bundle extras) {
23114                // Ignored
23115            }
23116
23117            @Override
23118            public void onStatusChanged(int moveId, int status, long estMillis) {
23119                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23120            }
23121        };
23122
23123        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23124        storage.setPrimaryStorageUuid(volumeUuid, callback);
23125        return realMoveId;
23126    }
23127
23128    @Override
23129    public int getMoveStatus(int moveId) {
23130        mContext.enforceCallingOrSelfPermission(
23131                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23132        return mMoveCallbacks.mLastStatus.get(moveId);
23133    }
23134
23135    @Override
23136    public void registerMoveCallback(IPackageMoveObserver callback) {
23137        mContext.enforceCallingOrSelfPermission(
23138                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23139        mMoveCallbacks.register(callback);
23140    }
23141
23142    @Override
23143    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23144        mContext.enforceCallingOrSelfPermission(
23145                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23146        mMoveCallbacks.unregister(callback);
23147    }
23148
23149    @Override
23150    public boolean setInstallLocation(int loc) {
23151        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23152                null);
23153        if (getInstallLocation() == loc) {
23154            return true;
23155        }
23156        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23157                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23158            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23159                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23160            return true;
23161        }
23162        return false;
23163   }
23164
23165    @Override
23166    public int getInstallLocation() {
23167        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23168                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23169                PackageHelper.APP_INSTALL_AUTO);
23170    }
23171
23172    /** Called by UserManagerService */
23173    void cleanUpUser(UserManagerService userManager, int userHandle) {
23174        synchronized (mPackages) {
23175            mDirtyUsers.remove(userHandle);
23176            mUserNeedsBadging.delete(userHandle);
23177            mSettings.removeUserLPw(userHandle);
23178            mPendingBroadcasts.remove(userHandle);
23179            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23180            removeUnusedPackagesLPw(userManager, userHandle);
23181        }
23182    }
23183
23184    /**
23185     * We're removing userHandle and would like to remove any downloaded packages
23186     * that are no longer in use by any other user.
23187     * @param userHandle the user being removed
23188     */
23189    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23190        final boolean DEBUG_CLEAN_APKS = false;
23191        int [] users = userManager.getUserIds();
23192        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23193        while (psit.hasNext()) {
23194            PackageSetting ps = psit.next();
23195            if (ps.pkg == null) {
23196                continue;
23197            }
23198            final String packageName = ps.pkg.packageName;
23199            // Skip over if system app
23200            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23201                continue;
23202            }
23203            if (DEBUG_CLEAN_APKS) {
23204                Slog.i(TAG, "Checking package " + packageName);
23205            }
23206            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23207            if (keep) {
23208                if (DEBUG_CLEAN_APKS) {
23209                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23210                }
23211            } else {
23212                for (int i = 0; i < users.length; i++) {
23213                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23214                        keep = true;
23215                        if (DEBUG_CLEAN_APKS) {
23216                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23217                                    + users[i]);
23218                        }
23219                        break;
23220                    }
23221                }
23222            }
23223            if (!keep) {
23224                if (DEBUG_CLEAN_APKS) {
23225                    Slog.i(TAG, "  Removing package " + packageName);
23226                }
23227                mHandler.post(new Runnable() {
23228                    public void run() {
23229                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23230                                userHandle, 0);
23231                    } //end run
23232                });
23233            }
23234        }
23235    }
23236
23237    /** Called by UserManagerService */
23238    void createNewUser(int userId, String[] disallowedPackages) {
23239        synchronized (mInstallLock) {
23240            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23241        }
23242        synchronized (mPackages) {
23243            scheduleWritePackageRestrictionsLocked(userId);
23244            scheduleWritePackageListLocked(userId);
23245            applyFactoryDefaultBrowserLPw(userId);
23246            primeDomainVerificationsLPw(userId);
23247        }
23248    }
23249
23250    void onNewUserCreated(final int userId) {
23251        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23252        // If permission review for legacy apps is required, we represent
23253        // dagerous permissions for such apps as always granted runtime
23254        // permissions to keep per user flag state whether review is needed.
23255        // Hence, if a new user is added we have to propagate dangerous
23256        // permission grants for these legacy apps.
23257        if (mPermissionReviewRequired) {
23258            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23259                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23260        }
23261    }
23262
23263    @Override
23264    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23265        mContext.enforceCallingOrSelfPermission(
23266                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23267                "Only package verification agents can read the verifier device identity");
23268
23269        synchronized (mPackages) {
23270            return mSettings.getVerifierDeviceIdentityLPw();
23271        }
23272    }
23273
23274    @Override
23275    public void setPermissionEnforced(String permission, boolean enforced) {
23276        // TODO: Now that we no longer change GID for storage, this should to away.
23277        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23278                "setPermissionEnforced");
23279        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23280            synchronized (mPackages) {
23281                if (mSettings.mReadExternalStorageEnforced == null
23282                        || mSettings.mReadExternalStorageEnforced != enforced) {
23283                    mSettings.mReadExternalStorageEnforced = enforced;
23284                    mSettings.writeLPr();
23285                }
23286            }
23287            // kill any non-foreground processes so we restart them and
23288            // grant/revoke the GID.
23289            final IActivityManager am = ActivityManager.getService();
23290            if (am != null) {
23291                final long token = Binder.clearCallingIdentity();
23292                try {
23293                    am.killProcessesBelowForeground("setPermissionEnforcement");
23294                } catch (RemoteException e) {
23295                } finally {
23296                    Binder.restoreCallingIdentity(token);
23297                }
23298            }
23299        } else {
23300            throw new IllegalArgumentException("No selective enforcement for " + permission);
23301        }
23302    }
23303
23304    @Override
23305    @Deprecated
23306    public boolean isPermissionEnforced(String permission) {
23307        return true;
23308    }
23309
23310    @Override
23311    public boolean isStorageLow() {
23312        final long token = Binder.clearCallingIdentity();
23313        try {
23314            final DeviceStorageMonitorInternal
23315                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23316            if (dsm != null) {
23317                return dsm.isMemoryLow();
23318            } else {
23319                return false;
23320            }
23321        } finally {
23322            Binder.restoreCallingIdentity(token);
23323        }
23324    }
23325
23326    @Override
23327    public IPackageInstaller getPackageInstaller() {
23328        return mInstallerService;
23329    }
23330
23331    private boolean userNeedsBadging(int userId) {
23332        int index = mUserNeedsBadging.indexOfKey(userId);
23333        if (index < 0) {
23334            final UserInfo userInfo;
23335            final long token = Binder.clearCallingIdentity();
23336            try {
23337                userInfo = sUserManager.getUserInfo(userId);
23338            } finally {
23339                Binder.restoreCallingIdentity(token);
23340            }
23341            final boolean b;
23342            if (userInfo != null && userInfo.isManagedProfile()) {
23343                b = true;
23344            } else {
23345                b = false;
23346            }
23347            mUserNeedsBadging.put(userId, b);
23348            return b;
23349        }
23350        return mUserNeedsBadging.valueAt(index);
23351    }
23352
23353    @Override
23354    public KeySet getKeySetByAlias(String packageName, String alias) {
23355        if (packageName == null || alias == null) {
23356            return null;
23357        }
23358        synchronized(mPackages) {
23359            final PackageParser.Package pkg = mPackages.get(packageName);
23360            if (pkg == null) {
23361                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23362                throw new IllegalArgumentException("Unknown package: " + packageName);
23363            }
23364            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23365            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23366        }
23367    }
23368
23369    @Override
23370    public KeySet getSigningKeySet(String packageName) {
23371        if (packageName == null) {
23372            return null;
23373        }
23374        synchronized(mPackages) {
23375            final PackageParser.Package pkg = mPackages.get(packageName);
23376            if (pkg == null) {
23377                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23378                throw new IllegalArgumentException("Unknown package: " + packageName);
23379            }
23380            if (pkg.applicationInfo.uid != Binder.getCallingUid()
23381                    && Process.SYSTEM_UID != Binder.getCallingUid()) {
23382                throw new SecurityException("May not access signing KeySet of other apps.");
23383            }
23384            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23385            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23386        }
23387    }
23388
23389    @Override
23390    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23391        if (packageName == null || ks == null) {
23392            return false;
23393        }
23394        synchronized(mPackages) {
23395            final PackageParser.Package pkg = mPackages.get(packageName);
23396            if (pkg == null) {
23397                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23398                throw new IllegalArgumentException("Unknown package: " + packageName);
23399            }
23400            IBinder ksh = ks.getToken();
23401            if (ksh instanceof KeySetHandle) {
23402                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23403                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23404            }
23405            return false;
23406        }
23407    }
23408
23409    @Override
23410    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23411        if (packageName == null || ks == null) {
23412            return false;
23413        }
23414        synchronized(mPackages) {
23415            final PackageParser.Package pkg = mPackages.get(packageName);
23416            if (pkg == null) {
23417                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23418                throw new IllegalArgumentException("Unknown package: " + packageName);
23419            }
23420            IBinder ksh = ks.getToken();
23421            if (ksh instanceof KeySetHandle) {
23422                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23423                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23424            }
23425            return false;
23426        }
23427    }
23428
23429    private void deletePackageIfUnusedLPr(final String packageName) {
23430        PackageSetting ps = mSettings.mPackages.get(packageName);
23431        if (ps == null) {
23432            return;
23433        }
23434        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23435            // TODO Implement atomic delete if package is unused
23436            // It is currently possible that the package will be deleted even if it is installed
23437            // after this method returns.
23438            mHandler.post(new Runnable() {
23439                public void run() {
23440                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23441                            0, PackageManager.DELETE_ALL_USERS);
23442                }
23443            });
23444        }
23445    }
23446
23447    /**
23448     * Check and throw if the given before/after packages would be considered a
23449     * downgrade.
23450     */
23451    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23452            throws PackageManagerException {
23453        if (after.versionCode < before.mVersionCode) {
23454            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23455                    "Update version code " + after.versionCode + " is older than current "
23456                    + before.mVersionCode);
23457        } else if (after.versionCode == before.mVersionCode) {
23458            if (after.baseRevisionCode < before.baseRevisionCode) {
23459                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23460                        "Update base revision code " + after.baseRevisionCode
23461                        + " is older than current " + before.baseRevisionCode);
23462            }
23463
23464            if (!ArrayUtils.isEmpty(after.splitNames)) {
23465                for (int i = 0; i < after.splitNames.length; i++) {
23466                    final String splitName = after.splitNames[i];
23467                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23468                    if (j != -1) {
23469                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23470                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23471                                    "Update split " + splitName + " revision code "
23472                                    + after.splitRevisionCodes[i] + " is older than current "
23473                                    + before.splitRevisionCodes[j]);
23474                        }
23475                    }
23476                }
23477            }
23478        }
23479    }
23480
23481    private static class MoveCallbacks extends Handler {
23482        private static final int MSG_CREATED = 1;
23483        private static final int MSG_STATUS_CHANGED = 2;
23484
23485        private final RemoteCallbackList<IPackageMoveObserver>
23486                mCallbacks = new RemoteCallbackList<>();
23487
23488        private final SparseIntArray mLastStatus = new SparseIntArray();
23489
23490        public MoveCallbacks(Looper looper) {
23491            super(looper);
23492        }
23493
23494        public void register(IPackageMoveObserver callback) {
23495            mCallbacks.register(callback);
23496        }
23497
23498        public void unregister(IPackageMoveObserver callback) {
23499            mCallbacks.unregister(callback);
23500        }
23501
23502        @Override
23503        public void handleMessage(Message msg) {
23504            final SomeArgs args = (SomeArgs) msg.obj;
23505            final int n = mCallbacks.beginBroadcast();
23506            for (int i = 0; i < n; i++) {
23507                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23508                try {
23509                    invokeCallback(callback, msg.what, args);
23510                } catch (RemoteException ignored) {
23511                }
23512            }
23513            mCallbacks.finishBroadcast();
23514            args.recycle();
23515        }
23516
23517        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23518                throws RemoteException {
23519            switch (what) {
23520                case MSG_CREATED: {
23521                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23522                    break;
23523                }
23524                case MSG_STATUS_CHANGED: {
23525                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23526                    break;
23527                }
23528            }
23529        }
23530
23531        private void notifyCreated(int moveId, Bundle extras) {
23532            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23533
23534            final SomeArgs args = SomeArgs.obtain();
23535            args.argi1 = moveId;
23536            args.arg2 = extras;
23537            obtainMessage(MSG_CREATED, args).sendToTarget();
23538        }
23539
23540        private void notifyStatusChanged(int moveId, int status) {
23541            notifyStatusChanged(moveId, status, -1);
23542        }
23543
23544        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23545            Slog.v(TAG, "Move " + moveId + " status " + status);
23546
23547            final SomeArgs args = SomeArgs.obtain();
23548            args.argi1 = moveId;
23549            args.argi2 = status;
23550            args.arg3 = estMillis;
23551            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23552
23553            synchronized (mLastStatus) {
23554                mLastStatus.put(moveId, status);
23555            }
23556        }
23557    }
23558
23559    private final static class OnPermissionChangeListeners extends Handler {
23560        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23561
23562        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23563                new RemoteCallbackList<>();
23564
23565        public OnPermissionChangeListeners(Looper looper) {
23566            super(looper);
23567        }
23568
23569        @Override
23570        public void handleMessage(Message msg) {
23571            switch (msg.what) {
23572                case MSG_ON_PERMISSIONS_CHANGED: {
23573                    final int uid = msg.arg1;
23574                    handleOnPermissionsChanged(uid);
23575                } break;
23576            }
23577        }
23578
23579        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23580            mPermissionListeners.register(listener);
23581
23582        }
23583
23584        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23585            mPermissionListeners.unregister(listener);
23586        }
23587
23588        public void onPermissionsChanged(int uid) {
23589            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23590                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23591            }
23592        }
23593
23594        private void handleOnPermissionsChanged(int uid) {
23595            final int count = mPermissionListeners.beginBroadcast();
23596            try {
23597                for (int i = 0; i < count; i++) {
23598                    IOnPermissionsChangeListener callback = mPermissionListeners
23599                            .getBroadcastItem(i);
23600                    try {
23601                        callback.onPermissionsChanged(uid);
23602                    } catch (RemoteException e) {
23603                        Log.e(TAG, "Permission listener is dead", e);
23604                    }
23605                }
23606            } finally {
23607                mPermissionListeners.finishBroadcast();
23608            }
23609        }
23610    }
23611
23612    private class PackageManagerInternalImpl extends PackageManagerInternal {
23613        @Override
23614        public void setLocationPackagesProvider(PackagesProvider provider) {
23615            synchronized (mPackages) {
23616                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
23617            }
23618        }
23619
23620        @Override
23621        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23622            synchronized (mPackages) {
23623                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
23624            }
23625        }
23626
23627        @Override
23628        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23629            synchronized (mPackages) {
23630                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
23631            }
23632        }
23633
23634        @Override
23635        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23636            synchronized (mPackages) {
23637                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
23638            }
23639        }
23640
23641        @Override
23642        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23643            synchronized (mPackages) {
23644                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
23645            }
23646        }
23647
23648        @Override
23649        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23650            synchronized (mPackages) {
23651                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
23652            }
23653        }
23654
23655        @Override
23656        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23657            synchronized (mPackages) {
23658                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
23659                        packageName, userId);
23660            }
23661        }
23662
23663        @Override
23664        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23665            synchronized (mPackages) {
23666                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23667                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
23668                        packageName, userId);
23669            }
23670        }
23671
23672        @Override
23673        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23674            synchronized (mPackages) {
23675                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
23676                        packageName, userId);
23677            }
23678        }
23679
23680        @Override
23681        public void setKeepUninstalledPackages(final List<String> packageList) {
23682            Preconditions.checkNotNull(packageList);
23683            List<String> removedFromList = null;
23684            synchronized (mPackages) {
23685                if (mKeepUninstalledPackages != null) {
23686                    final int packagesCount = mKeepUninstalledPackages.size();
23687                    for (int i = 0; i < packagesCount; i++) {
23688                        String oldPackage = mKeepUninstalledPackages.get(i);
23689                        if (packageList != null && packageList.contains(oldPackage)) {
23690                            continue;
23691                        }
23692                        if (removedFromList == null) {
23693                            removedFromList = new ArrayList<>();
23694                        }
23695                        removedFromList.add(oldPackage);
23696                    }
23697                }
23698                mKeepUninstalledPackages = new ArrayList<>(packageList);
23699                if (removedFromList != null) {
23700                    final int removedCount = removedFromList.size();
23701                    for (int i = 0; i < removedCount; i++) {
23702                        deletePackageIfUnusedLPr(removedFromList.get(i));
23703                    }
23704                }
23705            }
23706        }
23707
23708        @Override
23709        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23710            synchronized (mPackages) {
23711                // If we do not support permission review, done.
23712                if (!mPermissionReviewRequired) {
23713                    return false;
23714                }
23715
23716                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
23717                if (packageSetting == null) {
23718                    return false;
23719                }
23720
23721                // Permission review applies only to apps not supporting the new permission model.
23722                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
23723                    return false;
23724                }
23725
23726                // Legacy apps have the permission and get user consent on launch.
23727                PermissionsState permissionsState = packageSetting.getPermissionsState();
23728                return permissionsState.isPermissionReviewRequired(userId);
23729            }
23730        }
23731
23732        @Override
23733        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
23734            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
23735        }
23736
23737        @Override
23738        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23739                int userId) {
23740            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23741        }
23742
23743        @Override
23744        public void setDeviceAndProfileOwnerPackages(
23745                int deviceOwnerUserId, String deviceOwnerPackage,
23746                SparseArray<String> profileOwnerPackages) {
23747            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23748                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23749        }
23750
23751        @Override
23752        public boolean isPackageDataProtected(int userId, String packageName) {
23753            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23754        }
23755
23756        @Override
23757        public boolean isPackageEphemeral(int userId, String packageName) {
23758            synchronized (mPackages) {
23759                final PackageSetting ps = mSettings.mPackages.get(packageName);
23760                return ps != null ? ps.getInstantApp(userId) : false;
23761            }
23762        }
23763
23764        @Override
23765        public boolean wasPackageEverLaunched(String packageName, int userId) {
23766            synchronized (mPackages) {
23767                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23768            }
23769        }
23770
23771        @Override
23772        public void grantRuntimePermission(String packageName, String name, int userId,
23773                boolean overridePolicy) {
23774            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
23775                    overridePolicy);
23776        }
23777
23778        @Override
23779        public void revokeRuntimePermission(String packageName, String name, int userId,
23780                boolean overridePolicy) {
23781            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
23782                    overridePolicy);
23783        }
23784
23785        @Override
23786        public String getNameForUid(int uid) {
23787            return PackageManagerService.this.getNameForUid(uid);
23788        }
23789
23790        @Override
23791        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23792                Intent origIntent, String resolvedType, String callingPackage,
23793                Bundle verificationBundle, int userId) {
23794            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23795                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23796                    userId);
23797        }
23798
23799        @Override
23800        public void grantEphemeralAccess(int userId, Intent intent,
23801                int targetAppId, int ephemeralAppId) {
23802            synchronized (mPackages) {
23803                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23804                        targetAppId, ephemeralAppId);
23805            }
23806        }
23807
23808        @Override
23809        public boolean isInstantAppInstallerComponent(ComponentName component) {
23810            synchronized (mPackages) {
23811                return mInstantAppInstallerActivity != null
23812                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23813            }
23814        }
23815
23816        @Override
23817        public void pruneInstantApps() {
23818            synchronized (mPackages) {
23819                mInstantAppRegistry.pruneInstantAppsLPw();
23820            }
23821        }
23822
23823        @Override
23824        public String getSetupWizardPackageName() {
23825            return mSetupWizardPackage;
23826        }
23827
23828        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23829            if (policy != null) {
23830                mExternalSourcesPolicy = policy;
23831            }
23832        }
23833
23834        @Override
23835        public boolean isPackagePersistent(String packageName) {
23836            synchronized (mPackages) {
23837                PackageParser.Package pkg = mPackages.get(packageName);
23838                return pkg != null
23839                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23840                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23841                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23842                        : false;
23843            }
23844        }
23845
23846        @Override
23847        public List<PackageInfo> getOverlayPackages(int userId) {
23848            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23849            synchronized (mPackages) {
23850                for (PackageParser.Package p : mPackages.values()) {
23851                    if (p.mOverlayTarget != null) {
23852                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23853                        if (pkg != null) {
23854                            overlayPackages.add(pkg);
23855                        }
23856                    }
23857                }
23858            }
23859            return overlayPackages;
23860        }
23861
23862        @Override
23863        public List<String> getTargetPackageNames(int userId) {
23864            List<String> targetPackages = new ArrayList<>();
23865            synchronized (mPackages) {
23866                for (PackageParser.Package p : mPackages.values()) {
23867                    if (p.mOverlayTarget == null) {
23868                        targetPackages.add(p.packageName);
23869                    }
23870                }
23871            }
23872            return targetPackages;
23873        }
23874
23875        @Override
23876        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23877                @Nullable List<String> overlayPackageNames) {
23878            synchronized (mPackages) {
23879                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23880                    Slog.e(TAG, "failed to find package " + targetPackageName);
23881                    return false;
23882                }
23883
23884                ArrayList<String> paths = null;
23885                if (overlayPackageNames != null) {
23886                    final int N = overlayPackageNames.size();
23887                    paths = new ArrayList<>(N);
23888                    for (int i = 0; i < N; i++) {
23889                        final String packageName = overlayPackageNames.get(i);
23890                        final PackageParser.Package pkg = mPackages.get(packageName);
23891                        if (pkg == null) {
23892                            Slog.e(TAG, "failed to find package " + packageName);
23893                            return false;
23894                        }
23895                        paths.add(pkg.baseCodePath);
23896                    }
23897                }
23898
23899                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
23900                    mEnabledOverlayPaths.get(userId);
23901                if (userSpecificOverlays == null) {
23902                    userSpecificOverlays = new ArrayMap<>();
23903                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
23904                }
23905
23906                if (paths != null && paths.size() > 0) {
23907                    userSpecificOverlays.put(targetPackageName, paths);
23908                } else {
23909                    userSpecificOverlays.remove(targetPackageName);
23910                }
23911                return true;
23912            }
23913        }
23914
23915        @Override
23916        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23917                int flags, int userId) {
23918            return resolveIntentInternal(
23919                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
23920        }
23921
23922        @Override
23923        public ResolveInfo resolveService(Intent intent, String resolvedType,
23924                int flags, int userId, int callingUid) {
23925            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23926        }
23927
23928        @Override
23929        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23930            synchronized (mPackages) {
23931                mIsolatedOwners.put(isolatedUid, ownerUid);
23932            }
23933        }
23934
23935        @Override
23936        public void removeIsolatedUid(int isolatedUid) {
23937            synchronized (mPackages) {
23938                mIsolatedOwners.delete(isolatedUid);
23939            }
23940        }
23941
23942        @Override
23943        public int getUidTargetSdkVersion(int uid) {
23944            synchronized (mPackages) {
23945                return getUidTargetSdkVersionLockedLPr(uid);
23946            }
23947        }
23948
23949        @Override
23950        public boolean canAccessInstantApps(int callingUid) {
23951            return PackageManagerService.this.canAccessInstantApps(callingUid);
23952        }
23953    }
23954
23955    @Override
23956    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23957        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23958        synchronized (mPackages) {
23959            final long identity = Binder.clearCallingIdentity();
23960            try {
23961                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
23962                        packageNames, userId);
23963            } finally {
23964                Binder.restoreCallingIdentity(identity);
23965            }
23966        }
23967    }
23968
23969    @Override
23970    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23971        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23972        synchronized (mPackages) {
23973            final long identity = Binder.clearCallingIdentity();
23974            try {
23975                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
23976                        packageNames, userId);
23977            } finally {
23978                Binder.restoreCallingIdentity(identity);
23979            }
23980        }
23981    }
23982
23983    private static void enforceSystemOrPhoneCaller(String tag) {
23984        int callingUid = Binder.getCallingUid();
23985        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23986            throw new SecurityException(
23987                    "Cannot call " + tag + " from UID " + callingUid);
23988        }
23989    }
23990
23991    boolean isHistoricalPackageUsageAvailable() {
23992        return mPackageUsage.isHistoricalPackageUsageAvailable();
23993    }
23994
23995    /**
23996     * Return a <b>copy</b> of the collection of packages known to the package manager.
23997     * @return A copy of the values of mPackages.
23998     */
23999    Collection<PackageParser.Package> getPackages() {
24000        synchronized (mPackages) {
24001            return new ArrayList<>(mPackages.values());
24002        }
24003    }
24004
24005    /**
24006     * Logs process start information (including base APK hash) to the security log.
24007     * @hide
24008     */
24009    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24010            String apkFile, int pid) {
24011        if (!SecurityLog.isLoggingEnabled()) {
24012            return;
24013        }
24014        Bundle data = new Bundle();
24015        data.putLong("startTimestamp", System.currentTimeMillis());
24016        data.putString("processName", processName);
24017        data.putInt("uid", uid);
24018        data.putString("seinfo", seinfo);
24019        data.putString("apkFile", apkFile);
24020        data.putInt("pid", pid);
24021        Message msg = mProcessLoggingHandler.obtainMessage(
24022                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24023        msg.setData(data);
24024        mProcessLoggingHandler.sendMessage(msg);
24025    }
24026
24027    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24028        return mCompilerStats.getPackageStats(pkgName);
24029    }
24030
24031    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24032        return getOrCreateCompilerPackageStats(pkg.packageName);
24033    }
24034
24035    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24036        return mCompilerStats.getOrCreatePackageStats(pkgName);
24037    }
24038
24039    public void deleteCompilerPackageStats(String pkgName) {
24040        mCompilerStats.deletePackageStats(pkgName);
24041    }
24042
24043    @Override
24044    public int getInstallReason(String packageName, int userId) {
24045        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24046                true /* requireFullPermission */, false /* checkShell */,
24047                "get install reason");
24048        synchronized (mPackages) {
24049            final PackageSetting ps = mSettings.mPackages.get(packageName);
24050            if (ps != null) {
24051                return ps.getInstallReason(userId);
24052            }
24053        }
24054        return PackageManager.INSTALL_REASON_UNKNOWN;
24055    }
24056
24057    @Override
24058    public boolean canRequestPackageInstalls(String packageName, int userId) {
24059        return canRequestPackageInstallsInternal(packageName, 0, userId,
24060                true /* throwIfPermNotDeclared*/);
24061    }
24062
24063    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24064            boolean throwIfPermNotDeclared) {
24065        int callingUid = Binder.getCallingUid();
24066        int uid = getPackageUid(packageName, 0, userId);
24067        if (callingUid != uid && callingUid != Process.ROOT_UID
24068                && callingUid != Process.SYSTEM_UID) {
24069            throw new SecurityException(
24070                    "Caller uid " + callingUid + " does not own package " + packageName);
24071        }
24072        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24073        if (info == null) {
24074            return false;
24075        }
24076        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24077            return false;
24078        }
24079        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24080        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24081        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24082            if (throwIfPermNotDeclared) {
24083                throw new SecurityException("Need to declare " + appOpPermission
24084                        + " to call this api");
24085            } else {
24086                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24087                return false;
24088            }
24089        }
24090        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24091            return false;
24092        }
24093        if (mExternalSourcesPolicy != null) {
24094            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24095            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24096                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24097            }
24098        }
24099        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24100    }
24101
24102    @Override
24103    public ComponentName getInstantAppResolverSettingsComponent() {
24104        return mInstantAppResolverSettingsComponent;
24105    }
24106
24107    @Override
24108    public ComponentName getInstantAppInstallerComponent() {
24109        return mInstantAppInstallerActivity == null
24110                ? null : mInstantAppInstallerActivity.getComponentName();
24111    }
24112
24113    @Override
24114    public String getInstantAppAndroidId(String packageName, int userId) {
24115        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24116                "getInstantAppAndroidId");
24117        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24118                true /* requireFullPermission */, false /* checkShell */,
24119                "getInstantAppAndroidId");
24120        // Make sure the target is an Instant App.
24121        if (!isInstantApp(packageName, userId)) {
24122            return null;
24123        }
24124        synchronized (mPackages) {
24125            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24126        }
24127    }
24128}
24129
24130interface PackageSender {
24131    void sendPackageBroadcast(final String action, final String pkg,
24132        final Bundle extras, final int flags, final String targetPkg,
24133        final IIntentReceiver finishedReceiver, final int[] userIds);
24134    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
24135        int appId, int... userIds);
24136}
24137